【数据挖掘与商务智能决策】第十五章 智能推荐系统 - 协同过滤算法

前言

本人CSDN博客为“仿生程序员会梦见电子羊吗”,本文基于markdown本文书写,平台及软件为CSDN与Typora,文中图片存储地址为CSDN,故部分图片可能带有“CSDN@仿生程序员会梦见电子羊吗”的水印,属于本人原创,用于“数据挖掘与商务智能决策”的平时作业及大作业部分。

本篇内容为第十五章内容,智能推荐系统 - 协同过滤算法。
为便于阅读,我将文章内容分为以下几个板块:

  1. 基础知识
  2. 实验内容
  3. 拓展研究
  4. 心得体会

其中,各板块的介绍如下:

  • 基础知识
    • 包含关于本章主题的个人学习理解,总结的知识点以及值得记录的代码及运行结果。
  • 实验内容
    • 这是本篇的主题实验部分,也是老师发的实验内容,在电脑上(jupyter notebook)运行成功之后导出为markdown格式。
    • 其中,主标题为每一章的小节内容
      在这里插入图片描述
    • 如上图,主标题为PCA主成分分析与代码实现,次级标题为该文件内的子模块。每一个主标题下内容互不相同,也就是说,会出现两个主标题下均有相同python库引用的情况,为保证代码的完整性,在此予以保留。
    • 为表明确实是完成了课堂作业,故代码与老师给的代码大致相同,但markdown文本部分加入了自己的理解,同时,因为数据源不一定相同,运行结果和绘图也与教程相异,但实验本身是正确完整的。
    • 此外,一些老师发的相关的案(不在课程中心的实验,而是发到课程群中的案例,如 案例 航空公司客户价值分析)也会附在这一部分中。
  • 拓展研究
    • 这个部分是 自己在本课题实验之外尝试的拓展内容,包括代码和知识点,也有自己的实验
  • 心得体会

基础知识

实验内容

15.2 相似度计算三种常见方法

15.2.1 欧式距离

import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
df
用户1用户2用户3
物品A515
物品B422
物品C421
import numpy as np
dist = np.linalg.norm(df.iloc[0] - df.iloc[1])
dist
3.3166247903554

15.2.2 余弦内置函数

import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
df
用户1用户2用户3
物品A515
物品B422
物品C421
from sklearn.metrics.pairwise import cosine_similarity
user_similarity = cosine_similarity(df)
pd.DataFrame(user_similarity, columns=['物品A', '物品B', '物品C'], index=['物品A', '物品B', '物品C'])
物品A物品B物品C
物品A1.0000000.9146590.825029
物品B0.9146591.0000000.979958
物品C0.8250290.9799581.000000

15.2.3 皮尔逊相关系数简单版

from scipy.stats import pearsonr
X = [1, 3, 5, 7, 9]
Y = [9, 8, 6, 4, 2]
corr = pearsonr(X, Y)
print('相关系数r值为' + str(corr[0]) + ',显著性水平P值为' + str(corr[1]))
相关系数r值为-0.9938837346736188,显著性水平P值为0.0005736731093322215

皮尔逊相关系数小案例

import pandas as pd
df = pd.DataFrame([[5, 4, 4], [1, 2, 2], [5, 2, 1]], columns=['物品A', '物品B', '物品C'], index=['用户1', '用户2', '用户3'])  
df
物品A物品B物品C
用户1544
用户2122
用户3521
# 物品A与其他物品的皮尔逊相关系数
A = df['物品A']
corr_A = df.corrwith(A)
corr_A
物品A    1.000000
物品B    0.500000
物品C    0.188982
dtype: float64
# 皮尔逊系数表,获取各物品相关性
df.corr()
物品A物品B物品C
物品A1.0000000.5000000.188982
物品B0.5000001.0000000.944911
物品C0.1889820.9449111.000000

15.3 案例实战 - 电影智能推荐系统

1.读取数据

