Skip to content

Commit

Permalink
Merge pull request stojg#4 from stojg/analysis-z4JvGX
Browse files Browse the repository at this point in the history
Applied fixes from StyleCI
  • Loading branch information
Stig Lindqvist committed Dec 3, 2015
2 parents 897f118 + b56782c commit a9d38fd
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 136 deletions.
105 changes: 52 additions & 53 deletions src/stojg/recommend/ArticleData.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,42 @@
use stojg\recommend\strategy\Cosine;

/**
* Description of ArticleData
*
* Description of ArticleData.
*/
class ArticleData extends Data
{

/**
*
* @var array
*/
protected $stopWords = array("a", "about", "above", "above", "across", "after", "afterwards", "again", "against",
"all", "almost", "alone", "along", "already", "also", "although", "always", "am", "among", "amongst",
"amoungst", "amount", "an", "and", "another", "any", "anyhow", "anyone", "anything", "anyway", "anywhere",
"are", "around", "as", "at", "back", "be", "became", "because", "become", "becomes", "becoming", "been",
"before", "beforehand", "behind", "being", "below", "beside", "besides", "between", "beyond", "bill", "both",
"bottom", "but", "by", "call", "can", "cannot", "cant", "co", "con", "could", "couldnt", "cry", "de",
"describe", "detail", "do", "done", "down", "due", "during", "each", "eg", "eight", "either", "eleven", "else",
"elsewhere", "empty", "enough", "etc", "even", "ever", "every", "everyone", "everything", "everywhere",
"except", "few", "fifteen", "fify", "fill", "find", "fire", "first", "five", "for", "former", "formerly",
"forty", "found", "four", "from", "front", "full", "further", "get", "give", "go", "had", "has", "hasnt",
"have", "he", "hence", "her", "here", "hereafter", "hereby", "herein", "hereupon", "hers", "herself", "him",
"himself", "his", "how", "however", "hundred", "i'd", "ie", "if", "in", "inc", "indeed", "interest", "into",
"is", "it", "its", "itself", "keep", "last", "latter", "latterly", "least", "less", "ltd", "made", "many",
"may", "me", "meanwhile", "might", "mill", "mine", "more", "moreover", "most", "mostly", "move", "much", "must",
"my", "myself", "name", "namely", "neither", "never", "nevertheless", "next", "nine", "no", "nobody", "none",
"noone", "nor", "not", "nothing", "now", "nowhere", "of", "off", "often", "on", "once", "one", "only", "onto",
"or", "other", "others", "otherwise", "our", "ours", "ourselves", "out", "over", "own", "part", "per",
"perhaps", "please", "put", "rather", "re", "same", "see", "seem", "seemed", "seeming", "seems", "serious",
"several", "she", "should", "show", "side", "since", "sincere", "six", "sixty", "so", "some", "somehow",
"someone", "something", "sometime", "sometimes", "somewhere", "still", "such", "system", "take", "ten", "than",
"that", "the", "their", "them", "themselves", "then", "thence", "there", "thereafter", "thereby", "therefore",
"therein", "thereupon", "these", "they", "thickv", "thin", "third", "this", "those", "though", "three",
"through", "throughout", "thru", "thus", "to", "together", "too", "top", "toward", "towards", "twelve",
"twenty", "two", "un", "under", "until", "up", "upon", "us", "very", "via", "was", "we", "well", "were", "what",
"whatever", "when", "whence", "whenever", "where", "whereafter", "whereas", "whereby", "wherein", "whereupon",
"wherever", "whether", "which", "while", "whither", "who", "whoever", "whole", "whom", "whose", "why", "will",
"with", "within", "without", "would", "yet", "you", "your", "yours", "yourself", "yourselves", "the");
protected $stopWords = ['a', 'about', 'above', 'above', 'across', 'after', 'afterwards', 'again', 'against',
'all', 'almost', 'alone', 'along', 'already', 'also', 'although', 'always', 'am', 'among', 'amongst',
'amoungst', 'amount', 'an', 'and', 'another', 'any', 'anyhow', 'anyone', 'anything', 'anyway', 'anywhere',
'are', 'around', 'as', 'at', 'back', 'be', 'became', 'because', 'become', 'becomes', 'becoming', 'been',
'before', 'beforehand', 'behind', 'being', 'below', 'beside', 'besides', 'between', 'beyond', 'bill', 'both',
'bottom', 'but', 'by', 'call', 'can', 'cannot', 'cant', 'co', 'con', 'could', 'couldnt', 'cry', 'de',
'describe', 'detail', 'do', 'done', 'down', 'due', 'during', 'each', 'eg', 'eight', 'either', 'eleven', 'else',
'elsewhere', 'empty', 'enough', 'etc', 'even', 'ever', 'every', 'everyone', 'everything', 'everywhere',
'except', 'few', 'fifteen', 'fify', 'fill', 'find', 'fire', 'first', 'five', 'for', 'former', 'formerly',
'forty', 'found', 'four', 'from', 'front', 'full', 'further', 'get', 'give', 'go', 'had', 'has', 'hasnt',
'have', 'he', 'hence', 'her', 'here', 'hereafter', 'hereby', 'herein', 'hereupon', 'hers', 'herself', 'him',
'himself', 'his', 'how', 'however', 'hundred', "i'd", 'ie', 'if', 'in', 'inc', 'indeed', 'interest', 'into',
'is', 'it', 'its', 'itself', 'keep', 'last', 'latter', 'latterly', 'least', 'less', 'ltd', 'made', 'many',
'may', 'me', 'meanwhile', 'might', 'mill', 'mine', 'more', 'moreover', 'most', 'mostly', 'move', 'much', 'must',
'my', 'myself', 'name', 'namely', 'neither', 'never', 'nevertheless', 'next', 'nine', 'no', 'nobody', 'none',
'noone', 'nor', 'not', 'nothing', 'now', 'nowhere', 'of', 'off', 'often', 'on', 'once', 'one', 'only', 'onto',
'or', 'other', 'others', 'otherwise', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'part', 'per',
'perhaps', 'please', 'put', 'rather', 're', 'same', 'see', 'seem', 'seemed', 'seeming', 'seems', 'serious',
'several', 'she', 'should', 'show', 'side', 'since', 'sincere', 'six', 'sixty', 'so', 'some', 'somehow',
'someone', 'something', 'sometime', 'sometimes', 'somewhere', 'still', 'such', 'system', 'take', 'ten', 'than',
'that', 'the', 'their', 'them', 'themselves', 'then', 'thence', 'there', 'thereafter', 'thereby', 'therefore',
'therein', 'thereupon', 'these', 'they', 'thickv', 'thin', 'third', 'this', 'those', 'though', 'three',
'through', 'throughout', 'thru', 'thus', 'to', 'together', 'too', 'top', 'toward', 'towards', 'twelve',
'twenty', 'two', 'un', 'under', 'until', 'up', 'upon', 'us', 'very', 'via', 'was', 'we', 'well', 'were', 'what',
'whatever', 'when', 'whence', 'whenever', 'where', 'whereafter', 'whereas', 'whereby', 'wherein', 'whereupon',
'wherever', 'whether', 'which', 'while', 'whither', 'who', 'whoever', 'whole', 'whom', 'whose', 'why', 'will',
'with', 'within', 'without', 'would', 'yet', 'you', 'your', 'yours', 'yourself', 'yourselves', 'the', ];

/**
*
* @param array $set
*/
public function __construct()
Expand All @@ -54,7 +50,6 @@ public function __construct()
}

