svd与svd++联系与区别

最近一直在做基于SVD推荐方面的工作,主要使用的是Mahout提供的cf.taste.impl.recommender.svd包下的推荐器,这里有一段参考代码,使用的推荐器是SVDRecommender,如下所示:

public class SVDRecommenderEx {
	private static String input = "/Users/harikrishna_gurram/customer.csv";
	private static DataModel model = null;
	private static SVDRecommender recommender = null;
	private static ALSWRFactorizer fatorizer = null;

	private static String[] books = { "Meet Big Brother", "Explore the Universe", "Memoir as metafiction",
			"A child-soldier's story", "Wicked good fun", "The 60s kids classic", "A short-form master",
			"Go down the rabbit hole", "Unseated a president", "An Irish-American Memoir" };

	private static String[] userNames = { "Hari Krishna Gurram", "Gopi Battu", "Rama Krishna Gurram", "Sudheer Ganji",
			"Kiran Darsi", "Joel Chelli", "Sankalp Dubey", "Sunil Kumar", "Janaki Sriram", "Phalgun Garimella",
			"Reshmi george", "Sailaja Navakotla", "Aravind Phaneendra", "Keerthi Shetty", "Sujatha",
			"Vadiraj Kulakarni", "Arpan", "Suprabath Bisoi", "Sravani", "Gireesh Amara" };

	public static void main(String args[]) throws IOException, TasteException {
		model = new FileDataModel(new File(input));
		fatorizer = new ALSWRFactorizer(model, 5, 0.05, 10);
		recommender = new SVDRecommender(model, fatorizer);
		List<RecommendedItem> recommendations = recommender.recommend(1, 5);
		System.out.println("Recommendations for customer " + userNames[0] + " are:");
		System.out.println("*************************************************");

		System.out.println("BookId\title\t\testimated preference");
		for (RecommendedItem recommendation : recommendations) {
			int bookId = (int) recommendation.getItemID();
			float estimatedPref = recommender.estimatePreference(1, bookId);
			System.out.println(bookId + " " + books[bookId - 1] + "\t" + estimatedPref);
		}
		System.out.println("*************************************************");
	}
}

在上一段代码中,用到的矩阵分解器Factorizer是基于最小二乘分解的分解器ALSWRFactorizer,还有一种常用的分解器SVDPlusPlusFactorizer。

其实,基于潜在(隐藏)因子的推荐,即基于隐语义模型的推荐,通常采用SVD或改进的SVD(SVD++)方式。

奇异值分解(SVD)

考虑协同过滤中最为常见的场景:用户给电影评分的,我们需要一个数学模型来模拟这个评分场景,比如对电影做评分预测。

将评分矩阵U看作是两个矩阵的乘积:

其中,可以看作是user x对电影的隐藏特征y的喜好程度,而可以看作是特征y在电影z中的体现程度。那么上述模型的评分预测公式为:

其中,q 和 p 分别对应了电影和用户在各个隐藏特质上的特征向量。

以上的模型中,用户和电影都体现得无差别,例如某些用户非常挑剔,总是给予很低的评分;或是某部电影拍得奇烂,恶评如潮。为了模拟以上的情况,需要引入 baseline predictor.


其中 μ 为所有评分基准,bi 为电影 i 的评分均值相对μ的偏移,bu 类似。注意,这些都是参数,需要通过训练得到具体数值,但可以用相应的均值作为初始化时的估计。

模型参数bi,bu,qi,pu通过最优化下面这个目标函数获得:

其中,前一项是一种最小二乘损失函数的表达形式,第二项和第三项分别是正则化项。可以用梯度下降方法或迭代的最小二乘算法求解。在迭代最小二乘算法中,首先固定pu优化qi,然后固定qi优化pu,然后交替更新。梯度下降方法中参数的更新式子如下(为了简便,把目标函数中的μ+bi+bu+qipu整体替换为r^ui):

其中α是学习速率,也是更新步长。

SVD++

某个用户对某个电影进行了评分,那么说明他看过这部电影,那么这样的行为事实上蕴含了一定的信息,因此我们可以这样来理解问题:评分的行为从侧面反映了用户的喜好,可以将这样的反映通过隐式参数的形式体现在模型中,从而得到一个更为精细的模型,便是 SVD++.

其中 I(u) 为该用户所评价过的所有电影的集合,yj为隐藏的“评价了电影 j”反映出的个人喜好偏置。收缩因子取集合大小的根号是一个经验公式,并没有理论依据。

模型参数bi,bu,qi,pu,yj通过最优化下面这个目标函数获得:

SVD方法类似,可以通过梯度下降算法进行求解。

阅读更多

没有更多推荐了,返回首页