原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式。

我用pandas实现相同的公式只要3行。

特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据。

'''
基于用户的协同推荐 矩阵数据
''' import pandas as pd
from io import StringIO
import json #数据类型一:csv矩阵(用户-商品)(适用于小数据量)
csv_txt = '''"user","Blues Traveler","Broken Bells","Deadmau5","Norah Jones","Phoenix","Slightly Stoopid","The Strokes","Vampire Weekend"
"Angelica",3.5,2.0,,4.5,5.0,1.5,2.5,2.0
"Bill",2.0,3.5,4.0,,2.0,3.5,,3.0
"Chan",5.0,1.0,1.0,3.0,5,1.0,,
"Dan",3.0,4.0,4.5,,3.0,4.5,4.0,2.0
"Hailey",,4.0,1.0,4.0,,,4.0,1.0
"Jordyn",,4.5,4.0,5.0,5.0,4.5,4.0,4.0
"Sam",5.0,2.0,,3.0,5.0,4.0,5.0,
"Veronica",3.0,,,5.0,4.0,2.5,3.0,''' #数据类型二:json数据(用户、商品、打分)
json_txt = '''{"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0,
"Norah Jones": 4.5, "Phoenix": 5.0,
"Slightly Stoopid": 1.5,
"The Strokes": 2.5, "Vampire Weekend": 2.0}, "Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5,
"Deadmau5": 4.0, "Phoenix": 2.0,
"Slightly Stoopid": 3.5, "Vampire Weekend": 3.0}, "Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0,
"Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5,
"Slightly Stoopid": 1.0}, "Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0,
"Deadmau5": 4.5, "Phoenix": 3.0,
"Slightly Stoopid": 4.5, "The Strokes": 4.0,
"Vampire Weekend": 2.0}, "Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0,
"Norah Jones": 4.0, "The Strokes": 4.0,
"Vampire Weekend": 1.0}, "Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0,
"Norah Jones": 5.0, "Phoenix": 5.0,
"Slightly Stoopid": 4.5, "The Strokes": 4.0,
"Vampire Weekend": 4.0}, "Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0,
"Norah Jones": 3.0, "Phoenix": 5.0,
"Slightly Stoopid": 4.0, "The Strokes": 5.0}, "Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0,
"Phoenix": 4.0, "Slightly Stoopid": 2.5,
"The Strokes": 3.0}
}''' df = None #方式一:加载csv数据
def load_csv_txt():
global df
df = pd.read_csv(StringIO(csv_txt), header=0, index_col="user") #方式二:加载json数据(把json读成矩阵)
def load_json_txt():
global df
df = pd.read_json(json_txt, orient='index') #测试:读取数据
load_csv_txt()
#load_json_txt() def build_xy(user_name1, user_name2):
#df2 = df.ix[[user_name1, user_name2]].dropna(axis=1)
#return df2.ix[user_name1], df2.ix[user_name2] bool_array = df.ix[user_name1].notnull() & df.ix[user_name2].notnull()
return df.ix[user_name1, bool_array], df.ix[user_name2, bool_array] #曼哈顿距离
def manhattan(user_name1, user_name2):
x, y = build_xy(user_name1, user_name2)
return sum(abs(x - y)) #欧几里德距离
def euclidean(user_name1, user_name2):
x, y = build_xy(user_name1, user_name2)
return sum((x - y)**2)**0.5 #闵可夫斯基距离
def minkowski(user_name1, user_name2, r):
x, y = build_xy(user_name1, user_name2)
return sum(abs(x - y)**r)**(1/r) #皮尔逊相关系数
def pearson(user_name1, user_name2):
x, y = build_xy(user_name1, user_name2)
mean1, mean2 = x.mean(), y.mean()
#分母
denominator = (sum((x-mean1)**2)*sum((y-mean2)**2))**0.5
return [sum((x-mean1)*(y-mean2))/denominator, 0][denominator == 0] #余弦相似度(数据的稀疏性问题,在文本挖掘中应用得较多)
def cosine(user_name1, user_name2):
x, y = build_xy(user_name1, user_name2)
#分母
denominator = (sum(x*x)*sum(y*y))**0.5
return [sum(x*y)/denominator, 0][denominator == 0] metric_funcs = {
'manhattan': manhattan,
'euclidean': euclidean,
'minkowski': minkowski,
'pearson': pearson,
'cosine': cosine
} #df.ix[["Angelica","Bill"]].dropna(axis=1)
print(manhattan("Angelica","Bill")) #计算最近的邻居
def computeNearestNeighbor(user_name, metric='pearson', k=3, r=2):
'''
metric: 度量函数
k: 返回k个邻居
r: 闵可夫斯基距离专用 返回:pd.Series,其中index是邻居名称,values是距离
'''
if metric in ['manhattan', 'euclidean']:
return df.drop(user_name).index.to_series().apply(metric_funcs[metric], args=(user_name,)).nsmallest(k)
elif metric in ['minkowski']:
return df.drop(user_name).index.to_series().apply(metric_funcs[metric], args=(user_name, r,)).nsmallest(k)
elif metric in ['pearson', 'cosine']:
return df.drop(user_name).index.to_series().apply(metric_funcs[metric], args=(user_name,)).nlargest(k) print(computeNearestNeighbor('Hailey', metric='pearson')) #向给定用户推荐(返回:pd.Series)
def recommend(user_name):
# 找到距离最近的用户名
nearest_username = computeNearestNeighbor(user_name).index[0] # 找出邻居评价过、但自己未曾评价的乐队(或商品)
# 结果:index是商品名称,values是评分
return df.ix[nearest_username, df.ix[user_name].isnull() & df.ix[nearest_username].notnull()].sort_values() #为Hailey做推荐
print(recommend('Hailey')) #向给定用户推荐
def recommend2(user_name, metric='pearson', k=3, n=5, r=2):
'''
metric: 度量函数
k: 根据k个最近邻居,协同推荐
r: 闵可夫斯基距离专用
n: 推荐的商品数目 返回:pd.Series,其中index是商品名称,values是加权评分
'''
# 找到距离最近的k个邻居
nearest_neighbors = computeNearestNeighbor(user_name, metric='pearson', k=k, r=r) # 计算权值
if metric in ['manhattan', 'euclidean', 'minkowski']: # 距离越小,越类似
nearest_neighbors = 1 / nearest_neighbors # 所以,取倒数(或者别的减函数,如:y=2**-x)
elif metric in ['pearson', 'cosine']: # 距离越大,越类似
pass nearest_neighbors = nearest_neighbors / nearest_neighbors.sum() #已经变为权值(pd.Series) # 逐个邻居找出其评价过、但自己未曾评价的乐队(或商品)的评分,并乘以权值
neighbors_rate_with_weight = []
for neighbor_name in nearest_neighbors.index:
# 每个结果:pd.Series,其中index是商品名称,values是评分(已乘权值)
neighbors_rate_with_weight.append(df.ix[neighbor_name, df.ix[user_name].isnull() & df.ix[neighbor_name].notnull()] * nearest_neighbors[neighbor_name]) # 把邻居们的加权评分拼接成pd.DataFrame,按列累加,取最大的前n个商品的评分
return pd.concat(neighbors_rate_with_weight, axis=1).sum(axis=1, skipna=True).nlargest(n) #为Hailey做推荐
print(recommend2('Hailey', metric='manhattan', k=3, n=5)) #为Hailey做推荐
print(recommend2('Hailey', metric='euclidean', k=3, n=5, r=2)) #为Hailey做推荐
print(recommend2('Hailey', metric='pearson', k=1, n=5))

