-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit be562dd
Showing
21 changed files
with
1,928 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef _DATAMODEL_H_ | ||
#define _DATAMODEL_H_ | ||
|
||
#include <map> | ||
using namespace std; | ||
|
||
struct Rating { | ||
public: | ||
Rating(int u_id, int i_id, double score, long time): | ||
user_id(u_id),item_id(i_id),score(score),timestamp(time) {} | ||
Rating(){} | ||
int user_id; | ||
int item_id; | ||
double score; | ||
long timestamp; | ||
}; | ||
|
||
class Entity { | ||
public: | ||
Entity():rating_count(0),score_avg(0){} | ||
int id; | ||
int rating_count; | ||
double score_avg; | ||
map<int,Rating> ratings; | ||
}; | ||
|
||
class DataModel { | ||
public: | ||
DataModel():n_user(0),n_item(0),n_rating(0),user_0(0),item_0(0),entities(NULL),min_score(1),max_score(5){} | ||
DataModel(int n_u,int n_i,int n_r):n_user(n_u),n_item(n_i),n_rating(n_r),user_0(0),item_0(0),entities(NULL), | ||
min_score(1),max_score(5){} | ||
DataModel(int n_u,int n_i,int n_r,int u_0,int i_0):n_user(n_u),n_item(n_i),n_rating(n_r),user_0(u_0), | ||
item_0(i_0),entities(NULL),min_score(1),max_score(5){} | ||
DataModel(int n_u,int n_i,int n_r,double min_s,double max_s):n_user(n_u),n_item(n_i),n_rating(n_r),user_0(0), | ||
item_0(0),entities(NULL),min_score(min_s),max_score(max_s){} | ||
DataModel(int n_u,int n_i,int n_r,int u_0,int i_0,double min_s,double max_s):n_user(n_u),n_item(n_i), | ||
n_rating(n_r),user_0(u_0),item_0(i_0),entities(NULL),min_score(min_s),max_score(max_s){} | ||
int n_user; | ||
int n_item; | ||
int n_rating; | ||
int user_0; | ||
int item_0; | ||
double min_score; | ||
double max_score; | ||
Entity *entities; | ||
}; | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#ifndef _EVALUATE_H_ | ||
#define _EVALUATE_H_ | ||
|
||
#include "User.h" | ||
#include "Item.h" | ||
#include "Rating.h" | ||
#include <cmath> | ||
|
||
double evl_rmse(RatingModel testModel,RatingModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double rmse; | ||
for(int i = 0; i < testModel.n_rating; i++) { | ||
sum += pow(testModel.ratings[i].score - resultModel.ratings[i].score, 2); | ||
count ++; | ||
} | ||
rmse = sqrt(sum/count); | ||
return rmse; | ||
} | ||
|
||
double evl_rmse(UserModel testModel,UserModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double rmse; | ||
for(int u = testModel.user_0; u < testModel.n_user + testModel.user_0; u++) { | ||
map<int,Rating> &rs_1 = testModel.getRatings(u); | ||
map<int,Rating> &rs_2 = resultModel.getRatings(u); | ||
map<int,Rating>::iterator it2; | ||
for(map<int,Rating>::iterator it1 = rs_1.begin(); it1 != rs_1.end(); it1++) { | ||
int item = it1->first; | ||
if((it2 = rs_2.find(item)) != rs_2.end()) { | ||
sum += pow(it1->second.score - it2->second.score, 2); | ||
count ++; | ||
} | ||
} | ||
} | ||
rmse = sqrt(sum/count); | ||
return rmse; | ||
} | ||
|
||
double evl_rmse(ItemModel testModel,ItemModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double rmse; | ||
for(int i = testModel.item_0; i < testModel.n_item + testModel.item_0; i++) { | ||
map<int,Rating> &rs_1 = testModel.getRatings(i); | ||
map<int,Rating> &rs_2 = resultModel.getRatings(i); | ||
map<int,Rating>::iterator it2; | ||
for(map<int,Rating>::iterator it1 = rs_1.begin(); it1 != rs_1.end(); it1++) { | ||
int user = it1->first; | ||
if((it2 = rs_2.find(user)) != rs_2.end()) { | ||
sum += pow(it1->second.score - it2->second.score, 2); | ||
count ++; | ||
} | ||
} | ||
} | ||
rmse = sqrt(sum/count); | ||
return rmse; | ||
} | ||
|
||
double evl_mae(UserModel testModel,UserModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double mae; | ||
for(int u = testModel.user_0; u < testModel.n_user + testModel.user_0; u++) { | ||
map<int,Rating> &rs_1 = testModel.getRatings(u); | ||
map<int,Rating> &rs_2 = resultModel.getRatings(u); | ||
map<int,Rating>::iterator it2; | ||
for(map<int,Rating>::iterator it1 = rs_1.begin(); it1 != rs_1.end(); it1++) { | ||
int item = it1->first; | ||
if((it2 = rs_2.find(item)) != rs_2.end()) { | ||
sum += abs(it1->second.score - it2->second.score); | ||
count ++; | ||
} | ||
} | ||
} | ||
mae = sum/count; | ||
return mae; | ||
} | ||
|
||
double evl_mae(ItemModel testModel,ItemModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double mae; | ||
for(int i = testModel.item_0; i < testModel.n_item + testModel.item_0; i++) { | ||
map<int,Rating> &rs_1 = testModel.getRatings(i); | ||
map<int,Rating> &rs_2 = resultModel.getRatings(i); | ||
map<int,Rating>::iterator it2; | ||
for(map<int,Rating>::iterator it1 = rs_1.begin(); it1 != rs_1.end(); it1++) { | ||
int user = it1->first; | ||
if((it2 = rs_2.find(user)) != rs_2.end()) { | ||
sum += abs(it1->second.score - it2->second.score); | ||
count ++; | ||
} | ||
} | ||
} | ||
mae = sum/count; | ||
return mae; | ||
} | ||
|
||
double evl_mae(RatingModel testModel,RatingModel resultModel) | ||
{ | ||
double sum = 0; | ||
int count = 0; | ||
double mae; | ||
for(int i = 0; i < testModel.n_rating; i++) { | ||
sum += abs(testModel.ratings[i].score - resultModel.ratings[i].score); | ||
count ++; | ||
} | ||
mae = sum/count; | ||
return mae; | ||
} | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#include "FileDataReader.h" | ||
#include <iostream> | ||
#include <fstream> | ||
#include <vector> | ||
#include <cstring> | ||
|
||
bool FileDataReader::readData(UserModel &userModel) | ||
{ | ||
ifstream datafile(dataset_path.c_str(), ifstream::in); | ||
if(!datafile.good()) | ||
return false; | ||
int user,item; | ||
int user_0 = userModel.user_0; | ||
int item_0 = userModel.item_0; | ||
int user_n = userModel.user_0 + userModel.n_user - 1; | ||
double score; | ||
long timestamp; | ||
while(datafile >> user >> item >> score >> timestamp) { | ||
user -= user_0; | ||
item -= item_0; | ||
userModel.entities[user].id = user; | ||
userModel.entities[user].ratings[item] = Rating(user,item,score,timestamp); | ||
userModel.entities[user].score_avg += score; | ||
userModel.entities[user].rating_count ++; | ||
} | ||
for(int i = user_0; i <= user_n; i++) { | ||
if(userModel.entities[i].rating_count > 0) | ||
userModel.entities[i].score_avg /= userModel.entities[i].rating_count; | ||
} | ||
return true; | ||
} | ||
|
||
bool FileDataReader::readData(ItemModel &itemModel) | ||
{ | ||
ifstream datafile(dataset_path.c_str(), ifstream::in); | ||
if(!datafile.good()) | ||
return false; | ||
int user,item; | ||
int user_0 = itemModel.user_0; | ||
int item_0 = itemModel.item_0; | ||
int item_n = itemModel.item_0 + itemModel.n_item - 1; | ||
double score; | ||
long timestamp; | ||
while(datafile >> user >> item >> score >> timestamp) { | ||
user -= user_0; | ||
item -= item_0; | ||
itemModel.entities[item].id = item; | ||
itemModel.entities[item].ratings[user] = Rating(user,item,score,timestamp); | ||
itemModel.entities[item].score_avg += score; | ||
itemModel.entities[item].rating_count ++; | ||
} | ||
for(int i = item_0; i <= item_n; i++) { | ||
if(itemModel.entities[i].rating_count > 0) | ||
itemModel.entities[i].score_avg /= itemModel.entities[i].rating_count; | ||
} | ||
return true; | ||
} | ||
|
||
bool FileDataReader::readData(RatingModel &ratingModel) | ||
{ | ||
ifstream datafile(dataset_path.c_str(), ifstream::in); | ||
if(!datafile.good()) | ||
return false; | ||
int user,item; | ||
double score; | ||
long timestamp; | ||
long i = 0; | ||
while(datafile >> user >> item >> score >> timestamp) { | ||
user -= ratingModel.user_0; | ||
item -= ratingModel.item_0; | ||
ratingModel.ratings[i++] = Rating(user,item,score,timestamp); | ||
} | ||
return true; | ||
} | ||
|
||
bool FileDataReader::readData(UserItemModel &userItemModel) | ||
{ | ||
ifstream datafile(dataset_path.c_str(), ifstream::in); | ||
if(!datafile.good()) | ||
return false; | ||
int user,item; | ||
double score; | ||
long timestamp; | ||
while(datafile >> user >> item >> score >> timestamp) { | ||
user -= userItemModel.user_0; | ||
item -= userItemModel.item_0; | ||
long id = user * userItemModel.n_item + item; | ||
userItemModel.userItemRatings[id] = UserItem(id, Rating(user,item,score,timestamp)); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool FileDataReader::readUserSimRank(double *userRanks, string filepath) | ||
{ | ||
ifstream fin(filepath.c_str(),ifstream::in); | ||
if(!fin.good()) | ||
return false; | ||
int u; | ||
double rank; | ||
while(fin >> u >> rank) { | ||
userRanks[u] = rank; | ||
} | ||
fin.close(); | ||
return true; | ||
} | ||
|
||
bool FileDataReader::readUserComRank(double *userRanks, string filepath) | ||
{ | ||
ifstream fin(filepath.c_str(),ifstream::in); | ||
if(!fin.good()) | ||
return false; | ||
int u; | ||
double rank; | ||
while(fin >> u >> rank) { | ||
userRanks[u] = rank; | ||
} | ||
fin.close(); | ||
return true; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef _FILEDATAREADER_H_ | ||
#define _FILEDATAREADER_H_ | ||
|
||
#include <string> | ||
#include "Item.h" | ||
#include "User.h" | ||
#include "Rating.h" | ||
#include "UserItem.h" | ||
using namespace std; | ||
|
||
class FileDataReader { | ||
public: | ||
FileDataReader(string dataset_path): dataset_path(dataset_path) {} | ||
bool readData(UserModel &userModel); | ||
bool readData(ItemModel &itemModel); | ||
bool readData(RatingModel &ratingModel); | ||
bool readData(UserItemModel &user_itemModel); | ||
bool readUserSimRank(double *userRanks, string filepath); | ||
bool readUserComRank(double *userRanks, string filepath); | ||
|
||
private: | ||
string dataset_path; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef _ITEM_H_ | ||
#define _ITEM_H_ | ||
|
||
#include "DataModel.h" | ||
|
||
class ItemModel: public DataModel { | ||
public: | ||
ItemModel(){} | ||
ItemModel(int n_u,int n_i,int n_r):DataModel(n_u,n_i,n_r){ | ||
entities = new Entity[n_item+1]; | ||
} | ||
ItemModel(int n_u,int n_i,int n_r,int u_0,int i_0):DataModel(n_u,n_i,n_r,u_0,i_0){ | ||
entities = new Entity[n_item+1]; | ||
} | ||
|
||
bool findRating(int u, int i, Rating &r) { | ||
map<int,Rating> &rs = entities[i].ratings; | ||
map<int,Rating>::iterator it; | ||
if((it = rs.find(u)) != rs.end()) { | ||
r = it->second; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
double getScore_avg(int i) { | ||
return entities[i].score_avg; | ||
} | ||
|
||
double getScore(int u, int i) { | ||
map<int,Rating> &rs = entities[i].ratings; | ||
map<int,Rating>::iterator it; | ||
if((it = rs.find(u)) != rs.end()) { | ||
return it->second.score; | ||
} | ||
return min_score - 1; | ||
} | ||
|
||
map<int,Rating>& getRatings(int i) { | ||
return entities[i].ratings; | ||
} | ||
}; | ||
|
||
#endif |
Oops, something went wrong.