【Educoder数据挖掘实训】相似度与相异度

【Educoder数据挖掘实训】相似度与相异度

开挖!!!!!!

T1 用相关系数计算直线之间的相似度

这关分为没啥关系的三部分,分别是欧几里得相关系数、余弦相关系数和泊松相关系数。

他们的公式都比较直观:

欧几里得相关系数的计算方式是按照对应点的相对距离来算的,也就是 d ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d(x,y) = \sqrt{\sum\limits_{i = 1}^{n}(x_i - y_i)^2} d(x,y)=i=1∑n(xi−yi)2 .

余弦相关系数则将两个数据看做两个 n n n维向量,计算方式为: c o s ( θ ) = ∑ i = 1 n ( x i × y i ) ∑ i = 1 n x i 2 ∑ i = 1 n y i 2 cos(\theta) = \frac{\sum\limits_{i = 1}^n (x_i\times y_i)}{\sum\limits_{i = 1}^{n}x_i^2\sum\limits_{i = 1}^{n}y_i^2} cos(θ)=i=1∑nxi2i=1∑nyi2i=1∑n(xi×yi)。

泊松相关系数将两个数据看成是数据集,计算方式为: ρ X Y = E ( ( X − E X ) ( Y − E Y ) ) D X D Y \rho_{XY} = \frac{E((X - EX)(Y - EY))}{\sqrt{DX}\sqrt{DY}} ρXY=DX DY E((X−EX)(Y−EY))。

其中第一部分代码只需要按照公式复刻一遍即可。

泊松部分的代码需要认真看一眼实训,实训给出的样例中提及了日期,只需要复制另一个人的日期即可。

代码如下:

python 复制代码
# 欧几里得相关系数
def euclidean(p, q):
    # 如果两数据集数目不同,计算两者之间都对应有的数
    same = 0
    for i in p:
        if i in q:
            same += 1
    # 计算欧几里德距离,并将其标准化
    # ***********Begin**********
    e = sum([(p[i] - q[i]) ** 2 for i in range(same)])
    # ************End***********   
    return 1 / (1 + e ** 0.5)
print("欧几里得计算出的相似度为",euclidean([1, 2, 3, 4, 5], [2, 4, 6,8, 10]))
# 余弦相似度
def cosine_similarity(x, y):
    xx = 0.0
    yy = 0.0
    xy = 0.0
    for i in range(len(x)):
        xx += x[i] * x[i]
        yy += y[i] * y[i]
        xy += x[i] * y[i]
    xx_sqrt = xx ** 0.5
    yy_sqrt = yy ** 0.5
    cos = xy/(xx_sqrt*yy_sqrt)
    return cos
print('余弦相关系数计算出的相似度为',cosine_similarity([5,3],[5,8]))
#泊松相关系数
import scipy
import numpy
from scipy.stats import pearsonr
########## Begin ##########
x =numpy.array([0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1])
########## End ##########
y =numpy.array([1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3])
r_row, p_value = pearsonr(x, y)
print ("用户(UID)84001033与用户(UID)84001003从2004/1/20到4/20/20这段日期的相似度为",r_row)

T2 基于相似度度量的商品推荐

这一关主要提及了 J a c c a r d Jaccard Jaccard 公式和余弦相似度,并在代码里要求复现余弦相似度的过程。

这个过程的核心思想是,将用户的喜欢商品列表转换成:每个商品被哪些用户喜欢。

我们将喜欢列表成为表 1 1 1,被喜欢列表成为表 2 2 2。

在构造系数的时候,对于两个不同的用户取二者表 1 1 1的交集计算数量加到一个横纵元素都为全体用户的表中,例如用户 A A A和用户 B B B共同喜欢三个商品 a , b , c a,b,c a,b,c,那么空表中 ( A , B ) , ( B , A ) (A,B),(B,A) (A,B),(B,A)都为 3 3 3。

然后我们用余弦计算公式把该表中所有整数都计算为余弦相似度。

对于每个用户 P P P在推荐商品的时候,对于一个商品 x x x, x x x的表 2 2 2中每一个用户除去 P P P的余弦值加在一起,成为 x x x的推荐度。取所有 P P P的表 1 1 1里没有的商品中推荐值最大的商品推荐给 P P P即可。

