SLIM  1.0
Sparse Linear Methods (SLIM) for top-n recommender systems
 All Data Structures Files Functions Variables Typedefs Macros Pages
Functions
slim_predict.c File Reference

This file contains all the routines for SLIM testing. More...

#include <slim.h>

Go to the source code of this file.

Functions

void slim_predict (ctrl_t *ctrl, gk_csr_t *train, gk_csr_t *test, gk_csr_t *model)
 SLIM testing.
 
double * slim_test (ctrl_t *ctrl, gk_csr_t *model, gk_csr_t *train, gk_csr_t *test)
 Top-N recommendations and evaluations.
 
int suggest_predict (ctrl_t *ctrl, gk_csr_t *model, int **iidx, gk_csr_t *train, int u, gk_dkv_t **rcmd)
 Top-N recommendation for a user.
 

Detailed Description

This file contains all the routines for SLIM testing.

Definition in file slim_predict.c.

Function Documentation

void slim_predict ( ctrl_t ctrl,
gk_csr_t *  train,
gk_csr_t *  test,
gk_csr_t *  model 
)

SLIM testing.

This routine contains the testing method for SLIM

Parameters
[in]ctrlA ctrl structure which contains all the Parameters for SLIM testing
[in]trainThe training data, which has been used to learn the model
[in]testThe testing data
[in]modelThe model

Definition at line 26 of file slim_predict.c.

References ctrl_t::nratings, and slim_test().

Referenced by main().

{
printf("model->nrows = %d, model->ncols = %d\n", model->nrows, model->ncols);
/* sanity check */
model->ncols = model->nrows;
gk_csr_CreateIndex(model, GK_CSR_COL);
double * eval = slim_test(ctrl, model, train, test);
/* print the results */
for (int j = 0; j < ctrl->nratings; j ++)
printf("For rating value %3d HR = %.5f ARHR = %.5f cumulative HR = %.5f ARHR = %.5f\n",
j+1, eval[j*4], eval[j*4+1], eval[j*4+2], eval[j*4+3]);
/* clean up */
gk_free((void **)&eval, LTERM);
}
double* slim_test ( ctrl_t ctrl,
gk_csr_t *  model,
gk_csr_t *  train,
gk_csr_t *  test 
)

Top-N recommendations and evaluations.

Parameters
[in]ctrlA ctrl structure
[in]modelA model
[in]trainThe training data from which the model is learned
[in]testThe testing data
Returns
eval A set of evaluations

Definition at line 60 of file slim_predict.c.

References ctrl_t::dbglvl, display_timer(), end_timer(), ctrl_t::nratings, ctrl_t::pred_file, start_timer(), and suggest_predict().

Referenced by slim_predict().