import pandas as pd 
movies = pd.read_excel('电影.xlsx')
movies.head()
电影编号名称类别
01玩具总动员(1995)冒险|动画|儿童|喜剧|幻想
12勇敢者的游戏(1995)冒险|儿童|幻想
23斗气老顽童2(1995)喜剧|爱情
34待到梦醒时分(1995)喜剧|剧情|爱情
45新娘之父2(1995)喜剧
score = pd.read_excel('评分.xlsx')
score.head()
用户编号电影编号评分
0114.0
1134.0
2164.0
31475.0
41505.0
df = pd.merge(movies, score, on='电影编号')
df.head()
电影编号名称类别用户编号评分
01玩具总动员(1995)冒险|动画|儿童|喜剧|幻想14.0
11玩具总动员(1995)冒险|动画|儿童|喜剧|幻想54.0
21玩具总动员(1995)冒险|动画|儿童|喜剧|幻想74.5
31玩具总动员(1995)冒险|动画|儿童|喜剧|幻想152.5
41玩具总动员(1995)冒险|动画|儿童|喜剧|幻想174.5
df.to_excel('电影推荐系统.xlsx')
df['评分'].value_counts()  # 查看各个评分的出现的次数
4.0    26794
3.0    20017
5.0    13180
3.5    13129
4.5     8544
2.0     7545
2.5     5544
1.0     2808
1.5     1791
0.5     1369
Name: 评分, dtype: int64
%matplotlib inline
import matplotlib.pyplot as plt
df['评分'].hist(bins=20)  # hist()函数绘制直方图,竖轴为各评分出现的次数
<AxesSubplot:>

在这里插入图片描述

2.数据分析

ratings = pd.DataFrame(df.groupby('名称')['评分'].mean())
ratings.sort_values('评分', ascending=False).head()
评分
名称
假小子(1997)5.0
福尔摩斯和华生医生历险记:讹诈之王(1980)5.0
机器人(2016)5.0
奥斯卡(1967)5.0
人类状况III(1961)5.0
ratings['评分次数'] = df.groupby('名称')['评分'].count()
ratings.sort_values('评分次数', ascending=False).head()
评分评分次数
名称
阿甘正传(1994)4.164134329
肖申克的救赎(1994)4.429022317
低俗小说(1994)4.197068307
沉默的羔羊(1991)4.161290279
黑客帝国(1999)4.192446278

3.数据处理

user_movie = df.pivot_table(index='用户编号', columns='名称', values='评分')
user_movie.tail()
名称007之黄金眼(1995)100个女孩(2000)100条街道(2016)101忠狗续集:伦敦大冒险(2003)101忠狗(1961)101雷克雅未克(2000)102只斑点狗(2000)10件或更少(2006)10(1979)11:14(2003)...龙珠:神秘冒险(1988)龙珠:血红宝石的诅咒(1986)龙珠:魔鬼城堡中的睡公主(1987)龙种子(1944)龙纹身的女孩(2011)龙舌兰日出(1988)龙虾(2015)龙:夜之怒的礼物(2011)龙:李小龙的故事(1993)龟日记(1985)
用户编号
606NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
607NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
6084.0NaNNaNNaNNaNNaNNaN3.5NaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
6094.0NaNNaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
610NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaN4.0NaN4.5NaNNaNNaN

5 rows × 9687 columns

user_movie.describe()  # 因为数据量较大,这个耗时可能会有1分钟左右
名称007之黄金眼(1995)100个女孩(2000)100条街道(2016)101忠狗续集:伦敦大冒险(2003)101忠狗(1961)101雷克雅未克(2000)102只斑点狗(2000)10件或更少(2006)10(1979)11:14(2003)...龙珠:神秘冒险(1988)龙珠:血红宝石的诅咒(1986)龙珠:魔鬼城堡中的睡公主(1987)龙种子(1944)龙纹身的女孩(2011)龙舌兰日出(1988)龙虾(2015)龙:夜之怒的礼物(2011)龙:李小龙的故事(1993)龟日记(1985)
count132.0000004.001.01.044.0000001.09.0000003.0000004.0000004.00...1.01.02.0000001.042.00000013.0000007.0000001.08.000002.0
mean3.4962123.252.52.53.4318183.52.7777782.6666673.3750003.75...3.53.53.2500003.53.4880953.0384624.0000005.02.812504.0
std0.8593810.50NaNNaN0.751672NaN0.8333331.0408331.0307760.50...NaNNaN0.353553NaN1.3274220.4311580.707107NaN1.032940.0
min0.5000002.502.52.51.5000003.52.0000001.5000002.0000003.00...3.53.53.0000003.50.5000002.0000003.0000005.00.500004.0
25%3.0000003.252.52.53.0000003.52.0000002.2500003.1250003.75...3.53.53.1250003.52.6250003.0000003.5000005.02.875004.0
50%3.5000003.502.52.53.5000003.52.5000003.0000003.5000004.00...3.53.53.2500003.54.0000003.0000004.0000005.03.000004.0
75%4.0000003.502.52.54.0000003.53.0000003.2500003.7500004.00...3.53.53.3750003.54.0000003.0000004.5000005.03.125004.0
max5.0000003.502.52.55.0000003.54.5000003.5000004.5000004.00...3.53.53.5000003.55.0000004.0000005.0000005.04.000004.0

