推荐系统——协同过滤学习

一.基于邻域的算法

说起推荐系统,最经典的协同过滤当然是绕不过去的一部分,算法思想到是很贴近现实生活,比如:当你无聊时想看电影,打开B站面对成千上万的片子却不知道要看哪一部,这时候如果你身边坐着一位和你兴趣相似的老司机,你就可以向他询问他所喜欢的片子,因为你们兴趣相似,所以很大可能上你也会喜欢。再比如,你又闲的无聊想看电影,却不知道看啥好,但是你想起来你之前看的一步片子很不错,那么和这个片子相似的片子你也有很大可能会喜欢上。以上两个例子就说明了协同过滤的思想,基于邻域的算法分成两大类:基于用户的协同过滤算法和基于物品的协同过滤算法。

1.基于用户的协同过滤算法学习与实现

数据

先亮出数据才好说话嘛,数据下载地址 http://grouplens.org/datasets/movielens/,让我们先看一看数据形式:

1::1193::5::978300760
1::661::3::978302109
1::914::3::978301968
1::3408::4::978300275

看一下README文档就知道数据格式是这样给出的

UserID::MovieID::Rating::Timestamp

算法思路

好的,看完了上面的数据,我们大概知道了我们手里到底有啥了,我们有一些用户对一些电影的评分和评分时间,那么现在我们要做的就是给其中一个用户推荐几部电影,那么我们怎么做呢?思路就像上面提到的,我们去寻找和我们兴趣相似的“老司机们”注意我这里是用了们,应为我们找到的类似用户应该是一群,然后获取这些“老司机们”的喜爱的电影,综合起来推荐给我们这位用户。

算法

说完了算法大致的思路,那么我们就该真刀真枪的描述一下我们的算法是怎样实现上面的思路的了。我们采用逆向的方法说明思路,我们希望通过用户u给他未评过分的电影i来打分预测来实现电影的推荐,之后我们从推荐评分高的电影中取k个推荐给用户u,那么我们怎样实现这个打分预测呢,看下面这个公式:


p(u,i)表示这个打分预测,S(u,k)表示和u用户相似的前k个用户,N(i)表示曾给i电影评过分的用户,Wuv表示用户u和用户v之间的相似度,rvi表示用户v对电影i的评分,嗯,是不是看起来很合理,并不难理解对吧?

接下来问题又来了,我们怎么计算Wuv呢?这里我们定义Wuv用户相似度为两个用户的余弦相似度:

这里的N(u)表示的是u用户所评过分的电影,N(v)表示v用户所评过分的电影,这样我们就可以计算出Wuv了,然后利用相似度进行排序之后我们的S(u,k)也就有了,是不是也很容易理解呢?

代码实现

终于到了代码实现的部分,想想还有点小激动呢,但是完全不知道怎么去实现啊于是参考了这篇Blog写的相当不错推荐阅读 点击打开链接,我们采用python来实现,首先我们要读取数据,我们暂时就用到Ratings中的数据
再使用数据之前我们可以先将数据集分成train和test数据代码如下:
def SplitData (data,M,k,seed):
    test=[]
    train=[]
    random.seed(seed)
    for user,item in data:
        if random.randint(0,M)==k:
            test.append([user,item])
        else:
            tarin.append([user,item])
    return train,test


1.读取数据
>>> import pandas as pd
>>> from pandas import Series,DataFrame
>>> rnames = ['user_id','movie_id','rating','timestamp']
>>> ratings = pd.read_table(r'/Users/zhangjiatao/Documents/STUDY/项目学习/《推荐系统》/数据/ml-1m/ratings.dat',sep='::',header=None,names=rnames)
这样我们就把数据读入我们的我们的ratings中了,我们输入
>>> ratings[:3]

查看前三行

可以看到数据已经被读入了,然后我们要将这种形式的数据转换成我们的评分矩阵我们再输入命令
>>> data = ratings.pivot(index='user_id',columns='movie_id',values='rating')
>>> data[:5]

用data来储存我们的评分矩阵并现实前五行

movie_id  1     2     3     4     5     6     7     8     9     10    ...   \

user_id                                                               ...    

1          5.0   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  ...    

2          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  ...    

3          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  ...    

4          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  ...    

5          NaN   NaN   NaN   NaN   NaN   2.0   NaN   NaN   NaN   NaN  ...    


movie_id  3943  3944  3945  3946  3947  3948  3949  3950  3951  3952  

user_id                                                               

1          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  

2          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  

3          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  

4          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  

5          NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN  


[5 rows x 3706 columns]


可以看到我们的评分矩阵是十分稀疏的,之后我们计算用户之间的俩俩之间的相似度
def UserSimilarity(train):
    W=dict()
    for u in train.keys():
        for v in train.keys():
            if u == v:
                continue
            W[u][v]=len(train[u]&train[v])
            W[u][v]=math.sqrt(len(train[u]*train[v]*1.0))
    return W

我们的到了一个相似矩阵W,让后我们利用上面的算法计算推荐的电影即可
def Recommend(user,train,W):
    rank=dict()
    interacted_intems=train[user]
    for u,wuv in sorted (W[u].items,key=itemgetter(1),\revers=True) [0:K] :
        for i, rvi in train[v].items():
            continue
        rank[i]+=wuv*rvi
    return rank



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值