推荐系统
面对海量的数据信息,从中快速推荐出符合用户特点、是用户感兴趣的物品
推荐算法分类
1 基于人口统计学的推荐
2 基于内容的推荐
3 基于协同过滤的推荐
4 混合推荐
基于人口统计学的推荐
基于内容的推荐
基于协同过滤的推荐(是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息)
1 基于近邻的协同过滤(基于用户、基于物品)
2 基于模型的协同过滤(奇异值分解(SVD)、潜在语义分析(LSA)、支撑向量机(SVM))
-
1 基于用户的协同过滤(基于用户、基于物品)
-
2 基于物品的协同过滤
Apache Mahout是基于Lambda架构,基于计算引擎(MapReduce/Spark/Flink?H2O)开发的机器学习和数据挖掘的分布式框架, 分布式线性代数框架,旨在快速实现自己的算法,支持多个分布式后端。
Mahout实现了常用的数据挖掘算法,包括聚类算法、回归算法、余玄相似性、分类算法、推荐过滤、频繁子项挖掘
- 个性化推荐系统实现步骤
1 获取用户画像
2 构建数据模型
3 将原始数据映射到Mahout定义的Data Model中
DataModel(基于内存)
GenericBooleanPrefDataModel(基于内存)
FileDataModel(基于文件)
JDBCDataModel(基于数据库)
4 调优推荐组件(相似度组件、临界关系组件、推荐算法等)
5 推荐模型评估
- 代码实现
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>${mahout.version}</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-integration</artifactId>
<version>${mahout.version}</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-math</artifactId>
<version>${mahout.version}</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-examples</artifactId>
<version>${mahout.version}</version>
</dependency>
1 用户相似度模型
/**
* LogLikelihoodSimilarity 对数似然相似度
* TanimotoCoefficientSimilarity 谷本系数相似度
* CityBlockSimilarity 曼哈顿距离相似度
* SpearmanCorrelationSimilarity Spearman秩相关系数
* UncenteredCosineSimilarity 余弦相似度
* EuclideanDistanceSimilarity 欧几里得距离相似度
* PearsonCorrelationSimilarity 皮尔逊相关系数相似度
* */
UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(dataModel);
2 构建近邻对象 threshold 是相似阈值 这个数值越高 推荐精准越高 但是推荐的数据也越少 最高为 给用户设置的喜好值最高值
/**
* ThresholdUserNeighborhood 对每个用户基于一定的限制,相似度限制内的所有用户为邻居
* NearestNUserNeighborhood 对每个用户取固定数量 N 的最近邻居
* */
float threshold = 0f;
UserNeighborhood neighborhood = new ThresholdUserNeighborhood(threshold, userSimilarity, dataModel);
3 构建推荐器
/**
* GenericUserBasedRecommender 基于用户相似度
* GenericItemBasedRecommender 基于item相似度
* SlopeOneRecommender 基于SlopeOne算法
* SVDRecommender 基于支持向量机
* KnnItemBasedRecommender 基于相似用户的实现
* TreeClusteringRecommender 基于树形聚类的推荐算法
* */
UserBasedRecommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, userSimilarity);
// 给用户4推荐10个相似数据
List<RecommendedItem> recommend = recommender.recommend(4, 10);
for (RecommendedItem recommendedItem : recommend) {
System.out.println(recommendedItem);
}
4 结果输出
try(PrintWriter writer = new PrintWriter(resultFile)){
for (int userID=1; userID <= model.getNumUsers(); userID++){
List<RecommendedItem> recommendedItems = recommender.recommend(userID, 2);
String line = userID+" : ";
for (RecommendedItem recommendedItem: recommendedItems){
line += recommendedItem.getItemID()+":"+recommendedItem.getValue()+",";
}
if (line.endsWith(",")){
line = line.substring(0, line.length()-1);
}
writer.write(line);
writer.write('\n');
}
} catch (IOException ioe){
resultFile.delete();
throw ioe;
}
5 推荐模型评估
//参数0.9表示每个用户训练集为90%,1.0代表所有的用户来参与评估
// 0。75 预测评分为5的话,实际为 5 - 0.75
// 结果值越小与实际值越相似
double score = evaluator.evaluate(recommenderBuilder, null, dataModel, 0.9, 1.0);
System.out.println("均方差:"+score);
double rmse = recommenderEvaluator.evaluate(recommenderBuilder, null, dataModel, 0.9, 1.0);
System.out.println("均方根误差:"+rmse);
相似度算法分析
欧式距离
欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离
场景:适合于特征数据量较小的情况
欧式距离相似度EuclideanDistanceSimilarity
原理:利用欧式距离d定义的相似度s,s=1 / (1+d)。
范围:[0,1],值越大,说明d越小,也就是距离越近,则相似度越大。
曼哈顿距离
同欧式距离相似,都是用于多维数据空间距离的测度。
两个点在标准坐标系上的绝对轴距总和
应用场景:主要应用场景,如棋盘、城市里两个点之间的距离等
曼哈顿距离CityBlockSimilarity
范围:[0,1],同欧式距离一致,值越小,说明距离值越大,相似度越大。
说明:比欧式距离计算量少,性能相对高。
余弦相似度
多维空间两点与所设定的点形成夹角的余弦值。
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。
应用场景:用余弦值衡量文本相似度,常用于文本识别,比如新闻的挖掘
举例:
文本1中词语a,b分别出现100,50次,向量表示为(100,50)
文本2中词语a,b分别出现50,25次,向量表示为(50,25)
文本3中词语a,b分别出现10,0次,向量表示为(10,0)
文本4中词语a,b分别出现2,0次,向量表示为(2,0)
可以得知,1,2点向量平行(词频比例相同),
3,4点向量平行,那么是不是可以判断1,2文本更相似,3,4文本更相似呢?
余弦相似度PearsonCorrelationSimilarityUncenteredCosineSimilarity
范围:[-1,1],值越大,说明夹角越大,两点相距就越远,相似度就越小。
距离与余弦相似度区别:余弦相似度衡量的是维度间取值方向的一致性,注重维度之间的差异,不注重数值上的差异,而欧氏度量的正是数值上的差异性。
案例分析:如某T恤从100块降到了50块(A(100,50)),某西装从1000块降到了500块(B(1000,500)),那么T恤和西装都是降价了50%,两者的价格变动趋势一致,可以用余弦相似度衡量,即两者有很高的变化趋势相似度,但是从商品价格本身的角度来说,两者相差了好几百块的差距,欧氏距离较大,即两者有较低的价格相似度。
Pearson相关系数
是用来衡量两个数据集合是否在一条线上面,它用来衡量定距变量间的线性关系。
这个相对于欧几里德距离要复杂一点。它的一个好处是,当两者对一件物品的评分差距较大时,并不一定两者不想近,如果他两对于其他的物品评价也有差距,但是都是正相关,那两者的相似度还是相近的。这个比欧几里德距离准确。
场景:适合于特征数据量较大的情况(效果较好)
适用于A的评价普遍高于B的评价
它是存在一条拟合线的,这条线尽量靠近所有点,结果也是求所有点和这条线的拟合程度。皮尔逊相关度评价算法首先会找出两位评论者都曾评论过的物品,然后计算两者的评分总和与平方和,并求得评分的乘积之和。最后,算法利用这些计算结果计算出皮尔逊相关度。
公式定义为: 两个连续变量(X,Y)的pearson相关性系数(Px,y)等于它们之间的协方差cov(X,Y)除以它们各自标准差的乘积(σX,σY)。系数的取值总是在-1.0到1.0之间,接近0的变量被成为无相关性,接近1或者-1被称为具有强相关性。
皮尔森相关度 PearsonCorrelationSimilarity
范围:[-1,1],绝对值越大,说明相关性越强,负相关对于推荐的意义小。
Tanimoto 固本系数
这是一个计算交集和并集的比率的方法
度量两个集合之间的相似程度的方法。
应用场景:比较文本相似度,用于文本查重与去重;计算对象间距离,用于数据聚类等
A=[1,2,3,4] 列表长度:4
B=[1,2,7] 列表长度:3
C = A & B = [1,2] 列表长度:2
T = Nc / ( Na + Nb -Nc) = len(c) / ( len(a) + len(b) - len(c)) = 2 / (4+3-2) = 0.4
可以用户计算用户之间的相似程度,这种方法适用于:数据表示为0、1这种二值化,而非有数量大小的情况
对数似然相似度:LogLikelihoodSimilarity
原理:重叠的个数,不重叠的个数,都没有的个数
说明:处理无打分的偏好数据,比Tanimoto系数的计算方法更为智能。
对于事件A和事件B,我们考虑两个事件发生的次数,具有如下矩阵