8 rows × 9687 columns

4.智能推荐

FG = user_movie['阿甘正传(1994)']  # FG是Forrest Gump(),阿甘英文名称的缩写
pd.DataFrame(FG).head()
阿甘正传(1994)
用户编号
14.0
2NaN
3NaN
4NaN
5NaN
import numpy as np
np.seterr(divide='ignore',invalid='ignore')
# axis默认为0,计算user_movie各列与FG的相关系数
corr_FG = user_movie.corrwith(FG)
similarity = pd.DataFrame(corr_FG, columns=['相关系数'])
similarity.head()
D:\coder\randomnumbers\venv\lib\site-packages\numpy\lib\function_base.py:2845: RuntimeWarning: Degrees of freedom <= 0 for slice
  c = cov(x, y, rowvar, dtype=dtype)
D:\coder\randomnumbers\venv\lib\site-packages\numpy\lib\function_base.py:518: RuntimeWarning: Mean of empty slice.
  avg = a.mean(axis, **keepdims_kw)
相关系数
007之黄金眼(1995)0.217441
100个女孩(2000)NaN
100条街道(2016)NaN
101忠狗续集:伦敦大冒险(2003)NaN
101忠狗(1961)0.141023
similarity.dropna(inplace=True)  # 或写成similarity=similarity.dropna()
similarity.head()
相关系数
007之黄金眼(1995)0.217441
101忠狗(1961)0.141023
102只斑点狗(2000)-0.857589
10件或更少(2006)-1.000000
11:14(2003)0.500000
similarity_new = pd.merge(similarity, ratings['评分次数'], left_index=True, right_index=True)
similarity_new.head()
相关系数评分次数
007之黄金眼(1995)0.217441132
101忠狗(1961)0.14102344
102只斑点狗(2000)-0.8575899
10件或更少(2006)-1.0000003
11:14(2003)0.5000004
# 第二种合并方式
similarity_new = similarity.join(ratings['评分次数'])
similarity_new.head()
相关系数评分次数
007之黄金眼(1995)0.217441132
101忠狗(1961)0.14102344
102只斑点狗(2000)-0.8575899
10件或更少(2006)-1.0000003
11:14(2003)0.5000004
similarity_new[similarity_new['评分次数'] > 20].sort_values(by='相关系数', ascending=False).head()  # 选取阈值
相关系数评分次数
阿甘正传(1994)1.000000329
抓狂双宝(1996)0.72323831
雷神:黑暗世界(2013)0.71580921
致命吸引力(1987)0.70185636
X战警:未来的日子(2014)0.68228430

补充知识点:groupby()函数的使用

import pandas as pd
data = pd.DataFrame([['战狼2', '丁一', 6, 8], ['攀登者', '王二', 8, 6], ['攀登者', '张三', 10, 8], ['卧虎藏龙', '李四', 8, 8], ['卧虎藏龙', '赵五', 8, 10]], columns=['电影名称', '影评师', '观前评分', '观后评分'])
data
电影名称影评师观前评分观后评分
0战狼2丁一68
1攀登者王二86
2攀登者张三108
3卧虎藏龙李四88
4卧虎藏龙赵五810
means = data.groupby('电影名称')[['观后评分']].mean()
means
观后评分
电影名称
卧虎藏龙9.0
战狼28.0
攀登者7.0
means = data.groupby('电影名称')[['观前评分', '观后评分']].mean()
means
观前评分观后评分
电影名称
卧虎藏龙8.09.0
战狼26.08.0
攀登者9.07.0
means = data.groupby(['电影名称', '影评师'])[['观后评分']].mean()
means
观后评分
电影名称影评师
卧虎藏龙李四8.0
赵五10.0
战狼2丁一8.0
攀登者张三8.0
王二6.0
count = data.groupby('电影名称')[['观后评分']].count()
count
观后评分
电影名称
卧虎藏龙2
战狼21
攀登者2
count = count.rename(columns={'观后评分':'评分次数'})
count
评分次数
电影名称
卧虎藏龙2
战狼21
攀登者2

拓展研究

心得体会

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值