推荐算法 Surprise(二)

使用自定义数据集:

Surprise有一些内置数据集,但您当然可以使用自定义数据集。评分数据可以从文件(如csv文件)或pandas 的Dataframe 来加载。无论哪种方法,都需要定义一个Reader对象来解析文件或Dataframe。

1. 从一个文件中上传数据集(例如csv文件),你需要 load_from_file()函数。

from surprise import BaselineOnly
from surprise import Dataset
from surprise.model_selection import cross_validate
from surprise import Reader
import os

file_path = os.path.expanduser(r'C:\Users\60191\.surprise_data\ml-100k\ml-100k\u.data')

reader = Reader(line_format='user item rating timestamp', sep='\t')

data = Dataset.load_from_file(file_path, reader=reader)

cross_validate(BaselineOnly(),data,verbose=True)

关于readers的更多细节和使用方法,请查阅Reader class文档。

2. 从pandas 的Dataframe 中获取数据,你需要load_from_df()函数。你还需要一个Reader对象,只需要设定参数rating_scale参数即可。dataframe必须包括三列,分别按顺序对应用户id,物品id以及评分。

import pandas as pd
from surprise import NormalPredictor
from surprise import Dataset
from surprise.model_selection import cross_validate
from surprise import Reader


ratings_dic = {'itemid':[1, 1, 1, 2, 2],
               'userid':[9, 32, 2, 45, 'user_foo'],
               'rating':[2, 2, 4, 3, 1]}
df = pd.DataFrame(ratings_dic)

reader = Reader(rating_scale=(1,5))

data = Dataset.load_from_df(df[['userid','itemid','rating']], reader)

cross_validate(NormalPredictor(),data,cv=2,verbose=True)

结果:

Evaluating RMSE, MAE of algorithm NormalPredictor on 2 split(s).

                  Fold 1  Fold 2  Mean    Std     
RMSE (testset)    2.0250  1.8865  1.9558  0.0693  
MAE (testset)     1.6772  1.6113  1.6442  0.0330  
Fit time          0.00    0.00    0.00    0.00    
Test time         0.00    0.00    0.00    0.00    

使用交叉验证迭代器:

我么可以使用cross_validate()函数做所有对我们来说困难的工作。但是为了更好的控制,我们实例化一个交叉验证迭代器,并使用迭代器的split()函数和test()函数在每一个split上做出预测。

如下,这是一个将数据集分为3折的经典K-折交叉验证实例。

from surprise import SVD
from surprise import Dataset
from surprise.model_selection import KFold
from surprise import accuracy


data = Dataset.load_builtin('ml-100k')

kf = KFold(n_splits=3)

algo = SVD()

for trainset,testset in kf.split(data):
    
    algo.fit(trainset)
    predictions = algo.test(testset)
    
    accuracy.rmse(predictions, verbose=True)

其结果是:

RMSE: 0.9427
RMSE: 0.9443
RMSE: 0.9471

其他验证器,例如留一法等交叉验证器也可使用,可以在这里查看所有的交叉验证器。

我们有时会遇到数据集已经被预划分为几个文件,例如 movielens-100k就分别提供了5个训练集和测试集。Surprise可以使用surprise.model_selection.split.PredefinedKFold对象来处理这种问题。(情况较少,没有进行翻译与测试,具体查看官方文档)

使用GridSearchCV调整算法参数:

cross_validate()函数可以对一组给定参数的交叉验程序进行准确性测评。如果你想知道哪些参数组合能够产生最好的结果,那么这个 GridSearchCV类就可以帮助你。给定一个参数dic,它会测试所有的参数组合,并报告对所有评测指标的最佳参数。这个想法受到scikit-learn的GridSearchCV的启发。

下面这个实例,我们测试了SVD算法的参数 n_epochs, lr_allreg_all 的不同值。

from surprise import SVD
from surprise import Dataset
from surprise.model_selection import GridSearchCV


data = Dataset.load_builtin('ml-100k')

para_grid = {'n_epochs':[5,10],
             'lr_all':[0.002,0.005],
             'reg_all':[0.4,0.6]}
gs = GridSearchCV(SVD, para_grid, measures=['rmse','mae'],cv=3)

gs.fit(data)

#获得rmse最好得分
print(gs.best_score['rmse'])

#获得使rmse最好得分的参数
print(gs.best_params['rmse'])

其结果:

0.9641795296927803
{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}

这里我们测试3折交叉验证过程的平均RMSE和MAE,但也可以使用任何交叉验证迭代器。

