推荐系统中的itembased和userbased协同过滤算法在计算评分时需要用到相似度计算。
记录几个常见的相似度计算代码
引用自【机器学习实战】
import numpy as np
from numpy import linalg as la
#欧式距离1
import math
#假设p1,p2维度相同
def EuclidSimilarity(p1,p2):
sum_of_squares = sum([pow(p1[i] - p2[i] , 2)
for i in range(0,len(p1))])
##未归一化
return math.sqrt(sum_of_squares)
##归一化
return 1/(1+math.sqrt(sum_of_squares))
#欧式距离2
def euclidSimilar(inA,inB):
return 1.0/(1.0+la.norm(inA-inB))
#皮尔逊相关系数
def pearsonSimilar(inA,inB):
if len(inA)<3:
return 1.0
#把值域[-1,1]缩放到[0,1]
return 0.5+0.5*np.corrcoef(inA,inB,rowvar=0)[0][1]
#余弦相似度
def cosSimilar(inA,inB):
inA=np.mat(inA)
inB=np.mat(inB)
num=float(inA*inB.T)
denom=la.norm(inA)*la.norm(inB)
return 0.5+0.5*(num/denom)
欧氏距离公式:
欧氏距离公式
在日常使用中,一般习惯于将相似度与1类比,相似度在数值上反映为0<=Similarity(X,y)<=1,越接近1,相似度越高;那么我们在使用欧几里得距离时,可以通过 1/(1+Distance(X,Y))归一化。
皮尔逊相关度计算 PearsonSimilarity:
协方差代表了两个变量之间的是否同时偏离均值。
cov(X, Y) = E(X-EX)(Y-EY)= E(XY)-E(X)E(Y)
当 cov(X, Y)>0时,表明 X与Y 正相关;
当 cov(X, Y)<0时,表明X与Y负相关;
当 cov(X, Y)=0时,表明X与Y不相关。
计算:
Xi 1.1 1.9 3
Yi 5.0 10.4 14.6
E(X) = (1.1+1.9+3)/3=2
E(Y) = (5.0+10.4+14.6)/3=10
E(XY)=(1.1×5.0+1.9×10.4+3×14.6)/3=23.02
Cov(X,Y)=E(XY)-E(X)E(Y)=23.02-2×10=3.02 协方差计算
标准差计算:
方差:D(X)=E(X2)-E2(X)=(1.12+1.92+32)/3 - 4=4.60-4=0.6 开根号的标准差 σx=0.77
方差:D(Y)=E(Y2)-E2(Y)=(52+10.42+14.62)/3-100=15.44 σy=3.93
X,Y的相关系数:
协方差/(标准差X*标准差Y)
r(X,Y)=Cov(X,Y)/(σxσy)=3.02/(0.77×3.93) = 0.9979
实际应用中大部分相似度计算还是调用sklearn,scipy中的包,一方面是速度原因,另一方面是自己写的相似度度量通常是两两比对,包中的度量是返回一个相似度矩阵,可以同时快速计算多个特征的相似度,下面列举一些相似度以及一些例子:
##余弦相似度,返回一个相似度矩阵,即对角线为1的矩阵
## sklearn.metrics.pairwise中定义:相似度 = 1 - 距离
#例如:余弦相似度 = 1 - 余弦距离
from sklearn.metrics.pairwise import pairwise_distances
row_similarity =1 - pairwise_distances(R, metric='cosine')
column_similarity =1 - pairwise_distances(R.T, metric='cosine')
##欧氏距离
from sklearn.metrics.pairwise import pairwise_distances
row_similarity = pairwise_distances(R, metric='euclidean')
column_similarity = pairwise_distances(R.T, metric='euclidean')
##通过修改参数metric来改变度量方式:
##metric =[ 'euclidean', 'l2', 'l1', 'manhattan', 'cityblock', 'braycurtis', 'canberra', 'chebyshev', 'correlation', 'cosine', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule', 'wminkowski']
##皮尔逊相关系数
#又叫皮尔森卡方检验,这是一种最常用的卡方检验方法,它有两个用途:
#1是计算某个变量对某种分布的拟合程度,
#2是根据两个观测变量的[Contingency table]来计算这两个变量是否是独立的。
#主要有三个步骤:
#第一步用方差和的方式来计算观测频率和理论频率之间卡方值;
#第二步算出卡方检验的自由度(行数-1乘以列数-1);
#第三步比较卡方值和对应自由度的卡方分布,判断显著性
from sklearn.metrics.pairwise import pairwise_distances
#行和行之间的相关系数
row_similarity =1 - pairwise_distances(R, metric='correlation')
#列和列之间的相关系数
column_similarity = 1 - pairwise_distances(R.T, metric='correlation')
#或者:
from scipy.stats import pearsonr
a = pearsonr(x, y)
#scipy中的pearsonr函数返回皮尔逊相关系数和p-value,相关性越强,p-value越低
#p-value只是用来说明是否有相关性,p-value<0.05,就存在相关性,并不是越小越好
##或者:
#列和列之间的相关系数
df.corr()
#行和行之间的相关系数
df.T.corr()
##用sklearn中的f_regression可以批量计算
#批量计算F_score,p_value:
#计算df中第一列(df[0])和整个df每列的F_score,p_value
F_score,p_value = f_regression(df, df[0])
p-value:
上面的皮尔逊相关度中用到了p-value 和F score, 下面简单介绍p-value。
p-value只是用来说明是否有相关性,p-value<0.05,就存在相关性,并不是越小越好,如果p-value<0.05时第一个值绝对值较大,这两个返回值一起表明有较强相关性。p值不是完全可靠的。
p-value就是为了验证假设和实际之间一致性的统计学意义的值,即假设检验。有些地方叫右尾概率,根据卡方值和自由度可以算出一个固定的p-value。
sklearn f_regression文档:
sklearn.feature_selection.f_regression(X, y, center=True)
一元线性回归测试:
线性模型用于检验每一个回归的个体效应。这是一个在特征选择过程中使用的评分函数,而不是独立的功能选择程序。
这是在两个步骤中完成的:
每个回归和目标之间的关联计算,即,((X[:, i] - mean(X[:, i])) * (y - mean_y)) / (std(X[:, i]) * std(y)).
它被转换成F score,再转化成p-value。
Parameters:
X : {array-like, sparse matrix} shape = (n_samples, n_features)
将按顺序进行测试的一组回归器。
y : array of shape(n_samples).
一个array维度为样本数n,需要计算的数据矩阵
center : True, bool,
如果选择True,X和y将被中心化。
(矩阵中心化是使用数据减去数据的均值,其实就是一个平移的过程,平移后所有数据的中心是(0,0),将所有维度上的数据减去其均值后,数据变成均值为0的较为稳定的数据(必要时还可进行标准化),此时进行计算,则不同维度之间的数据相差不会太大,可以有效降低误差,提高准确率。)
Returns:
F : array, shape=(n_features,)
特征的F score
pval : array, shape=(n_features,)
F-scores 的p-values
网友评论