'''
基于物品的协同推荐 矩阵数据 说明:
1.修正的余弦相似度是一种基于模型的协同过滤算法。我们前面提过,这种算法的优势之
一是扩展性好,对于大数据量而言,运算速度快、占用内存少。 2.用户的评价标准是不同的,比如喜欢一个歌手时有些人会打4分,有些打5分;不喜欢时
有人会打3分,有些则会只给1分。修正的余弦相似度计算时会将用户对物品的评分减去
用户所有评分的均值,从而解决这个问题。 如何预测用户对给定物品的打分?
一、基于用户协同
方法1:用户之间的距离/相似度(K近邻算法)
二、基于物品协同
方法1:物品之间的相似度(修正的余弦相似度)
方法2:物品之间的差异值(加权Slope One算法) 由于使用的是用户产生的各种数据,因此又称为社会化过滤算法。 协同过滤会遇到的种种问题,包括数据的稀疏性和算法的可扩展性。此外,协同过滤算法倾向于推荐那些已经很流行的物品。 这类推荐系统会让流行的物品更为流行,冷门的物品更无人问津。
-- Daniel Fleder & Kartik Hosanagar 2009 《 推荐系统对商品分类的影响》
''' import pandas as pd
from io import StringIO #数据类型一:条目(用户、商品、打分)(避免巨型稀疏矩阵)
csv_txt = '''"David","Imagine Dragons",3
"David","Daft Punk",5
"David","Lorde",4
"David","Fall Out Boy",1
"Matt","Imagine Dragons",3
"Matt","Daft Punk",4
"Matt","Lorde",4
"Matt","Fall Out Boy",1
"Ben","Kacey Musgraves",4
"Ben","Imagine Dragons",3
"Ben","Lorde",3
"Ben","Fall Out Boy",1
"Chris","Kacey Musgraves",4
"Chris","Imagine Dragons",4
"Chris","Daft Punk",4
"Chris","Lorde",3
"Chris","Fall Out Boy",1
"Tori","Kacey Musgraves",5
"Tori","Imagine Dragons",4
"Tori","Daft Punk",5
"Tori","Fall Out Boy",3''' #数据类型一:条目(用户、商品、打分)(避免巨型稀疏矩阵)
#根据《data minning guide》第85页的users2数据
csv_txt2 = '''"Amy","Taylor Swift",4
"Amy","PSY",3
"Amy","Whitney Houston",4
"Ben","Taylor Swift",5
"Ben","PSY",2
"Clara","PSY",3.5
"Clara","Whitney Houston",4
"Daisy","Taylor Swift",5
"Daisy","Whitney Houston",3''' df = None #方式一:加载csv数据
def load_csv_txt():
global df
#df = pd.read_csv(StringIO(csv_txt2), header=None, names=['user','goods','rate'])
df = pd.read_csv("BX-Book-Ratings.csv", header=None, names=['user','goods','rate'], sep=';') print('测试:读取数据')
load_csv_txt()
#load_json_txt() #=======================================
# 注意:不需要build_xy
#======================================= # 计算两个物品相似度
def computeSimilarity(goods1, goods2):
'''根据《data minning guide》第71页的公式s(i,j)'''
df1 = df.ix[df['goods'].isin([goods1]), ['user','rate']]
df2 = df.ix[df['goods'].isin([goods2]), ['user','rate']] df3 = pd.merge(df1, df2, on='user', how='inner') #只保留两种商品都被同一用户评过分的商品的评分 # 注意:先构造了一个只有index=df3['user']的pd.Series,目的是方便下一步的减
mean = pd.Series(df3['user'].tolist(), index=df3['user']).apply(lambda x:df.ix[df['user']==x, 'rate'].mean()) # 每行的用户评分都减去了该用户的平均评分
df3.index = df3['user']
df3['rate_x'] = df3['rate_x'] - mean
df3['rate_y'] = df3['rate_y'] - mean # 返回修正的余弦相似度
return sum(df3['rate_x'] * df3['rate_y']) / (sum(df3['rate_x']**2) * sum(df3['rate_y']**2))**0.5 # merge之后默认的列名:rate_x,rate_y # csv_txt
#print('\n测试:计算Kacey Musgraves与Imagine Dragons的相似度')
#print(computeSimilarity("Kacey Musgraves","Imagine Dragons")) #为了让公式的计算效果更佳,对物品的评价分值最好介于-1和1之间
def rate2newrate(rate):
'''根据《data minning guide》第76页的公式NR(u,N)'''
ma, mi = df['rate'].max(), df['rate'].min()
return (2*(rate - mi) - (ma - mi))/(ma - mi) #已知rate2newrate求newrate2rate
def newrate2rate(new_rate):
'''根据《data minning guide》第76页的公式R(u,N)'''
ma, mi = df['rate'].max(), df['rate'].min()
return (0.5 * (new_rate + 1) * (ma - mi)) + mi #print('\n测试:计算3的new_rate值')
#print(rate2newrate(3)) #print('\n测试:计算0.5的rate值')
#print(newrate2rate(0.5)) # 预测给定用户对物品的可能评分(对评分进行了修正/还原)
def p2(user, goods):
'''根据《data minning guide》第75页的公式p(u,i)'''
#assert pd.isnull(df.ix[df['user']==user & df['goods']==goods, 'rate']) # 必须用户对给定物品尚未评分 #用户对其它所有已打分物品的打分数据
df2 = df.ix[df['user']==user, ['goods','rate']]
s1 = pd.Series(df2['rate'].tolist(), index=df2['goods'])
s1 = s1.apply(lambda x:rate2newrate(x)) #修正
s2 = s1.index.to_series().apply(lambda x:computeSimilarity(x, goods)) #打分物品分别与给定物品的相似度 return newrate2rate(sum(s1 * s2) / sum(abs(s2)))#还原 # csv_txt
#print('\n测试:预测David对Kacey Musgraves的打分(修正)')
#print(p2("David","Kacey Musgraves")) #==================================
# 下面是Slope One算法
#
# 两个步骤:
# 1. 计算差值
# 2. 预测用户对尚未评分物品的评分
#================================== # 1.计算两物品之间的差异
def dev(goods1, goods2):
'''根据《data minning guide》第80页的公式dev(i,j)'''
#s = (df[goods1] - df[goods2]).dropna() df1 = df.ix[df['goods'].isin([goods1]), ['user','rate']]
df2 = df.ix[df['goods'].isin([goods2]), ['user','rate']]
print('df1\n', df1)
print('df2\n', df2) df3 = pd.merge(df1, df2, on='user', how='inner') #只保留两个物品都有评分的用户的评分
print(df3)
print(df3.shape[0]) d = sum(df3['rate_x'] - df3['rate_y'])/df3.shape[0] # 差异值
return d, df3.shape[0] #返回差异值,及权值(同时对两个物品打分的人数) # csv_txt
#print('\n测试:计算Kacey Musgraves与Imagine Dragons的分数差异')
#print(dev("Kacey Musgraves","Imagine Dragons")) #计算所有两两物品之间的评分差异,得到方阵pd.DataFrame(行对列)
def get_dev_table():
'''根据《data minning guide》第87页的表'''
#goods_names = df.columns.tolist()
goods_names = df['goods'].unique().tolist()
df2 = pd.DataFrame(.0, index=goods_names, columns=goods_names) #零方阵 for i,goods1 in enumerate(goods_names):
for goods2 in goods_names[i+1:]:
d, _ = dev(goods1, goods2) # 注意:只取了物品差异值
df2.ix[goods1, goods2] = d
df2.ix[goods2, goods1] = -d # 对称的位置取反 return df2 #print('\n测试:计算所有两两物品之间的评分差异表')
#print(get_dev_table()) #预测某用户对给定物品的评分
# 加权Slope One算法
def slopeone(user, goods):
'''根据《data minning guide》第82页的公式p(u,j)'''
df1 = df.ix[df['user'].isin([user]), ['goods', 'rate']] s1 = pd.Series(df1['rate'].tolist(), index=df1['goods']) # 用户对已打分物品的打分数据 s2 = s1.index.to_series().apply(lambda x:dev(goods, x)) # 待打分物品与已打分物品的差异值及权值 s3 = s2.apply(lambda x:x[0]) #差异值
s4 = s2.apply(lambda x:x[1]) #权值
#print(s1, s3, s4) return sum((s1 + s3) * s4)/sum(s4) #print('\n测试:加权Slope One算法,预测用户Ben对物品Whitney Houston的评分')
#print(slopeone('Ben', 'Whitney Houston')) # 3.375 print('\n测试:加权Slope One算法,预测用户276744对书本0600570967的评分') #大数据量
print(slopeone(276744, '0600570967'))