一旦fit()被调用,best_estimator会使我们得到参数被优化过的算法实例,我们可以这样使用:

algo = gs.best_estimator['rmse']
algo.fit(data.build_full_trainset())

注意:字典参数,例如bsl_optionssim_options需特殊对待。请参考以下例子:

param_grid = {'k': [10, 20],
              'sim_options': {'name': ['msd', 'cosine'],
                              'min_support': [1, 5],
                              'user_based': [False]}
              }

当然,两者可以结合,例如 KNNBaseline :

param_grid = {'bsl_options': {'method': ['als', 'sgd'],
                              'reg': [1, 2]},
              'k': [2, 3],
              'sim_options': {'name': ['msd', 'cosine'],
                              'min_support': [1, 5],
                              'user_based': [False]}
              }

进一步分析,cv_results包括所有的信息而且可以被导入到一个pandas的dataframe。

results_df = pd.DataFrame.from_dict(gs.cv_results)

在我们的例子中,cv_results看起来像这样(float格式):

'split0_test_rmse' : [ 1.0 , 1.0 , 0.97 , 0.98 , 0.98 , 0.99 , 0.96 , 0.97 ] 
'split1_test_rmse' : [ 1.0 , 1.0 , 0.97 , 0.98 , 0.98 , 0.99 , 0.96 , 0.97 ] 
'split2_test_rmse' : [ 1.0 , 1.0 , 0.97 , 0.98 , 0.98 , 0.99 , 0.96 , 0.97 ] 
'mean_test_rmse' :   [ 1.0 , 1.0 , 0.97 , 0.98 , 0.98 , 0.99 , 0.96 , 0.97 ] 
'std_test_rmse' :    [ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ] 
'rank_test_rmse' :   [ 7  8  3  5  4  6  1  2 ]
'split0_test_mae' :  [ 0.81 , 0.82 , 0.78 , 0.79 , 0.79 , 0.8 , 0.77 , 0.79 ] 
'split1_test_mae' :  [ 0.8 , 0.81 , 0.78 , 0.79 , 0.78 , 0.79 , 0.77 , 0.78 ] 
'split2_test_mae' :  [ 0.81 , 0.81 , 0.78 , 0.79 , 0.78 , 0.8 , 0.77 , 0.78 ] 
'mean_test_mae' :    [ 0.81 , 0.81 , 0.78 , 0.79 , 0.79 , 0.8 , 0.77 , 0.78 ] 
'std_test_mae' :     [ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ] 
'rank_test_mae' :    [ 7  8  2  5  4  6  1  3 ]
'mean_fit_time' :    [ 1.53 , 1.52 , 1.53 , 1.53 , 3.04 , 3.05 , 3.06 , 3.02 ] 
'std_fit_time' :     [ 0.03 , 0.04 , 0.0 , 0.01 , 0.04 , 0.01 , 0.06 , 0.01 ] 
'mean_test_time' :   [ 0.46 , 0.45 , 0.44 , 0.44 , 0.47 , 0.49 , 0.46 , 0.34 ] 
'std_test_time' :    [ 0.0 , 0.01 , 0.01 , 0.0 , 0.03 , 0.06 , 0.01 , 0.08 ] 
'PARAMS' :           [{ 'n_epochs' : 5 , 'lr_all' : 0.002 , 'reg_all' : 0.4 }, { 'n_epochs' : 5 , 'lr_all' : 0.002 , 'reg_all' : 0.6 }, {'n_epochs' : 5 , 'lr_all' : 0.005 , 'reg_all' : 0.4 }, { 'n_epochs' : 5 , 'lr_all' : 0.005 , 'reg_all' : 0.6 }, { 'n_epochs' : 10 , 'lr_all' : 0.002 , 'reg_all' : 0.4 }, { 'n_epochs' : 10 , 'lr_all' : 0.002 , 'reg_all' : 0。6 }, {'n_epochs' : 10 , 'lr_all' : 0.005 , 'reg_all' : 0.4 }, { 'n_epochs' : 10 , 'lr_all' : 0.4 ,0.6 ,0.4 ,0.6 ]0.005, 'reg_all': 0.6}]
'param_n_epochs':   [5, 5, 5, 5, 10, 10, 10, 10]
'param_lr_all':     [0.0, 0.0, 0.01, 0.01, 0.0, 0.0, 0.01, 0.01]
'param_reg_all':    [0.4, 0.6, 0.4, 0.6,    

你可以发现,每个列表具有相同大小的参数组合数,它对应下面的表格(参见官方文档)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值