基于用户的协同过滤算法

协同过滤算法在推荐系统领域占有及其重要的地位,协同过滤算法的出现甚至标志了智能推荐的出现。协同过滤算法大体上分为两类:基于用户的协同过滤和基于物品的协同过滤。近几年出现的对协同过滤算法的改进,大部分都是基于这两种算法。笔者最近学习了基于用户的协同过滤算法,所以在此做一个简单的总结,有不对之处请各位指出。

基于用户的协同过滤算法的主要思想是基于用户A可能会喜欢与用户A特征相似的用户B所喜欢的物品。例如,如果一个女生想买一双鞋子,她很有可能去问她的朋友,让她的朋友来给她作一些推荐。在这里这个女生和她的朋友可以看成是相似的用户。协同过滤算法就是基于这样的一种思想。顺理成章,基于用户的协同过滤算法需要解决如下两个问题:

1)、有哪些用户和用户A相似。

2)、这些与A相似的用户喜欢哪些产品,然后将这些产品中用户A没有听说过的产品推荐给用户A

那么,如何计算两个用户的相似度,对于一个电子商务网站、电影网站或者音乐网站来说,通过分析日志文件可以获取用户的行为,通过注册信息可以获取用户的一些基本信息,比如邮箱、性别、年龄等,但这些注册信息是不够完整的,有些网站可能连这些基本的注册信息都没有。但用户在网站上有哪些行为是可以通过日志文件获取的,所以计算用户之间的相似性可以转化为计算用户行为的相似性。在这里我们采用两个用户购买了哪些产品或者是听了哪些音乐等这些行为来衡量。假设用户U曾将购买的产品的集合为A,V曾经购买的产品集合为B。衡量二者的相似性可以用Jaccard公式来计算:

或者使用余弦相似度来计算:

公式中A和B都是一个集合,|A|代表了集合A元素 的个数,同样|B|代表了集合B的个数。所以代表了用户U和用户V购买的

相同物品的个数。例如,设A={a, b, c, d} ,B = {a, b, e, f} 则:

|AB| = |{a, b, c, d}{a, b, e,f}| = |{a, b}| = 2

|AB| = |{a, b, c, d}{a, b, e, f}| = |{a, b, c, d, e, f}| = 6

由此便可以根据用户U和用户V所够买的产品而计算出二者的相似性。

假设有三个用户U1, U2, U3,U4 。他们分别对物品集合P(U1), P(U2), P(U3),P(U4)产生正反馈,所谓正反馈指的是用户购买

了这些产品。其中P(U1)={a, b, c, d,e} , P(U2)={c, d, e, f), P(U3) = (a, f, g, z), P(U4)={h, i, a, z, m}, 那么如何计算他们两两之

间的相似度。下面用java程序模拟整个过程,这里使用余弦相似度。

package CollaborateFilter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class CFuser {
	public static void main(String[] args){
		String[] products1 = {"a", "b", "c", "d","e"};
		User U1 = new User("U1", products1);
		String[] products2 = {"c","d","e","f"};
		User U2 = new User("U2", products2);
		String[] products3 = {"a","f","g","z"};
		User U3 = new User("U3", products3);
		String[] products4 = {"h","i","a","z","m"};
		//新建一个set用来存储用户信息
		User U4 = new User("U4", products2);
		List<User> users = new ArrayList<User>();
		users.add(U1);
		users.add(U2);
		users.add(U3);
		users.add(U4);
		List<User> usersList=  CalSimilarity.CalSimilaritys(users);
		for(int i = 0; i < usersList.size(); i++){
			System.out.println(usersList.get(i).getUsername());
			Map<String, Double> similarity = usersList.get(i).getSimilarMap();
			for (Entry<String, Double> entry : similarity.entrySet()) {
				   System.out.print("  key=" + entry.getKey() + " similarity= " + entry.getValue());
			}
			System.out.println();
		}
	}
}
/**
 * 用户类别,包括用户名,和所购买的产品
 * @author zhouqi
 *
 */
class User{
	//用户姓名
	private String username;
	//用户所购买的产品
	private String[] products;
	//相似度
	private Map<String, Double> SimilarMap; 
	public User(){ }//空构造方法
	public  User(String username, String[] products){
		this.username = username;
		this.products = products;
	}//构造方法
	public Map<String, Double> getSimilarMap() {
		return SimilarMap;
	}
	public User setSimilarMap(Map<String, Double> similarMap) {
		SimilarMap = similarMap;
		return this;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String[] getProducts() {
		return products;
	}
	public void setProducts(String[] products) {
		this.products = products;
	}
	
}
//使用余弦相似度计算两个用户之间的相似度。
class CalSimilarity{
	public static double Cal2Similarity(User user1, User user2){
		String[] products1 = user1.getProducts();
		String[] products2 = user2. getProducts();
		double count = 0.0;
		for(int i = 0; i < products1.length; i++){
			for(int j = 0 ; j < products2.length; j++){
				if(products1[i] == products2[j]) {
					count++; 
				}
			}
		}
		double similarity = count/(products1.length * products2.length);
		return similarity;
	}
	//计算很多用户之间的相似度。
	public static List<User> CalSimilaritys(List<User> users){
		List<User> usersList = new ArrayList<User>();
		for(int i = 0; i < users.size(); i ++){
			Map<String, Double> smap = new HashMap<String, Double>();
			//System.out.println(users.get(i).getUsername());
			for(int j = 0; j < users.size(); j ++){
				if(i == j) continue;
				//计算两个用户之间的相似度
				double similarity = CalSimilarity.Cal2Similarity(users.get(i), users.get(j));
				smap.put(users.get(j).getUsername(), similarity);
			}
			usersList.add(users.get(i).setSimilarMap(smap));
		}
		return usersList;
	}
}



用户协同过滤算法是一种常见的推荐算法,它通过分析用户之间的相似性,来给用户推荐相似用户喜欢的物品。具体实现方式是,首先根据用户之间的历史行为数据(如购买记录、评分记录等),计算用户之间的相似度,然后利用相似用户的历史行为数据,推荐给目标用户他们喜欢的物品。 下面是一个简单的基于用户协同过滤算法的Python代码: ```python import numpy as np # 历史行为数据 data = np.array([ [5, 3, 0, 1, 4], [1, 0, 0, 5, 1], [4, 3, 0, 0, 5], [0, 1, 5, 4, 4], [5, 4, 4, 0, 0] ]) # 计算用户相似度 def similarity(user1, user2): return np.dot(user1, user2) / (np.linalg.norm(user1) * np.linalg.norm(user2)) # 给定目标用户id,计算推荐物品列表 def recommend(target_id): target_user = data[target_id] similarities = [] for i in range(len(data)): if i != target_id: sim = similarity(target_user, data[i]) similarities.append((i, sim)) similarities.sort(key=lambda x: x, reverse=True) top_similarities = similarities[:2] recommended_items = [] for item_id in range(len(target_user)): if target_user[item_id] == 0: score = 0 count = 0 for sim_id, sim_score in top_similarities: if data[sim_id][item_id] != 0: score += sim_score * data[sim_id][item_id] count += sim_score if count > 0: recommended_items.append((item_id, score/count)) recommended_items.sort(key=lambda x: x, reverse=True) return recommended_items # 测试代码 print(recommend(0)) # 给id为0的用户推荐物品 ``` 代码中的`data`是历史行为数据矩阵,其中每一行表示一个用户对各个物品的行为数据,0表示未有行为。`similarity`函数用于计算两个用户之间的相似度,这里采用的是余弦相似度计算方法。`recommend`函数则是用于给定目标用户id,计算出推荐的物品列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值