You are here

protected function CFRecommender::loadPreference in Recommender API 7.6

Load matrix from the database into a matrix class in memory

1 call to CFRecommender::loadPreference()
CFRecommender::execute in classes/Recommender.php
Do all computation here.

File

classes/Recommender.php, line 67

Class

CFRecommender
This is the classical collaborative filtering implementation.

Code

protected function loadPreference() {
  $this->userNum = db_query("SELECT COUNT(DISTINCT {$this->structure['preference']['user field']}) FROM {$this->structure['preference']['name']}")
    ->fetchField();
  $this->itemNum = db_query("SELECT COUNT(DISTINCT {$this->structure['preference']['item field']}) FROM {$this->structure['preference']['name']}")
    ->fetchField();
  $fields = array(
    $this->structure['preference']['user field'],
    $this->structure['preference']['item field'],
    $this->structure['preference']['score field'],
  );
  if ($this->isBooleanRecommender) {
    unset($fields[2]);
  }
  $result = db_select($this->structure['preference']['name'], 'p')
    ->fields('p', $fields)
    ->execute();
  if ($this->userNum < 3 || $this->itemNum < 3 || $result
    ->rowCount() < 10) {
    throw new LengthException('Cannot run recommender due to insufficient data.');
  }

  // create Sparse matrix, might fail if not enough memory.
  $matrix_type = $this->isBooleanRecommender ? 'RealMatrix' : 'SparseMatrix';
  $this->preferenceMatrix = Matrix::create($matrix_type, $this->userNum, $this->itemNum);
  $this->userMap = array();
  $this->itemMap = array();

  // build the matrix
  while ($row = $result
    ->fetchAssoc()) {
    $user_id = $row[$this->structure['preference']['user field']];
    $item_id = $row[$this->structure['preference']['item field']];
    $score = $this->isBooleanRecommender ? 1 : $row[$this->structure['preference']['score field']];
    if (!array_key_exists($user_id, $this->userMap)) {
      $this->userMap[$user_id] = count($this->userMap);
    }
    if (!array_key_exists($item_id, $this->itemMap)) {
      $this->itemMap[$item_id] = count($this->itemMap);
    }
    $this->preferenceMatrix
      ->set($this->userMap[$user_id], $this->itemMap[$item_id], $score);
  }
}