【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)的更多相关文章

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

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

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

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

  3. 【笔记6】用pandas实现条目数据格式的推荐算法 (基于物品的协同)

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

  4. 简单的基于矩阵分解的推荐算法-PMF, NMF

    介绍: 推荐系统中最为主流与经典的技术之一是协同过滤技术(Collaborative Filtering),它是基于这样的假设:用户如果在过去对某些项目产生过兴趣,那么将来他很可能依然对其保持热忱.其 ...

  5. HAWQ + MADlib 玩转数据挖掘之(四)——低秩矩阵分解实现推荐算法

    一.潜在因子(Latent Factor)推荐算法 本算法整理自知乎上的回答@nick lee.应用领域:"网易云音乐歌单个性化推荐"."豆瓣电台音乐推荐"等. ...

  6. (转) 基于MapReduce的ItemBase推荐算法的共现矩阵实现(一)

    转自:http://zengzhaozheng.blog.51cto.com/8219051/1557054 一.概述 这2个月为公司数据挖掘系统做一些根据用户标签情况对用户的相似度进行评估,其中涉及 ...

  7. 用Spark学习矩阵分解推荐算法

    在矩阵分解在协同过滤推荐算法中的应用中,我们对矩阵分解在推荐算法中的应用原理做了总结,这里我们就从实践的角度来用Spark学习矩阵分解推荐算法. 1. Spark推荐算法概述 在Spark MLlib ...

  8. 推荐算法之用矩阵分解做协调过滤——LFM模型

    隐语义模型(Latent factor model,以下简称LFM),是推荐系统领域上广泛使用的算法.它将矩阵分解应用于推荐算法推到了新的高度,在推荐算法历史上留下了光辉灿烂的一笔.本文将对 LFM ...

  9. Python 的 Pandas 对矩阵的行进行求和

    Python 的 Pandas 对矩阵的行进行求和: 若使用 df.apply(sum) 方法的话,只能对矩阵的列进行求和,要对矩阵的行求和,可以先将矩阵转置,然后应用 df.apply(sum) 即 ...

