【协同过滤算法——Day11】
搭建智能推荐系统的算法有很多,其中商业实战中用的较多的为协同过滤(collaborative filtering)。
文章目录
协同过滤算法的原理
根据用户群体对产品偏好的数据,发现用户之间的相似性或者物品之间的相似性,并基于这些相似性为用户作推荐。
- 基于用户的协同过滤算法(User-based Collaborative Filtering)
其本质是:寻找相似的用户,进而对用户推荐相似用户关注的产品
- 基于物品的协同过滤算法(Item-based Collaborative Filtering)
其本质是:根据用户的历史偏好信息,将类似的物品推荐给用户
在商业实战中,大多应用场景偏向于使用基于物品的协同过滤算法。主要有如下两个原因:
原因一:通常用户的数量是非常庞大的(如淘宝数亿的用户群体),而物品的数量相对有限,因此计算不同物品之间的相似度往往比计算不同用户的相似度容易很多。
原因二:用户的喜好较为多变,而物品属性较明确不随时间变化,过去用户对物品的评分长期有效,所以物品间的相似度比较固定,因此可以预先离线计算好物品间的相似度,把结果存在表中,向客户进行推荐时再使用。
相似度计算的常用方法
无论是基于用户还是基于物品的协同过滤算法,其本质都是寻找数据之间的相似度。本节介绍计算相似度的三种常见方法:
- 欧式距离
∑ i = 1 n ( X i ( a ) − X i ( b ) ) 2 \Large \sqrt{\sum_{i=1}^n{(X_i^{(a)}-X_i^{(b)})}^2} i=1∑n(Xi(a)−Xi(b))2
- 余弦相似度
使用两向量夹角θ的余弦值cosθ来表示两个向量的相似度,称为余弦相似度。余弦相似度的范围是:[-1,1],夹角越小,余弦值越接近于1,两个向量越靠近,两者越相似。两个向量有相同的指向时,余弦相似度的值为1;两个向量夹角为90°时,余弦相似度的值为0;两个向量指向完全相反的方向时,余弦相似度的值为-1。
余弦相似度公式为:
c
o
s
θ
=
<
a
,
b
>
∣
∣
a
∣
∣
∣
∣
b
∣
∣
\Large cos\theta = \frac{<a,b>}{|| a|||| b||}
cosθ=∣∣a∣∣∣∣b∣∣<a,b>
其中,<a,b>表示的是向量a和向量b的内积,||a||和||b||分别表示向量a和向量b的模(长度)。
例如,向量a=(X1,Y1),向量b=(X2,Y2),代入余弦相似度公式可以得到:
c
o
s
θ
=
X
1
∗
X
2
+
Y
1
∗
Y
2
X
1
2
+
Y
1
2
∗
X
2
2
+
Y
2
2
cos\theta = \frac{X_1*X_2+Y_1*Y_2}{\sqrt{X_1^2+Y_1^2}*\sqrt{X_2^2+Y_2^2}}
cosθ=X12+Y12∗X22+Y22X1∗X2+Y1∗Y2
可以将其推广至n维向量空间:
若向量a=(X1,X2,X3,…,Xn),向量b=(Y1,Y2,Y3,…,Yn),其夹角的余弦值(余弦相似度)可以表示为:
c
o
s
θ
=
x
1
∗
y
1
+
x
2
∗
y
2
+
x
3
∗
y
3
+
.
.
.
+
x
n
∗
y
n
x
1
2
+
x
2
2
+
x
3
2
+
.
.
.
+
x
n
2
∗
y
1
2
+
y
2
2
+
y
3
2
+
.
.
.
+
y
n
2
cos\theta = \frac{x_1*y_1+x_2*y_2+x_3*y_3+...+x_n*y_n}{\sqrt{x_1^2+x_2^2+x_3^2+...+x_n^2}*\sqrt{y_1^2+y_2^2+y_3^2+...+y_n^2}}
cosθ=x12+x22+x32+...+xn2∗y12+y22+y32+...+yn2x1∗y1+x2∗y2+x3∗y3+...+xn∗yn
- 皮尔逊相关系数
皮尔逊相关系数r是用来描述两个数值型变量间线性相关强弱程度的统计量,r的绝对值越大表明相关性越强。r取值范围为[-1,1],为正代表两个变量存在正相关,为负代表两个变量存在负相关,r=0,说明两个变量之间无线性相关关系。要计算变量X与Y的皮尔逊相关系数,其计算公式如下:
r
=
C
o
v
(
X
,
Y
)
S
X
S
Y
\Large r=\frac{Cov(X,Y)}{S_XS_Y}
r=SXSYCov(X,Y)
其中SX和SY分别为变量X和变量Y的标准差,COV(X,Y)为变量X和变量Y的协方差。
相似度计算的Python实现
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=imgs%5Cimage-20230109103400598.png&pos_id=img-fdLMwFyQ-1718761693220
- 欧式距离的Python实现
利用numpy库的norm可以间接地计算两个向量的欧氏距离
import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
import numpy as np
dist = np.linalg.norm(df.iloc[0] - df.iloc[1])
- 余弦相似度的Python实现
通过sklearn的cosine_similarity函数实现余弦相似度的计算
import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
from sklearn.metrics.pairwise import cosine_similarity
# 对两两样本之间(此处是物品之间)做余弦相似度矩阵
item_similarity = cosine_similarity(df)
pd.DataFrame(item_similarity, columns=['物品A', '物品B', '物品C'], index=['物品A', '物品B', '物品C'])
- 皮尔逊相关系数的Python实现
通过scipy库中的pearsonr函数实现皮尔逊相关系数的计算
只需给它两个数组或列表(X,Y),它就能返回两个数值(r,P):
相关系数r值在[-1,1]之间,为正数则表示正相关,负数则表示负相关,绝对值越大相关性越高;
P值是显著性,与皮尔逊相关显著性检验有关,P<0.05时表示相关显著,即指变量X和Y之间真的存在相关性,而不是因为偶然因素引起的。
from scipy.stats import pearsonr
X = [1, 3, 5, 7, 9]
Y = [9, 8, 6, 4, 2]
corr = pearsonr(X, Y)
print("皮尔逊相关系数r的值为:",corr[0],"显著性水平P值为:",corr[1])
相关系数在DataFrame中的应用
在项目中计算相关系数的场景里,DataFrame的corrwith()和corr()方法经常被使用
- corrwith()
dataframe.corrwith()用于计算行或列之间的成对相关关系
- corr()
dataframe.corr()用于计算DataFrame中所有列的成对相关性
import pandas as pd
df = pd.DataFrame([[5, 4, 4], [1, 2, 2], [5, 2, 1]], columns=[‘物品A’, ‘物品B’, ‘物品C’], index=[‘用户1’, ‘用户2’, ‘用户3’])
物品A与其他物品的皮尔逊相关系数
A = df[‘物品A’]
corr_A = df.corrwith(A) # 等同于corr_A = df.corrwith(A,axis=0)
皮尔逊系数表,获取各物品(列)的皮尔逊相关系数
df.corr()