/**
*
* @param string $identifier
* @param string $content
*/
Expand All @@ -64,32 +59,33 @@ public function push($identifier, $content)
}

/**
*
* @param string $for
* @param Object $strategy
* @param object $strategy
*/
public function findNearest($for, $strategy = null)
{
if ($strategy === null) {
$strategy = new Cosine();
}

return parent::findNearest($for, $strategy);
}

/**
* Return a list of recommendations
* Return a list of recommendations.
*
* @param string $for - the item we want recommendations for
* @param object $strategy
*
* @param string $for - the item we want recommendations for
* @param Object $strategy
* @return array - return a list of identifier ordered by closest
*/
public function recommend($for, $strategy=null)
public function recommend($for, $strategy = null)
{
if ($strategy === null) {
if ($strategy === null) {
$strategy = new Cosine();
}
$distances = array();

$distances = [];
foreach ($this->set as $key => $itemData) {
if ($key == $for) {
continue;
Expand All @@ -98,30 +94,32 @@ public function recommend($for, $strategy=null)
if ($distance === false) {
continue;
}
$distances[$key] = array('key' => $key, 'value' => $distance);
$distances[$key] = ['key' => $key, 'value' => $distance];
}
if (!count($distances)) {
return false;
}
$this->sort($distances, true);

$data = array();
foreach($distances as $article){
if($article['value'] == 0) {
continue;
}
$data[] = $article['key'];
}

$data = [];
foreach ($distances as $article) {
if ($article['value'] == 0) {
continue;
}
$data[] = $article['key'];
}

return $data;
}

/**
* Get an array of words from the content and a count of how many times
* they appear in the text.
*
* Note that this method is naive and can't tell the similarity between 'bird' and 'birds'.
*
* @param string $content
*
* @return array
*/
protected function getWordCount($content)
Expand All @@ -131,6 +129,7 @@ protected function getWordCount($content)
$filteredWords = array_diff($words, $this->stopWords);
$countedWords = array_count_values($filteredWords);
ksort($countedWords);

return $countedWords;
}
}
37 changes: 19 additions & 18 deletions src/stojg/recommend/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,25 @@
namespace stojg\recommend;