随机推荐

  1. MySQL的SSL加密连接与性能开销

    本文转载自:http://www.innomysql.net/article/23959.html(只作转载, 不代表本站和博主同意文中观点或证实文中信息) Contents [hide] 1 前言 ...

  2. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  3. javascript 模式(2)——单例模式

    单例模式是一种非常极端的模式,它保证了一个类在整个应用程序域中只有一个实体,意味着当你多次创建某一个类的实例的时候它们都是第一次创建的那个. 在Java或c#环境实现单例模式很简单,只需要定义静态变量 ...

  4. TouchPoint.js – 可视化展示 HTML 原型点击效果

    TouchPoint.js 是一个用于 HTML 原型展示的 JavaScript 库(作为UX过程的一部分),通过视觉表现用户在屏幕上的点击.TouchPoint 是高度可定制,非常适合屏幕录制,用 ...

  5. 提交留言HTML模板代码

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  6. [deviceone开发]-do_ImageView实现正圆的示例

    一.简介 我们经常需要用一个正圆形状的图片来设置头像,在do平台这个比较容易,就是通过设置圆角来实现,但是有几个小技巧需要解释一下 主要组件:do_ImageView 二.效果图 三.相关下载 htt ...

  7. SharePoint服务器端对象模型 之 使用CAML进展数据查询

    SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列 ...

  8. 参加了iDOF2016会议,发表演讲“油田SOA与云平台的系统思考与实践”

    PPT的全部抓图,扫描二维码直接到微信里去看吧:

  9. iOS 系统分析(一) 阅读内核准备知识

    ➠更多技术干货请戳:听云博客 0x01 iOS体系架构 1.1 iOS 系统的整体体系架构 用户体验( The User Experience layer ):SpringBoard 同时支持 Spo ...

  10. iOS开发之功能模块--用runtime给UIView类别拓展PressMenu工具

    这是个很有用的列别工具类,在聊天对话框添加和QQ一样的"复制.粘贴.取消"等选项,而且使用起来很方便,只要找到聊天泡泡内部的某个View,比如Label或者背景冒泡的UIImage ...