python 复制代码
# (一):找到与目标用户兴趣相似的用户集合
########## Begin ##########
# 目标用户(A用户喜欢a、b、d商品)
target_user = {'A':['a','b','d']}
print(f'目标用户:{target_user}')
# 相似用户用户()
alike_user = {'B': ['a','c'],'C': ['b','e'],'D':['c','d','e']}
print(f'相似用户:{alike_user}')
########## End ##########
# 倒排表
"""
a A B C
"""
# 总共商品类型
key_value = []
value1 = target_user.values()
for item in value1:
    for good in item:
        # 如果不再就添加到键值
        if good not in key_value:
            key_value.append(good)
value2 = alike_user.values()
########## Begin ##########
for item in value2:
    for good in item:
        if good not in key_value:
            key_value.append(good)
print(f'总共商品类型:{key_value}')
########## End ##########
new_table = []
for good in key_value:
    new_dict = {}
    user_list = []
    # 目标用户
    key_value_list = target_user.items()
    # print(key_value_list)
    for key_value in key_value_list:
        key = key_value[0]
        value = key_value[1]
        if (good in value) & (key not in user_list):
            user_list.append(key)
    # new_dict[good] = user_list
    # new_table.append(new_dict)
    # 相似用户
    key_value_list = alike_user.items()
    # print(key_value_list)
    for key_value in key_value_list:
        key = key_value[0]
        value = key_value[1]
        if (good in value) & (key not in user_list):
            user_list.append(key)
    new_dict[good] = user_list
    new_table.append(new_dict)
print(new_table)
########## Begin ##########
# 计算余弦相似度
import pandas as pd
import numpy as np
df = pd.DataFrame(data=np.zeros((4,4)), columns=['A','B','C','D'],index=['A','B','C','D'])
print(df)
# 统计交集
for item in new_table:
    print(list(item.values())[0])
    label = list(item.values())[0]
    x = label[0]
    y = label[1]
    df.loc[x,y] = df.loc[x,y] + 1
    df.loc[y,x] = df.loc[y,x] + 1
print(df)
########## End ##########
# 计算两两之间的相似度
count_list = {}
for i in ['A','B','C','D']:
    count = df.loc[i,:].sum()
    count_list[i] = count
print(count_list)
# 计算余弦相似度
########## Begin ##########
for i in ['A','B','C','D']:
    for j in ['A', 'B', 'C', 'D']:
        df.loc[i,j] = df.loc[i,j] / np.sqrt(count_list[i] * count_list[j])
########## End ##########
print(df)
########## Begin ##########
# 计算p(A,c)和p(A,e)
p_Ac = df.loc['A','B'] + df.loc['A','D']
print(f'p(A,c):{p_Ac}')
p_Ae = df.loc['A','C'] + df.loc['A','D']
print(f'p(A,e):{p_Ae}')
########## End ##########
if p_Ac > p_Ae:
    print("用户A对c商品更感兴趣,将e商品推荐给A")
elif p_Ac < p_Ae:
    print("用户A对e商品更感兴趣,将e商品推荐给A")
else:
    print("用户A对c商品和e商品同样感兴趣!")

补充:

  1. 代码里有个明显笔误,无论如何都推荐商品 e e e。
  2. 这种推荐方法其实很容易有两个商品的值都一样的情况,当然在本题本题中不会出现。一般我们应对这种问题的处理方法就是将两个商品打包或者继续继续观察这两个商品的受众。
相关推荐
Python大数据分析@27 分钟前
python操作CSV和excel,如何来做?
开发语言·python·excel
黑叶白树29 分钟前
简单的签到程序 python笔记
笔记·python
北京搜维尔科技有限公司29 分钟前
搜维尔科技:【应用】Xsens在荷兰车辆管理局人体工程学评估中的应用
人工智能·安全
说私域32 分钟前
基于开源 AI 智能名片 S2B2C 商城小程序的视频号交易小程序优化研究
人工智能·小程序·零售
YRr YRr33 分钟前
深度学习:Transformer Decoder详解
人工智能·深度学习·transformer
知来者逆38 分钟前
研究大语言模型在心理保健智能顾问的有效性和挑战
人工智能·神经网络·机器学习·语言模型·自然语言处理
Shy96041842 分钟前
Bert完形填空
python·深度学习·bert
云起无垠1 小时前
技术分享 | 大语言模型赋能软件测试:开启智能软件安全新时代
人工智能·安全·语言模型
上海_彭彭1 小时前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
老艾的AI世界1 小时前
新一代AI换脸更自然,DeepLiveCam下载介绍(可直播)
图像处理·人工智能·深度学习·神经网络·目标检测·机器学习·ai换脸·视频换脸·直播换脸·图片换脸