【笔记6】用pandas实现条目数据格式的推荐算法 (基于物品的协同)的更多相关文章

  1. 【笔记5】用pandas实现矩阵数据格式的推荐算法 (基于物品的协同)

    ''' 基于物品的协同推荐 矩阵数据 说明: 1.修正的余弦相似度是一种基于模型的协同过滤算法.我们前面提过,这种算法的优势之 一是扩展性好,对于大数据量而言,运算速度快.占用内存少. 2.用户的评价 ...

  2. 【笔记4】用pandas实现条目数据格式的推荐算法 (基于用户的协同)

    ''' 基于用户的协同推荐 条目数据 ''' import pandas as pd from io import StringIO import json #数据类型一:条目(用户.商品.打分)(避 ...

  3. 【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)

    原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式. 我用pandas实现相同的公式只要3行. 特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据. ''' 基于 ...

  4. R语言实现关联规则与推荐算法(学习笔记)

    R语言实现关联规则 笔者前言:以前在网上遇到很多很好的关联规则的案例,最近看到一个更好的,于是便学习一下,写个学习笔记. 1 1 0 0 2 1 1 0 0 3 1 1 0 1 4 0 0 0 0 5 ...

  5. 学习笔记-menusript控件中条目权限设置使用

    在做一个小程序的时候,偶然发现了使用menusript控件做权限设置的方法,仅此标记,以供参考. 首先创建一个实例:testuseright.sln, 在项目文件里创建两个窗体:Form1.cs和us ...

  6. Python笔记 #12# Dictionary & Pandas: Object Creation

    Document of Dictionaries 10 Minutes to pandas tutorialspoint import pandas as pd data = [['Alex',10] ...

  7. Office365学习笔记—Lookup类型加载条目过多解决方案

    1,随着接触的项目越来越多,遇到的各种奇葩的问题也越来越多,不得不说,SharePoint是个好东西,提高了开发效率,简化了很多基础的功能.但是令人头疼的问题是,当你想做个稍微复杂点的功能,就不得不研 ...

  8. Office365学习笔记—列表查询,删除条目,更新条目。

    1,基于Query语句的列表查询. function retrieveListItems(itemId) { var siteUrl=_spPageContextInfo.webServerRelat ...

  9. 读书笔记一、pandas之series

    转自 # 直接传入一组数据 from pandas import Series, DataFrame obj = Series([4, 2, 3]) obj 0 4 1 2 2 3 dtype: in ...

随机推荐

  1. 对于SSH框架的选择

    选择框架:SSH 对于Web开发来说,SSH框架可以提高开发效率,还可以方便需求的变更以及对后期维护方面更容易操作.SSH也是目前稍微流行的Web开发框架. 选择框架描述: 首先说明一下SSH并不是一 ...

  2. jquery.zclip轻量级复制失效问题

    工作原理 利用一个透明的 Flash ,让其漂浮在按钮之上,这样其实点击的不是按钮而是 Flash ,也就可以使用 Flash 的复制功能了 <script src="js/jquer ...

  3. SQL切换真假状态标识字段

    需求:用一条SQL(SQL SERVER)语句,实现反向更改状态标识字段(类型为bit)的值.即是从true变false,或从false到true. 方案: 一.判断原来这个字段值,然后UPDATE为 ...

  4. Android开发7:简单的数据存储(使用SharedPreferences)和文件操作

    前言 啦啦啦~大家好,又见面啦~ 本篇博文讲和大家一起完成一个需要注册.登录的备忘录的,一起学习 SharedPreferences 的基本使用,学习 Android 中常见的文件操作方法,复习 An ...

  5. Android 四大组件 与 MVC 架构模式

    作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是 ...

  6. UILabel

    //UILabel->UIView /* 1.实例化 2.属性 3.添加到父视图上 */ //实例化 UILabel *label = [[UILabel alloc] initWithFram ...

  7. Unix Linux 通用vi命令,使用帮助手册【珍藏版】

    Vi 简介 Vi 是 Unix 世界里极为普遍的全萤幕文书编辑器,几乎可以说任何一台 Unix 机器都会提供这套软体.Linux 当然也有,它的 vi 其实是 elvis(版权问题),不过它们都差不多 ...

  8. Android 框架学习之 第一天 okhttp & Retrofit

    最近面试,一直被问道新技术新框架,这块是短板,慢慢补吧. 关于框架的学习,分几个步骤 I.框架的使用 II.框架主流使用的版本和Android对应的版本 III.框架的衍生使用比如okhttp就会有R ...

  9. tomcat 应用部署的几点注意

    将应用部署到Tomcat根目录的目的是可以通过"http://[ip]:[port]"直接访问应用,而不是使用"http://[ip]:[port]/[appName]& ...

  10. Wintel物联网平台-Windows IoT新手入门指南

    1. 引言 近期,微软跟进物联网的速度也在不断加速,除了微软手环,.NET MicroFramework,还有一个叫做Windows IoT的项目.该项目早在今年4月份的Build大会上就提出来了,7 ...