学习记录——推荐系统实践 2.2 用户行为分析
长尾分布
参考:https://blog.csdn.net/gengsuning/article/details/78094794
https://baike.baidu.com/item/幂律分布/4281937
长尾分布是拖着长长的尾巴的概率分布曲线
长尾分布表明,有很大尺度的 个体总数 很少,而 尺度不高的个体总数很多。
对于推荐系统而言就是要改变用户找到自己喜欢的物品的方式。但是在这里有个悖论,用户不是上帝,无法得知自己是否已经游览过了所有的物品。从而无法找到自己喜欢的物品。“我怎么知道我不知道?”
帕累托定律(80/20 法则)
Zipf定律 每个单词出现的频率与它的排名序号的常数次幂存在简单的反比关系:
P(r) ~r^-α
长尾分布是幂律分布的一些特殊情况
幂律分布
变量x的概率密度函数满足:f(x)~x^(-α-1)
Delicious数据集
链接:https://pan.baidu.com/s/1suYhX2LlTz-ux57VuSwiSA
提取码:35nf
{user’\t’item’\t’tag}
用户活跃度分析
横坐标:用户活跃度
纵坐标:用户活跃度为K 的用户总数
曲线满足长尾分布的特点
表明 用户活跃度低 的 用户 占了 用户的大多数
而 用户活跃度 高的 用户 占了少数。
但是少数的高活跃度用户 贡献了 大量的 用户 活跃度
物品流行度分析
横坐标:物品流行度
纵坐标:物品流行度为K 的物品总数
曲线满足长尾分布
表明 冷门物品 占据 物品的大多数
而 热门 物品 占据 物品的 少数
但是 少数的人们 物品 有很大的 流行度
代码
import csv
import matplotlib.pyplot as plt
def GetData():
user_items = dict()
item_users = dict()
csv_file = csv.reader(open('Delicious.csv', 'r'))
for info in csv_file:
user = info[0]
item = info[1]
user_items.setdefault(user, [])
user_items[user].append(item)
item_users.setdefault(item, [])
item_users[item].append(user)
return user_items, item_users
def PlotItem_Users():
k = dict()
max_len = 0
for item in item_users.keys():
if max_len <= (len(item_users[item])):
max_len = len(item_users[item])
k.setdefault(len(item_users[item]), 0)
k[len(item_users[item])] += 1
y = []
x = []
t = range(max_len)
for i in t:
if i in k:
y.append(k[i])
x.append(i)
plt.title('物品流行度分析', fontproperties='SimHei', fontsize=10)
plt.xlim(xmin=0, xmax=1000)
plt.ylim(ymin=0, ymax=1000)
plt.scatter(x, y, s=10)
plt.show()
def PlotUser_Items():
k = dict()
max_len = 0
for user in user_items.keys():
if max_len < (len(user_items[user])):
max_len = len(user_items[user])
k.setdefault(len(user_items[user]), 0)
k[len(user_items[user])] += 1
y = []
x = []
t = range(1, max_len)
for i in t:
if i in k:
y.append(k[i])
x.append(i)
plt.title('用户活跃度分析', fontproperties='SimHei', fontsize=10)
plt.xlim(xmin=0, xmax=2000)
plt.ylim(ymin=0, ymax=175)
plt.scatter(x, y, s=10)
plt.show()
user_items, item_users = GetData()
PlotItem_Users()
PlotUser_Items()
用户活跃度与物品流行度的关系
movielens数据集
横坐标:用户活跃度
纵坐标:用户活跃度为 K 的 所有用户,评价过的物品,的平均流行度图中曲线呈下降趋势,表明 新用户 比较喜欢 游览热门的物品
而老用户则喜欢游览冷门的物品
代码
import csv
import matplotlib.pyplot as plt
def GetData():
user_items = dict()
item_weight = dict()
item_N = dict()
csv_file = csv.reader(open('test.csv', 'r'))
for info in csv_file:
user = info[0]
item = info[1]
weight = info[2]
user_items.setdefault(user, [])
user_items[user].append([item, weight])
item_weight.setdefault(item, 0)
item_N.setdefault(item, 0)
item_N[item] += 1
item_weight[item] += 1
# for item in item_weight.keys():
# item_weight[item] /= item_N[item]
return user_items, item_weight
def PlotItem_User():
pu = dict()
pi = dict()
max_len = 0
for user in user_items.keys():
if max_len < len(user_items[user]):
max_len = len(user_items[user])
pu.setdefault(len(user_items[user]), 0)
pu[len(user_items[user])] += 1
pi.setdefault(len(user_items[user]), 0)
for items in user_items[user]:
item = items[0]
pi[len(user_items[user])] += item_weight[item]
for k in pi.keys():
pi[k] /= pu[k] * k
t = range(1, max_len)
y = []
x = []
for i in t:
if i in pu:
y.append(pi[i])
x.append(i)
plt.scatter(x, y, label='user_items', s=10)
plt.show()
user_items, item_weight = GetData()
PlotItem_User()