{
int nu = test->nrows;
int nhits = 0;
double arh = 0;
int n = 0;
ctimer_t * timer = gk_malloc(sizeof(ctimer_t), "malloc timer");
start_timer(timer);
/* evaluation results for return */
double * eval = gk_malloc(sizeof(double)*(ctrl->nratings)*4, "malloc eval");
gk_dset(ctrl->nratings*4, 0, eval);
/* number of testing instances for each rating value */
int * nr = gk_malloc(sizeof(int)*ctrl->nratings, "malloc nr");
gk_iset(ctrl->nratings, 0, nr);
int ncols = gk_max(train->ncols, model->ncols);
int * nc = gk_malloc(sizeof(int)*ncols, "malloc nc");
gk_iset(ncols, 0, nc);
int * nhc = gk_malloc(sizeof(int)*ncols, "malloc nhc");
gk_iset(ncols, 0, nhc);
/* auxiliary_space */
int * iidx = NULL;
/* output file for predictions */
FILE * pfile = NULL;
if (ctrl->pred_file){
pfile = gk_fopen(ctrl->pred_file, "w", "pred file");
printf("Output predictions to %s file...\n", ctrl->pred_file);
}
/* predictions for all the users */
for (int u = 0; u < nu; u ++){
/* show the process */
if (u % 1000 == 0) {
if (ctrl->dbglvl == 0){
printf("."); fflush(stdout);
}
}
/* no testing instances for this user */
if (test->rowptr[u+1] - test->rowptr[u] == 0) {
if (ctrl->pred_file)
fprintf(pfile, "\n");
continue;
}
n ++;
/* top-n recommendation */
gk_dkv_t * rcmd = NULL;
int nrcmd = 0;
nrcmd = suggest_predict(ctrl, model, &iidx, train, u, &rcmd);
/* stats for the recommendation */
for (int kk = test->rowptr[u]; kk < test->rowptr[u+1]; kk ++){
int r = (int)(test->rowval[kk]); /* assume all ratings are integers [1, 2, ..., nratings] */
nr[r-1] ++ ;
nc[test->rowind[kk]] ++;
}
/* evaluations */
for (int jj = 0; jj < nrcmd; jj ++){
/* output the predictions */
if (ctrl->pred_file)
fprintf(pfile, "%d %.5f ", (int)rcmd[jj].val+1, rcmd[jj].key);
for (int kk = test->rowptr[u]; kk < test->rowptr[u+1]; kk ++){
int r = (int)(test->rowval[kk]); /* assume all ratings are integers [1, 2, ..., nratings] */
/* hit hit */
if (rcmd[jj].val == test->rowind[kk]){
nhc[test->rowind[kk]] ++;
/* overall hit rates */
nhits ++; arh += 1.0/(double)(jj + 1) ;
/* hit rates on different ratings */
eval[(r - 1)*4 + 0] += 1.0; /* hit rate on rating r */
eval[(r - 1)*4 + 1] += 1.0/(double)(jj + 1) ; /* arh on rating r */
eval[(r - 1)*4 + 2] = eval[(r - 1)*4 + 0];
eval[(r - 1)*4 + 3] = eval[(r - 1)*4 + 1];
}
}
}
/* finalize the prediction output */
if (ctrl->pred_file)
fprintf(pfile, "\n");
/* clean up */
gk_free((void **)&rcmd, LTERM);
}
/* end timing */
printf("\n");
end_timer(timer);
display_timer(timer, "SLIM prediction");
/* all stats */
for (int i = 0; i < ctrl->nratings; i ++){
if (nr[i] > 0){
eval[i*4 + 0] /= (double)nr[i];
eval[i*4 + 1] /= (double)nr[i];
}
}
/* cumulative stats */
for (int i = ctrl->nratings - 2; i >= 0; i --){
nr[i] += nr[i+1]; /* cumulative counts */
eval[i*4 + 2] += eval[(i+1)*4 + 2]; /* cumulative hit counts */
eval[i*4 + 3] += eval[(i+1)*4 + 3]; /* cumulative rhr counts */
}
for (int i = 0; i < ctrl->nratings; i ++){
if (nr[i] > 0){
eval[i*4 + 2] /= (double)nr[i];
eval[i*4 + 3] /= (double)nr[i];
}
}
/* finish up */
if (ctrl->pred_file)
gk_fclose(pfile);
gk_free((void **)&nc, LTERM);
gk_free((void **)&nhc, LTERM);
gk_free((void **)&nr, LTERM);
gk_free((void **)&timer, LTERM);
gk_free((void **)&iidx, LTERM);
return eval;
}
int suggest_predict ( ctrl_t ctrl,
gk_csr_t *  model,
int **  iidx,
gk_csr_t *  train,
int  u,
gk_dkv_t **  rcmd 
)

Top-N recommendation for a user.

Parameters
[in]ctrlA ctrl structure
[in]modelA model
[in]iidxAn auxiliary array for efficient recommendations
[in]trainTraining data from which the model is learned
[in]uThe index of the user for which the top-n recommendations are generated
[out]rcmdThe list of recommendations, in which the keys are the recommendation scores and the values are the item indices
Returns
int The actual number of recommendations

Definition at line 228 of file slim_predict.c.

References ctrl_t::topn.

Referenced by slim_test().

{
if (model->colptr == NULL)
gk_csr_CreateIndex(model, GK_CSR_COL);
int ni = train->ncols;
if (*iidx == NULL)
*iidx = gk_malloc(sizeof(int)*ni, "malloc *iidx");
gk_iset(ni, -1, *iidx);
int nuitrn = train->rowptr[u+1] - train->rowptr[u];
/* special case when no training data, thus no recommendations */
if (nuitrn == 0){
*rcmd = NULL;
return 0;
}
for (int ii = 0; ii < nuitrn; ii ++)
*(*iidx + *(train->rowptr[u] + ii + train->rowind)) -= 1;
gk_dkv_t * ccandb = gk_malloc(sizeof(gk_dkv_t)*ni, "malloc ccandb");
int nrcmd = 0;
/* efficient recommendations */
nuitrn = train->rowptr[u+1] - train->rowptr[u];
for (int i = 0; i < nuitrn; i ++){
int ii = *(train->rowptr[u] + i + train->rowind);
for (int j = 0; j < model->colptr[ii+1] - model->colptr[ii]; j ++){
int jj = *(model->colptr[ii] + j + model->colind);
if ((*iidx)[jj] < -1) continue;
if ((*iidx)[jj] == -1){
(*iidx)[jj] = nrcmd;
ccandb[nrcmd].key = *(model->colptr[ii] + j + model->colval) * 1.0;
ccandb[nrcmd].val = jj;
nrcmd ++;
}else{
ccandb[(*iidx)[jj]].key += *(model->colptr[ii] + j + model->colval) * 1.0;
}
}
}
/* sorting */
gk_dkvsortd(nrcmd, ccandb);
int nrcmd2 = gk_min(nrcmd, ctrl->topn);
*rcmd = ccandb;
return nrcmd2;
}