怎样搭建自己的模型

2019-04-14 15:31发布

本节介绍一下如何搭建自己的模型 搭建自己的预测系统非常简单,使用一个从AlgoBase衍生过来的算法,并且含有estimate方法。
使用内置的user id和item id, 返回预测的评分值r^ui: import os from surprise import Reader from surprise import AlgoBase from surprise import Dataset from surprise.model_selection import cross_validate from surprise import KNNBaseline class MyOwnAlgorithm(AlgoBase): def __init__(self): #初始化使用的算法 #AlgoBase.__init__(self) KNNBaseline.__init__(self) def estimate(self, u, i): #预测函数 return 3 ##读取数据 #指定文件的路径 file_path = os.path.expanduser('ml-100k/u.data') #告诉文本阅读器,文本的格式是什么样子的 reader = Reader(line_format='user item rating timestamp', sep=' ') #加载数据 data = Dataset.load_from_file(file_path, reader=reader) algo = MyOwnAlgorithm() cross_validate(algo, data, verbose = True) Evaluating RMSE, MAE of algorithm MyOwnAlgorithm on 5 split(s). Fold 1 Fold 2 Fold 3 Fold 4 Fold 5 Mean Std RMSE (testset) 1.2502 1.2488 1.2378 1.2408 1.2430 1.2441 0.0047 MAE (testset) 1.0095 1.0059 0.9937 1.0000 0.9992 1.0017 0.0055 Fit time 0.00 0.02 0.02 0.02 0.02 0.01 0.01 Test time 0.07 0.07 0.07 0.07 0.07 0.07 0.00 {'test_rmse': array([1.25015999, 1.24879942, 1.23780047, 1.24084649, 1.24304063]), 'test_mae': array([1.0095 , 1.0059 , 0.99365, 1. , 0.99925]), 'fit_time': (0.0, 0.01707291603088379, 0.017518997192382812, 0.017546653747558594, 0.017040252685546875), 'test_time': (0.07319474220275879, 0.07066011428833008, 0.07072019577026367, 0.0691843032836914, 0.07066011428833008)} 现在这个算法很简单,只能返回3,没有考虑users和items的关系 如果想要增加预测的信息,可以返回一个包含详细信息的字典,这个字典将会保存到 prediction 中去,details可以在稍后的分析中使用 def estimate(self, u, i): details = {'info1' : 'That was', 'info2' : 'easy stuff :)'} return 3, details 现在让我们设计一个稍微聪明的算法,可以预测trainset的平均评分值,只一个不以来user和item的常数值,我们可以通过fit函数一次计算所有的评分。
可以在交叉验证过程中 cross_validate 会调用fit函数,在做任何事的时候,要首先调用fit函数,fit函数返回的是self,所以可以使用algo.fit(trainset).test(testset). class MyOwnAlgorithm(AlgoBase): def __init__(self): # 总是调用base method. AlgoBase.__init__(self) def fit(self, trainset): # Here again: call base method before doing anything. AlgoBase.fit(self, trainset) # 计算平均评分值. 我们可以使用trainset.global_mean attribute self.the_mean = np.mean([r for (_, _, r) in self.trainset.all_ratings()]) return self def estimate(self, u, i): return self.the_mean trainset属性
当fit()函数返回时,我们需要的所有的关于trainset的信息都会保存在self.trainset属性中,它是一个Trainset对象,包含许多关于预测的参数和方法。
为了展示它的使用方法,让我们来设计一个算法来计算所有评分的平均值,user的平均评分值和item的平均评分值。 def estimate(self, u, i): sum_means = self.trainset.global_mean div = 1 if self.trainset.knows_user(u): sum_means += np.mean([r for (_, r) in self.trainset.ur[u]]) div += 1 if self.trainset.knows_item(i): sum_means += np.mean([r for (_, r) in self.trainset.ir[i]]) div += 1 return sum_means / div 判断算法是否得到prediction是至关重要的,如果prediction是不可用的,可以输出PredictionImpossible异常,
需要导入 from surprise import PredictionImpossible
这个异常会被predict()函数调用,预测值r^ui会通过default_prediction()[可以重载]来计算,返回的是trainset所有评分的平均值。
使用相似度和baselines
如果算法想要使用相似度度量或者baseline预测,需要在 init 方法中添加 bsl_options 和 sim_options 两个参数,将它们传递给Base Class,
compute_baselines() 和 compute_similarities()方法可以在fit()方法或者在其他地方中调用。 class MyOwnAlgorithm(AlgoBase): def __init__(self, sim_options={}, bsl_options={}): AlgoBase.__init__(self, sim_options=sim_options, bsl_options=bsl_options) #训练方法 def fit(self, trainset): AlgoBase.fit(self, trainset) # 计算 baselines 和 相似度 self.bu, self.bi = self.compute_baselines() self.sim = self.compute_similarities() return self #预测方法,计算user[u]对items[i]的评分 def estimate(self, u, i): #如果没有那个User或者item数据,则异常 if not (self.trainset.knows_user(u) and self.trainset.knows_item(i)): raise PredictionImpossible('User and/or item is unkown.') # 计算u和v的相似度, v代表所有其他的用户,users 对 item[i] 评分过. neighbors = [(v, self.sim[u, v]) for (v, r) in self.trainset.ir[i]] # 按相似度的大小对 neighbors 进行排序 neighbors = sorted(neighbors, key=lambda x: x[1], reverse=True) print('The 3 nearest neighbors of user', str(u), 'are:') for v, sim_uv in neighbors[:3]: print('user {0:} with sim {1:1.2f}'.format(v, sim_uv)) # ... Aaaaand return the baseline estimate anyway ;) 在这里插入图片描述