文章目录
Surprise库
Surprise(Simple Python Recommendation System Engine)是scikit系列的一个基于Python的构建和分析推荐系统的工具库。下面按照构建推荐系统并进行分析的流程梳理一遍涉及到的模块。
1. 加载数据模块
关于加载数据主要有surprise.Dataset读取数据模块和surprise.Reader数据解析模块。数据来源有以下四种:
- 加载库内置的数据:
Dataset.load_builtin(name)
,内建数据有‘ml-100k’, ‘ml-1m’和 ‘jester’,默认为’ml-100k’。
from surprise import SVD
from surprise import Dataset
from surprise import accuracy
from surprise.model_selection import KFold
# Load the movielens-100k dataset
data = Dataset.load_builtin('ml-100k')
# define a cross-validation iterator
kf = KFold(n_splits=3)
algo = SVD()
for trainset, testset in kf.split(data):
# train and test algorithm.
algo.fit(trainset)
predictions = algo.test(testset)
# Compute and print Root Mean Squared Error
accuracy.rmse(predictions, verbose=True)
- 从
pandas.DataFrame
加载数据:Dataset.load_from_df(df, reader)
。df
为pandas.DataFrame
格式,三列对应user_id
,item_id
,rating
。reader
为读取文件时的格式,是一个Reader
类,在这里只需要设置rating_scale
评分范围。
import pandas as pd
from surprise import Dataset
from surprise import Reader
# Creation of the dataframe. Column names are irrelevant.
ratings_dict = {'itemID': [1, 1, 1, 2, 2],
'userID': [9, 32, 2, 45, 'user_foo'],
'rating': [3, 2, 4, 3, 1]}
df = pd.DataFrame(ratings_dict)
# A reader is still needed but only the rating_scale param is requiered.
reader = Reader(rating_scale=(1, 5))
# The columns must correspond to user id, item id and ratings (in that order).
data = Dataset.load_from_df(df[['userID', 'itemID', 'rating']], reader)
- Reader:读取外部数据的时候需要用到,
surprise.reader.Reader(name, line_format, sep, rating_scale, skip_line)
。name
:可以选择内建数据集名称,使用时会忽略其他参数line_format
:定义每行格式,默认空格分割;sep
:设置分隔符;rating_scale
:设置rating
范围,格式为元组;skip_line
:默认为0。
- 从一个文件加载数据:
Dataset.load_from_file(file_path, reader)
。file_path
为数据集路径,reader
为文件解析类,包括每行格式、分隔符、评分范围等。
from surprise import Dataset
from surprise import Reader
# path to dataset file
file_path = os.path.expanduser('~/.surprise_data/ml-100k/ml-100k/u.data')
# As we're loading a custom dataset, we need to define a reader. In the
# movielens-100k dataset, each line has the following format:
# 'user item rating timestamp', separated by '\t' characters.
reader = Reader(line_format='user item rating timestamp', sep='\t')
data = Dataset.load_from_file(file_path, reader=reader)
- 针对数据已经划分好的情况,加载多个文件:
Dataset.load_from_folds(folds_file, reader)
。
from surprise import SVD
from surprise import Dataset
from surprise import Reader
from surprise import accuracy
from surprise.model_selection import PredefinedKFold
# path to dataset folder
files_dir = os.path.expanduser('~/.surprise_data/ml-100k/ml-100k/')
# This time, we'll use the built-in reader.
reader = Reader('ml-100k')
# folds_files is a list of tuples containing file paths:
# [(u1.base, u1.test), (u2.base, u2.test), ... (u5.base, u5.test)]
train_file = files_dir + 'u%d.base'
test_file = files_dir + 'u%d.test'
folds_files = [(train_file % i, test_file % i) for i in (1, 2, 3, 4, 5)]
data = Dataset.load_from_folds(folds_files, reader=reader)
pkf = PredefinedKFold()
algo = SVD()
for trainset, testset in pkf.split(data):
# train and test algorithm.
algo.fit(trainset)
predictions = algo.test(testset)
# Compute and print Root Mean Squared Error
accuracy.rmse(predictions, verbose=True)
2. 模型训练前的数据划分模块
这部分方法都位于surprise.model_selection.split部分。
2.1 交叉验证数据划分
方法名 | 说明 |
---|---|
KFold(n_splits=5, random_state=None, shuffle=True) | 基本的K折交叉验证迭代器 |
LeaveOneOut(n_splits=5, random_state=None, min_n_ratings=0) | 留一法 |
PredefinedKFold | 使用Dataset.load_from_folds加载数据时使用 |
RepeatedKFold(n_splits=5, n_repeats=10, random_state=None) | 使用不同的随机数重复n次k折交叉验证 |
ShuffleSplit(n_splits=5, test_size=0.2, train_size=None, random_state=None, shuffle=True) | 随机训练集和测试集的基本交叉验证迭代器 |
2.2 训练集测试集划分
train_test_split(data, test_size=0.2, train_size=None, random_state=None, shuffle=True)
3 构建算法模块
3.1 记号说明
符号 | 说明 |
---|---|
R R R | 评分集 |
R t r a i n R_{train} Rtrain, R t e s t R_{test} Rtest, R ^ \hat R R^ | 训练集,测试集,预测集 |
U U U | user集合 |
u u u, v v v | user |
I I I | item集合 |
i i i, j j j | item |
U i U_i Ui | 对item i有评分的user集合 |
U i j U_{ij} Uij | 同时对item i和j有评分的user集合 |
I u I_u Iu | user u评分过的item集合 |
I u v I_{uv} Iuv | user u和v共同评分过的item集合 |
r u i r_{ui} rui | user u对item i的真实评分 |
r ^ u i \hat r_{ui} r^ui | user u对item i的估计评分 |
b u i b_{ui} bui | user u对item i的baseline评分, b u i = μ + b u + b i b_{ui}=\mu+b_u+b_i bui=μ+bu+bi |
μ \mu μ | 所有评分的均值 |
μ u \mu_u μu | user u给出的所有评分的均值 |
μ i \mu_i μi | 打给item i的所有评分的均值 |
σ u \sigma_u σu | user u给出的所有评分的标准差 |
σ i \sigma_i σi | item i收到的所有评分的标准差 |
N i ( u ) k N_{i(u)}^k Ni(u)k | 给item i有评分的user u的k个近邻user集合,使用相似度指标计算得到 |
N u ( i ) k N_{u(i)}^k Nu(i)k | user u打过分的item i的k个近邻item集合,使用相似度指标计算得到 |
3.2 基于统计的算法
基于surprise.prediction_algorithms模块
- 随机预测:
random_pred.NormalPredictor
假设训练集评分服从正态分布,根据训练集数据进行最大似然估计得到评分的均值 μ ^ \hat\mu μ^和标准差 σ ^ \hat\sigma σ^,构建正态分布 N ( μ , σ ) N(\mu,\sigma) N(μ,σ),由正态分布产生预测结果。
μ ^ = ∑ r u i ∈ R t r a i n r u i ∣ R t r a i n ∣ \hat{\mu}=\frac{\sum_{r_{ui}\in{R_{train}}}r_{ui}}{|R_{train}|} μ^=∣Rtrain∣∑rui∈Rtrainrui
σ ^ = ∑ ( r u i − μ ^ ) 2 ∣ R t r a i n ∣ \hat{\sigma}=\sqrt{\frac{\sum(r_{ui}-\hat{\mu})^2}{|R_{train}|}} σ^=∣Rtrain∣∑(rui−μ^)2 - baseline:
baseline_only.BaselineOnly(bsl_options={}, verbose=True)
假设函数为 r u i = b u i = μ + b u + b i r_{ui}=b_{ui}=\mu+b_u+b_i rui=bui=μ+bu+bi,则需要最小化 ∑ r u i ∈ R t r a i n ( r u i − ( μ + b u + b i ) ) 2 + λ ( ∑ u b u 2 + ∑ i b i 2 ) \sum_{r_{ui}\in R_{train}}(r_{ui}-(\mu+b_u+b_i))^2+\lambda (\sum_u b_u^2+\sum_i b_i^2) ∑rui∈Rtrain(rui−(μ+bu+bi))2+λ(∑ubu2+∑ibi2),使用Stochastic Gradient Descent (SGD)
或Alternating Least Squares(ALS)
进行求解。
使用SGD时,损失函数为 ∑ r u i ∈ R t r a i n ( r u i − ( μ + b u + b i ) ) 2 + λ ( ∑ u b u 2 + ∑ i b i 2 ) \sum_{r_{ui}\in R_{train}}(r_{ui}-(\mu+b_u+b_i))^2+\lambda (\sum_u b_u^2+\sum_i b_i^2) rui∈Rtrain∑(rui−(μ+bu+bi))2+λ(u∑bu2+i∑bi2)参数有:
参数 | 说明 | 默认值 |
---|---|---|
reg | 损失函数的正则化参数 λ \lambda λ | 0.02 |
learning_rate | 学习率 | 0.005 |
n_epochs | 迭代次数 | 20 |
print('Using SGD')
bsl_options = {'method': 'sgd',
'learning_rate': .00005,
'n_epochs': 20
}
algo = BaselineOnly(bsl_options=bsl_options)
使用ALS时,损失函数为 ∑ r u i ∈ R t r a i n ( r u i − ( μ + b u + b i ) ) 2 + λ 1 ∑ u b u 2 + λ 2 ∑ i b i 2 \sum_{r_{ui}\in R_{train}}(r_{ui}-(\mu+b_u+b_i))^2+\lambda_1\sum_u b_u^2+\lambda_2\sum_i b_i^2 rui∈Rtrain∑(rui−(μ+bu+bi))2+λ1u∑bu2+λ2i∑bi2参数有:
参数 | 说明 | 默认值 |
---|---|---|
reg_u | item的正则化参数 λ 1 \lambda_1 λ1 | 15 |
reg_i | user的正则化参数 λ 2 \lambda_2 λ2 | 10 |
n_epochs | ALS过程的迭代次数 | 10 |
bsl_options = {'method': 'als',
'n_epochs': 5,
'reg_u': 12,
'reg_i': 5
}
algo = BaselineOnly(bsl_options=bsl_options)
3.3 基于近邻(协同过滤)的方法
3.3.1 相似度计算模块
sim_options={name, user_based, min_support ,shrinkage}
。
name
表示相似度计算方法,有cosine
,msd
,pearson
,pearson_baseline
四种;- Cosine similarity
c o s i n e _ s i m ( u , v ) = ∑ i ∈ I u v r u i r v i ∑ i ∈ I u v r u i 2 ∑ i ∈ I u v r v i 2 cosine\_sim(u,v)=\frac{\sum_{i\in{I_{uv}}}r_{ui}r_{vi}}{\sqrt{\sum_{i\in{I_{uv}}}r_{ui}^2}\sqrt{\sum_{i\in{I_{uv}}}r_{vi}^2}} cosine_sim(u,v)=∑i∈Iuvrui2∑i∈Iuvrvi2∑i∈Iuvruirvi - Mean Squared Difference similarity
m s d ( u , v ) = 1 ∣ I u v ∣ ∑ i ∈ I u v ( r u i − r v i ) 2 msd(u,v)=\frac{1}{|I_{uv}|}\sum_{i\in{I_{uv}}}(r_{ui}-r_{vi})^2 msd(u,v)=∣Iuv∣1i∈Iuv∑(rui−rvi)2
m s d _ s i m ( u , v ) = 1 1 + m s d ( u , v ) msd\_sim(u,v)=\frac{1}{1+msd(u,v)} msd_sim(u,v)=1+msd(u,v)1 - Pearson similarity
p e a r s o n _ s i m ( u , v ) = ∑ i ∈ I u v ( r u i − μ u ) ( r v i − μ v ) ∑ i ∈ I u v ( r u i − μ u ) 2 ∑ i ∈ I u v ( r v i − μ v ) 2 pearson\_sim(u,v)=\frac{\sum_{i\in{I_{uv}}}(r_{ui}-\mu_u)(r_{vi}-\mu_v)}{\sqrt{\sum_{i\in{I_{uv}}}(r_{ui}-\mu_u)^2}\sqrt{\sum_{i\in{I_{uv}}}(r_{vi}-\mu_v)^2}} pearson_sim(u,v)=∑i∈Iuv(rui−μu)2∑i∈Iuv(rvi−μv)2∑i∈Iuv(rui−μu)(rvi−μv) - Pearson baseline similarity:使用baseline
b
u
i
b_{ui}
bui取代mean
p e a r s o n _ b a s e l i n e _ s i m ( u , v ) = ∑ i ∈ I u v ( r u i − b u i ) ( r v i − b v i ) ∑ i ∈ I u v ( r u i − b u i ) 2 ∑ i ∈ I u v ( r v i − b v i ) 2 pearson\_baseline\_sim(u,v)=\frac{\sum_{i\in{I_{uv}}}(r_{ui}-b_{ui})(r_{vi}-b_{vi})}{\sqrt{\sum_{i\in{I_{uv}}}(r_{ui}-b_{ui})^2}\sqrt{\sum_{i\in{I_{uv}}}(r_{vi}-b_{vi})^2}} pearson_baseline_sim(u,v)=∑i∈Iuv(rui−bui)2∑i∈Iuv(rvi−bvi)2∑i∈Iuv(rui−bui)(rvi−bvi)
当评分矩阵十分稀疏时,使用下式计算以减少过拟合
p e a r s o n _ b a s e l i n e _ s h r i n k _ s i m ( u , v ) = ∣ I u v ∣ − 1 ∣ I u v ∣ − 1 + s h r i n k a g e p e a r s o n _ b a s e l i n e _ s i m ( u , v ) pearson\_baseline\_shrink\_sim(u,v)=\frac{|I_{uv}|-1}{|I_{uv}|-1+shrinkage}pearson\_baseline\_sim(u,v) pearson_baseline_shrink_sim(u,v)=∣Iuv∣−1+shrinkage∣Iuv∣−1pearson_baseline_sim(u,v)
- Cosine similarity
user_based
表示是否是基于用户的相似度,True
表示基于用户的相似度,False
表示基于物品的相似度;min_support
表示认为两个user或item具有相似性时具有的最少相同数量的item或user,数目小于min_support
的user或item会被认为相似性为0;shrinkage
是在name=pearson_baseline
时有用,默认值为100。
3.3.2 预测算法
knns.KNNBasic(k=40, min_k=1, sim_options={}, verbose=True)
:基本的基于物品or用户的协同过滤
r
^
u
i
=
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
×
r
v
i
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
\hat r_{ui}=\frac{\sum_{v\in{N_{i(u)}^k}}sim(u,v)\times r_{vi}}{\sum_{v\in{N_{i(u)}^k}}sim(u,v)}
r^ui=∑v∈Ni(u)ksim(u,v)∑v∈Ni(u)ksim(u,v)×rvi
knns.KNNWithMeans(k=40, min_k=1, sim_options={}, verbose=True)
:考虑用户/物品偏好的协同过滤
r
^
u
i
=
μ
u
+
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
×
(
r
v
i
−
μ
v
)
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
\hat r_{ui}=\mu_u+\frac{\sum_{v\in{N_{i(u)}^k}}sim(u,v)\times (r_{vi}-\mu_v)}{\sum_{v\in{N_{i(u)}^k}}sim(u,v)}
r^ui=μu+∑v∈Ni(u)ksim(u,v)∑v∈Ni(u)ksim(u,v)×(rvi−μv)
knns.KNNWithZScore(k=40, min_k=1, sim_options={}, verbose=True)
考虑用户/物品偏好,并对用户/物品进行z-score
归一化
r
^
u
i
=
μ
u
+
σ
u
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
×
(
r
v
i
−
μ
v
)
÷
σ
v
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
\hat r_{ui}=\mu_u+\sigma_u \frac{\sum_{v\in{N_{i(u)}^k}}sim(u,v)\times (r_{vi}-\mu_v)\div\sigma_v}{\sum_{v\in{N_{i(u)}^k}}sim(u,v)}
r^ui=μu+σu∑v∈Ni(u)ksim(u,v)∑v∈Ni(u)ksim(u,v)×(rvi−μv)÷σv
knns.KNNBaseline(k=40, min_k=1, sim_options={}, bsl_options={}, verbose=True)
基于baseline的协同过滤
r
^
u
i
=
b
u
i
+
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
×
(
r
v
i
−
b
v
i
)
∑
v
∈
N
i
(
u
)
k
s
i
m
(
u
,
v
)
\hat r_{ui}=b_{ui}+\frac{\sum_{v\in{N_{i(u)}^k}}sim(u,v)\times (r_{vi}-b_{vi})}{\sum_{v\in{N_{i(u)}^k}}sim(u,v)}
r^ui=bui+∑v∈Ni(u)ksim(u,v)∑v∈Ni(u)ksim(u,v)×(rvi−bvi)
3.4 基于矩阵分解的方法
- Simon Funk2016年参加Netflix Prize期间在博客公开了一个算法Funk-SVD,也称为Latent Factor Model。
假设函数为 r ^ u i = q i T p u \hat r_{ui}=q_i^Tp_u r^ui=qiTpu,等同于概率矩阵分解Probabilistic Matrix Factorization。 matrix_factorization.SVD
,考虑偏置项的LFM,也称为bias-SVD
假设函数为 r ^ u i = μ + b u + b i + q i T p u \hat r_{ui}=\mu+b_u+b_i+q_i^Tp_u r^ui=μ+bu+bi+qiTpu
构造损失函数为
∑ r u i ∈ R t r a i n ( r u i − r ^ u i ) 2 + λ ( b u 2 + b i 2 + ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 ) \sum_{r_{ui}\in {R_{train}}}(r_{ui}-\hat r_{ui})^2+\lambda(b_u^2+b_i^2+||q_i||^2+||p_u||^2) rui∈Rtrain∑(rui−r^ui)2+λ(bu2+bi2+∣∣qi∣∣2+∣∣pu∣∣2)
带入假设函数得 ∑ r u i ∈ R t r a i n ( r u i − ( μ + b u + b i + q i T p u ) ) 2 + λ ( b u 2 + b i 2 + ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 ) \sum_{r_{ui}\in {R_{train}}}(r_{ui}-(\mu+b_u+b_i+q_i^Tp_u))^2+\lambda(b_u^2+b_i^2+||q_i||^2+||p_u||^2) rui∈Rtrain∑(rui−(μ+bu+bi+qiTpu))2+λ(bu2+bi2+∣∣qi∣∣2+∣∣pu∣∣2)
使用SGD的迭代公式如下:
b u = b u + γ ( r u i − r ^ u i − λ b u ) b_u = b_u + \gamma(r_{ui}-\hat r_{ui}-\lambda b_u) bu=bu+γ(rui−r^ui−λbu)
b i = b i + γ ( r u i − r ^ u i − λ b i ) b_i = b_i + \gamma(r_{ui}-\hat r_{ui}-\lambda b_i) bi=bi+γ(rui−r^ui−λbi)
q i = q i + γ ( ( r u i − r ^ u i ) p u − λ q i ) q_i = q_i + \gamma((r_{ui}-\hat r_{ui})p_u-\lambda q_i) qi=qi+γ((rui−r^ui)pu−λqi)
p u = p u + γ ( ( r u i − r ^ u i ) q i − λ p u ) p_u = p_u + \gamma((r_{ui}-\hat r_{ui})q_i-\lambda p_u) pu=pu+γ((rui−r^ui)qi−λpu)
其中 γ \gamma γ是学习速率, λ \lambda λ是正则化系数。
算法参数:
参数名 | 说明 | 默认值 |
---|---|---|
n_factor | 设置的factor数目 | 100 |
n_epochs | SGD算法的迭代次数 | 20 |
biased | 是否使用bias-SVD,True使用bias-SVD,False使用SVD | True |
lr_all | 所有参数的学习速率,也可以针对不同的参数设置不同的学习速率 | 0.005 |
reg_all | 所有参数的正则化系数,也可以针对不同的参数设置不同的正则化系数 | 0.02 |
返回 p u p_u pu, q i q_i qi, b u b_u bu, b i b_i bi。
matrix_factorization.SVDpp
前面的LFM模型并没有显式地考虑用户的历史行为对用户评分预测的影响。Koren在Netflix Prize比赛中提出了一个模型,将用户历史评分的物品加入到了LFM模型中,结合了基于item的邻域方法(item-CF)和LFM,称为SVD++。(论文:Factor in the Neigbhorhood: Scalable and Accurate Collaborative Filtering)
假设函数为:
r ^ u i = μ + b u + b i + q i T p u + 1 ∣ I u ∣ ∑ j ∈ I u w i j \hat r_{ui}=\mu+b_u+b_i+q_i^Tp_u+\frac{1}{|I_u|}\sum_{j\in I_u}w_{ij} r^ui=μ+bu+bi+qiTpu+∣Iu∣1j∈Iu∑wij
将物品相似度矩阵 w i j w_{ij} wij同样进行分解,得:
r ^ u i = μ + b u + b i + q i T p u + 1 ∣ I u ∣ x i T ∑ j ∈ I u y j \hat r_{ui}=\mu+b_u+b_i+q_i^Tp_u+\frac{1}{|I_u|}x_i^T\sum_{j\in I_u}y_j r^ui=μ+bu+bi+qiTpu+∣Iu∣1xiTj∈Iu∑yj
为了缓解过拟合,令 x = q x=q x=q,得
r ^ u i = μ + b u + b i + q i T ( p u + 1 ∣ I u ∣ ∑ j ∈ I u y j ) \hat r_{ui}=\mu+b_u+b_i+q_i^T(p_u+\frac{1}{|I_u|}\sum_{j\in I_u}y_j) r^ui=μ+bu+bi+qiT(pu+∣Iu∣1j∈Iu∑yj)
后面构造损失函数,以及算法的超参数与bias-SVD相似。matrix_factorization.NMF
Non-negative Matrix Factorization (NMF)
,一种基于非负矩阵分解的协同过滤算法。假设函数为 r ^ u i = μ + b u + b i + q i T p u \hat r_{ui}=\mu+b_u+b_i+q_i^Tp_u r^ui=μ+bu+bi+qiTpu,与SVD的区别在于 q i q_i qi和 p u p_u pu的值在任何时候都是非负的。相关论文有:- Daniel D. Lee and H. Sebastian Seung. Algorithms for non-negative matrix factorization. 2001.
- Xin Luo, Mengchu Zhou, Yunni Xia, and Qinsheng Zhu. An efficient non-negative matrix factorization-based approach to collaborative filtering for recommender systems. 2014.
- Sheng Zhang, Weihong Wang, James Ford, and Fillia Makedon. Learning from incomplete ratings using non-negative matrix factorization. 1996.
模型参数有:
参数名 | 说明 | 默认值 |
---|---|---|
n_factor | 设置的factor数目 | 15 |
n_epochs | SGD算法的迭代次数 | 50 |
biased | 是否使用偏置项 | False |
reg_pu | p u p_u pu的正则化系数 | 0.06 |
reg_qi | q i q_i qi的正则化系数 | 0.06 |
reg_bu | b u b_u bu的正则化系数,biased=True时有效 | 0.02 |
reg_bi | b i b_i bi的正则化系数,biased=True时有效 | 0.02 |
lr_bu | b u b_u bu的学习速率,biased=True时有效 | 0.005 |
lr_bi | b i b_i bi的学习速率,biased=True时有效 | 0.005 |
init_low | factor随机初始化的下界,必须大于等于0 | 0 |
init_high | factor随机初始化的上界 | 1 |
4. 交叉验证和超参数优化
validation.cross_validate(algo, data, measures=[u'rmse', u'mae'], cv=None, return_train_measures=False, n_jobs=1, pre_dispatch=u'2*n_jobs', verbose=False)
对于给定的算法和数据运行交叉验证过程,返回正确性和花费时间的报告。
from surprise import SVD
from surprise import Dataset
from surprise.model_selection import cross_validate
# Load the movielens-100k dataset (download it if needed),
data = Dataset.load_builtin('ml-100k')
# We'll use the famous SVD algorithm.
algo = SVD()
# Run 5-fold cross-validation and print results
cross_validate(algo, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)
search.GridSearchCV(algo_class, param_grid, measures=[u'rmse', u'mae'], cv=None, refit=False, return_train_measures=False, n_jobs=1, pre_dispatch=u'2*n_jobs', joblib_verbose=0)
:网格搜索交叉验证
from surprise import SVD
from surprise import Dataset
from surprise.model_selection import GridSearchCV
# Use movielens-100K
data = Dataset.load_builtin('ml-100k')
param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],
'reg_all': [0.4, 0.6]}
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3)
gs.fit(data)
# best RMSE score
print(gs.best_score['rmse'])
# combination of parameters that gave the best RMSE score
print(gs.best_params['rmse'])