PHPackages                             stojg/recommend - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. stojg/recommend

AbandonedArchivedLibrary[Utility &amp; Helpers](/categories/utility)

stojg/recommend
===============

Library for mining

1.0.0(12y ago)351.7k8MITPHPPHP &gt;=5.3.3

Since Mar 24Pushed 10y agoCompare

[ Source](https://github.com/stojg/recommend)[ Packagist](https://packagist.org/packages/stojg/recommend)[ Docs](https://github.com/stojg/recommend/)[ RSS](/packages/stojg-recommend/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (1)Dependencies (1)Versions (3)Used By (0)

Recommend
=========

[](#recommend)

[![Build Status](https://camo.githubusercontent.com/3eeda9a8812a8274fcc2cd211bac966f6ed9a6f38135c0d3c522c7da7e994df9/68747470733a2f2f7472617669732d63692e6f72672f73746f6a672f7265636f6d6d656e642e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/stojg/recommend)[![Code Coverage](https://camo.githubusercontent.com/cfdd640f21e5bfa8f26c8780a75b73929859397ab5b9eaa5d5595f84b295b084/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73746f6a672f7265636f6d6d656e642f6261646765732f636f7665726167652e706e673f733d35393338636234363432623737633265613038316634373731663039363133346239336433343934)](https://scrutinizer-ci.com/g/stojg/recommend/)[![Scrutinizer Quality Score](https://camo.githubusercontent.com/8cffcb379dfa8c10010bb47b1307bdc6ebcb8ffba56ef282bfd7c70abf7de923/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73746f6a672f7265636f6d6d656e642f6261646765732f7175616c6974792d73636f72652e706e673f733d63636331666536373562396535316663383736393464356130396235303962663064313335326639)](https://scrutinizer-ci.com/g/stojg/recommend/)[![StyleCI](https://camo.githubusercontent.com/591b9b245cf2435ca6dc2bdd22ab2c10103b44d6004dd7435b24d57436545664/68747470733a2f2f7374796c6563692e696f2f7265706f732f31353033303839332f736869656c64)](https://styleci.io/repos/15030893)

This library should make it easier to find recommendations and similarities between different things. There are a couple of use cases that I developed it for:

- Recommend a list of music albums/artists to a user
- Recommend an article that is similar to the current one that a user is reading
- Find other users that have the same values as another user (think matchmaking ;)

Installation
------------

[](#installation)

The easiest way to get this installed in your project is by using composer

```
$ composer require stojg/recommend

```

Usage
-----

[](#usage)

Assuming that we have some data where users have rated music artists within a scale of one to five:

```
$artistRatings = array(
	"Abe" => array(
		"Blues Traveler" => 3,
		"Broken Bells" => 2,
		"Norah Jones" => 4,
		"Phoenix" => 5,
		"Slightly Stoopid" => 1,
		"The Strokes" => 2,
		"Vampire Weekend" => 2
	),
	"Blair" => array(
		"Blues Traveler" => 2,
		"Broken Bells" => 3,
		"Deadmau5" => 4,
		"Phoenix" => 2,
		"Slightly Stoopid" => 3,
		"Vampire Weekend" => 3
    ),
	"Clair" => array(
		"Blues Traveler" => 5,
		"Broken Bells" => 1,
		"Deadmau5" => 1,
		"Norah Jones" => 3,
		"Phoenix" => 5,
		"Slightly Stoopid" => 1
	)
);

```

We then load this data into the Data class

```
$data = new \stojg\recommend\Data($artistRatings);

```

If we want to find artists that *Blair* might like, we execute the recommend method.

```
$recommendations = $data->recommend('Blair', new \stojg\recommend\strategy\Manhattan());
var_export($recommendations);

```

The result of that computation would be:

```
array (
  0 => array (
	'key' => 'Norah Jones',
	'value' => 4,
  ),
  1 => array (
	'key' => 'The Strokes',
	'value' => 2,
  )
)

```

This means that *Blair* might like `Norah Jones` and not like `The Strokes`.

The `Recommender` works by finding someone in the `$artistRatings` that have rated artist similar to to *Blair*. In this case it turns out to be *Abe*, so it then tries to find artists that *Abe* have rated but not *Blair* and return them as a list of recommendations.

How the 'nearest neighbour' is found depends on which strategy that is chosen and how big and dense the dataset is.

The Dataset
-----------

[](#the-dataset)

The general rule is that the bigger the dataset is, the better. It have to be formatted as an array in the following format:

```
array(
	'uniqueID' => array(
		'objectID' => (int)'rating'
	)
);

```

Where in the case of the previous artist rating example

```
* uniqueID = Blair
* objectID = Music Artist
* rating = an numeric value

```

Strategies
----------

[](#strategies)

There are currently three strategies and which one to pick depends on how the data is organized and populated.

### Manhattan

[](#manhattan)

If the data is dense (almost all `objectID`s in the full data set have a non null rating) and the magnitude (rating) of the attributes values are important, this is a good strategy.

I.e. all users have rated all music artists and they all agree on the same scale.

### Paerson

[](#paerson)

Use this strategy if the data is dense but the ratings are subject to grade-inflation.

I.e. if user A have rated all artists between 2-4 and user B have rated artists between 4-5 this strategy tries to compensate for the fact that the user A’s rating of 2 is equal to Users B’s 4.

### Cosine

[](#cosine)

This is the strategy to pick if the data is sparse.

I.e. If there is a list with ten thousand artists, it quite likely that the users only listened and rated a few of them.

Articles
--------

[](#articles)

There is a provided helper class for recommending articles that are similar to another article. The implementation is quite stupid, but it should give you a hint on how to expand this library with your own datasets.

### Usage

[](#usage-1)

```
$articleData = new \stojg\recommend\ArticleData();
$allArticles = getFromDatabase();
foreach($allArticles as $article) {
       $articleData->push($article->id, $article->content);
   }
  $recommendedArticle = $articleData->recommend($articleID = 4);

```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

4435d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ffa59057c23c330890610ea045f407f8cdbc0fa36bde26d5a7a9aa18d5fd5197?d=identicon)[stojg](/maintainers/stojg)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/stojg-recommend/health.svg)

```
[![Health](https://phpackages.com/badges/stojg-recommend/health.svg)](https://phpackages.com/packages/stojg-recommend)
```

###  Alternatives

[captainhook/plugin-composer

Composer-Plugin handling your git-hooks

201.9M169](/packages/captainhook-plugin-composer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