/**
* This class contains behaviour for finding recommendations
*
* This class contains behaviour for finding recommendations.
*/
class Data
{

/**
* This the
* This the.
*
* @var array
*/
protected $item = '';

/**
* This is the full dataset
* This is the full dataset.
*
* @var array
*/
protected $set = array();
protected $set = [];

/**
*
* @param array $set - The full dataset
*/
public function __construct($set)
Expand All @@ -33,38 +30,40 @@ public function __construct($set)
}

/**
* Return a list of recommendations
* Return a list of recommendations.
*
* @param string $for - the item we want recommendations for
* @param object $strategy
*
* @param string $for - the item we want recommendations for
* @param Object $strategy
* @return array
*/
public function recommend($for, $strategy)
{
$nearest = $this->findNearest($for, $strategy);
if ($nearest === false) {
return array();
return [];
}
$recommendations = array();
$recommendations = [];
foreach ($this->set[$nearest] as $item => $rating) {
// The item has been already been rated
if (isset($this->set[$for][$item])) {
continue;
}
$recommendations[] = array('key' => $item, 'value' => $rating);
$recommendations[] = ['key' => $item, 'value' => $rating];
}
$this->sort($recommendations, false);

return $recommendations;
}

/**
* Find the nearest key that matching is closest to the item in the set
* Find the nearest key that matching is closest to the item in the set.
*
* @return string
*/
public function findNearest($for, $strategy)
{
$distances = array();
$distances = [];
foreach ($this->set as $key => $itemData) {
if ($key == $for) {
continue;
Expand All @@ -73,22 +72,23 @@ public function findNearest($for, $strategy)
if ($distance === false) {
continue;
}
$distances[] = array('key' => $key, 'value' => $distance);
$distances[] = ['key' => $key, 'value' => $distance];
}
if (!count($distances)) {
return false;
}
$this->sort($distances, true);

return $distances[0]['key'];
}

/**
* sort an nested array that have a value attribute
* sort an nested array that have a value attribute.
*
* i.e [ 0 => [ 'value' => 5 ], 1 => [ 'value' => 2 ] ]
*
* @param array $distances
* @param bool $ascending
* @param bool $ascending
*/
protected function sort(&$distances, $ascending = true)
{
Expand All @@ -98,6 +98,7 @@ protected function sort(&$distances, $ascending = true)
} elseif ($first['value'] < $second['value']) {
return ($ascending) ? -1 : 1;
}

return 0;
});
}
Expand Down
6 changes: 2 additions & 4 deletions src/stojg/recommend/strategy/Cosine.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
* cosine of the angle between them. The cosine of 0° is 1, and it is less than 1 for any other angle. It is thus a
* judgement of orientation and not magnitude: two vectors with the same orientation have a Cosine similarity of 1,
* two vectors at 90° have a similarity of 0, and two vectors diametrically opposed have a similarity of -1,
* independent of their magnitude
*
* independent of their magnitude.
*/
class Cosine
{

/**
* Use if the data is sparse
* Use if the data is sparse.
*/
public function run($rating1, $rating2)
{
Expand Down
4 changes: 1 addition & 3 deletions src/stojg/recommend/strategy/Manhattan.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

/**
* Computes the Manhattan distance.
*
*/
class Manhattan extends Minkowski
{

/**
* Overrides the parent Minkowski to set the r-dimension to 1
* Overrides the parent Minkowski to set the r-dimension to 1.
*/
public function __construct()
{
Expand Down
10 changes: 3 additions & 7 deletions src/stojg/recommend/strategy/Minkowski.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@
namespace stojg\recommend\strategy;

/**
* Computes the Minkowski distance
* Computes the Minkowski distance.
*
* If the data is dense (almost all attributes have a non
* zero value) and the magnitude of the attributes values
* are important, this is a good similarity comparisator
*
*/
class Minkowski
{

/**
*
* @var int
*/
protected $r = 1;

/**
*
* @param int $r
*/
public function __construct($r = 1)
Expand All @@ -29,9 +25,8 @@ public function __construct($r = 1)
}

/**
*
* Both rating1 and rating2 are an array of the form
* ['The Strokes'=> 3.0, 'Slightly Stoopid' => 2.5, ...]
* ['The Strokes'=> 3.0, 'Slightly Stoopid' => 2.5, ...].
*
* @param array $rating1
* @param array $rating2
Expand All @@ -49,6 +44,7 @@ public function run($rating1, $rating2)
if ($commonRatings) {
return pow($distance, 1 / $this->r);
}

return false;
}
}
Loading

0 comments on commit a9d38fd

Please sign in to comment.