surprise库使用
这个库的安装就安装了四个小时,他会报错,说什么``Microsoft Visual C++ 14.0 is required`,找了很多资料和博客,但是那些博客的方案都没有作用,最后终于解决:
直接下载Microsoft Build Tools for Visual Studio 2019.
Build Tools中选择C++桌面开发,右边只选MSVC v142 和 Windows 10 SDK(前两项),即可解决
surprise官方文档:https://surprise.readthedocs.io/en/stable/getting_started.html
数据处理
surprise库作为开源推荐系统框架,他对数据集有着一定的要求,需要按照要求处理成它支持的格式。
数据格式:
每一行说明了user对item的评分,比如“2,1,1”,是指user-2对item-1的评分是1。
代码(读取源文件写入新文件,csv格式)
with open('./data/sur_DVD_Matrix.csv', 'w', encoding='utf-8', newline="") as f:
csv_writer = csv.writer(f)
for user in tqdm(range(num_user)):
for item in range(num_item):
if rating_old[user, item] != 0:
csv_writer.writerow([user, item, rating_old[user, item]])
数据读取
file_path = './data/sur_DVD_Matrix.csv'
# 告诉文本阅读器,文本的格式是怎么样的
reader = Reader(line_format='user item rating', sep=',')
# 加载数据
data = Dataset.load_from_file(file_path, reader=reader)
注意,这里读出来的data也不是surprise最终可以用来处理的数据,
接下来对读出来的data进行处理,才能成为surprise各种算法模型的处理对象,我这里使用的全部作为训练集
trainset = self.data.build_full_trainset()
还可以划分
trainset, testset = train_test_split(data, test_size=.25)
模型训练
可以使用GridSearchCV进行调参,选择效果最好的参数的模型
# 选择最好的参数
param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],
'reg_all': [0.4, 0.6]}
gs = GridSearchCV(SVD, param_grid, measures=['mae'], cv=3)
gs.fit(data)
# best RMSE score
print(gs.best_score['mae'])
# combination of parameters that gave the best RMSE score
print(gs.best_params['mae'])
#得到最好的参数对应的模型,进行训练
algo = gs.best_estimator['mae']
也可以不调参直接用(这里就algo=xxxxx想用哪个就用哪个)
algo = SVD()
algo.fit(trainset)
对于基于邻域的协同过滤还有一套相似度度量参数
官方文档:https://surprise.readthedocs.io/en/stable/prediction_algorithms.html#similarity-measures-configuration
pysim_options = {'name': 'cosine',#定义距离度量方式
'user_based': False
}
algo = KNNBasic()
模型评测
方法一:根据想用的评测指标直接三行代码出来就行
predictions = algo.test(testset)
# Compute and print Root Mean Squared Error
accuracy.rmse(predictions, verbose=True)
方法二:对每个数据进行打分,自己计算评测指标
surprise中想要打分,必须要对user和item对应的索引进行字符化
uid = str(i) # raw user id
iid = str(j) # raw item id
pred = algo.predict(uid, iid).est
sum = 0
for i, j in self.test_rating_list:
uid = str(i) # raw user id
iid = str(j) # raw item id
pred = algo.predict(uid, iid).est
sum += abs(self.ratingValues[i][j] - pred)
MAE = sum / 1000
print(MAE)