protected function CFRecommender::computePrediction in Recommender API 7.6
1 call to CFRecommender::computePrediction()
- CFRecommender::execute in classes/
Recommender.php - Do all computation here.
File
- classes/
Recommender.php, line 115
Class
- CFRecommender
- This is the classical collaborative filtering implementation.
Code
protected function computePrediction() {
// we do the computation based on $this->preferenceMatrix loaded in memory
$this->userVectors = $this->preferenceMatrix
->row_vectors();
// regardless of whether preferenceMatrix is a sparse matrix or not, predictionMatrix is always a sparseMatrix.
$this->predictionMatrix = Matrix::create('SparseMatrix', $this->userNum, $this->itemNum);
// calculate prediction for each user-item pair
foreach ($this->userMap as $user_real_id => $user_matrix_index) {
foreach ($this->itemMap as $item_real_id => $item_matrix_index) {
// skip predictions on already existed preference ratings.
if (!$this->isBooleanRecommender && !is_nan($this->preferenceMatrix
->get($user_matrix_index, $item_matrix_index)) || $this->isBooleanRecommender && $this->preferenceMatrix
->get($user_matrix_index, $item_matrix_index) != 0) {
continue;
}
// $user_matrix_index is the current user's matrix index to computing. $j is the "similar users"
$numerator = 0;
$denominator = 0;
for ($j = 0; $j < $this->userNum; $j++) {
if ($j == $user_matrix_index) {
continue;
}
// skip myself.
if (is_nan($this->userVectors[$j]
->get($item_matrix_index))) {
continue;
}
// if no rating from j, skip.
$similarity_value = $this->similarityMatrix
->get($j, $user_matrix_index);
if (is_nan($similarity_value)) {
continue;
}
// skip if there is no similarity between $user_matrix_index and $j.
$mean_j = $this->isBooleanRecommender ? $this->userVectors[$j]
->mean(TRUE) : $this->userVectors[$j]
->intersect_mean($this->userVectors[$user_matrix_index]);
$normalized_j_score = $this->preferenceMatrix
->get($j, $item_matrix_index) - $mean_j;
$numerator += $normalized_j_score * $similarity_value;
$denominator += abs($similarity_value);
}
if ($denominator != 0) {
$prediction = $this->userVectors[$user_matrix_index]
->mean(TRUE) + $numerator / $denominator;
$this->predictionMatrix
->set($user_matrix_index, $item_matrix_index, $prediction);
}
}
}
}