Python:计算管理层讨论与分析的余弦相似度

发布时间:2022-06-24 阅读 307

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:梁淑珍 (华侨大学)
邮箱13514084150@163.com

编者按:本文主要参考自下文「Cosine Similarity Explained using Python」,特此致谢!


目录


我们所熟知的智能推荐算法,在很大程度上依赖于能否正确识别一组研究对象或用户之间的相似性。计算相似度的方法有很多,本文主要介绍余弦相似度。

1. 余弦相似度原理

余弦相似度是通过计算两个非零向量的余弦值来衡量它们之间的相似程度,这与内积的计算过程相同。具体来看以下三个向量:

接着,将这三个向量绘制在坐标轴中:

从上图可以看出 B 比 C 更接近 A,可以说 A 与 B 更相似。那么,我们该如何从数学上度量它们之间的相似性呢? 一个直接的方法是通过余弦值来判断两个向量的接近程度,相关计算公式如下:

具体来看,余弦相似度计算过程可分为以下三步:

Step1:计算点积

其中,Ai 和 Bi 分别代表向量 A 和 B 的第 i 个分量。在本例中,向量 A 和向量 B 的点积为:

Step2:计算模长

在本例中,

Step3:计算余弦相似度

经过计算,向量 A 与向量 B 之间的余弦相似度约为 0.976。要注意,相似度的计算具有对称性,即 A 与 B 的相似度等价于 B 与 A 的相似度。重复上述计算过程,可以得出 A 和 C 的余弦相似度值约为 0.740。以上结果和我们看到的结果基本一致。但在大多数情况下,待处理的数据有多个甚至上百个特征,在高维空间中,想要通过可视化判断数据之间的相似程度是不可能的。

2. 计算余弦相似度

在理解了余弦相似度的原理之后,赶紧实操起来吧!例如,现有三种产品,连帽衫、毛衣和短上衣,我们想知道哪两种产品比较相似。其中,这三种产品的长宽数据如下:

Product Width Length
Hoodie 1 4
Sweater 2 4
Crop−top 3 2

以上数据集与文章开头使用的数据集完全一致。我们可以通过常识判断,连帽衫和毛衣的相似度更高。利用 Python 计算余弦相似度时,我们需要导入 pandassklearn 两个模块。首先,将数据导入到数据框中。

import pandas as pd
data = {'width': [1, 2, 3],
        'length': [4, 4, 2]}
df = pd.DataFrame (data, columns = ['width','length'])
print(df)

接下来,使用 sklearn 库中的 cosine_similarity() 方法,算出数据集中每个向量之间的余弦相似度。

from sklearn.metrics.pairwise import cosine_similarity
similarity = cosine_similarity(df)
print(similarity)

输出结果为二维数组:

[[1.         0.97618706 0.73994007]
 [0.97618706 1.         0.86824314]
 [0.73994007 0.86824314 1.        ]]

为了更好地理解这些数字,可以将数组转化为矩阵。

A B C
A 1 0.98 0.74
B 0.98 1 0.87
C 0.74 0.87 1

Python 的计算结果与手工计算相同,使用以上代码可以将数据集扩展至更高维度。

3. 计算MDA相似度

以上为英文情境下余弦相似度的计算,接着,我们来看一下中文情境下余弦相似度如何计算。在这里,我们使用到了 CNRDS 数据库中关于 MDA 的 10 个样本数据,如需完整的 MDA 数据请到 CNRDS 数据库中下载。

# 导入包
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import jieba
import re

# 调用数据
data = pd.read_excel("https://file.lianxh.cn/data/m/mda.xlsx")
stopwords = pd.read_csv("https://file.lianxh.cn/data/c/cn_stopwords.txt", names=["stopwords"])

# 定义分词函数
def cut_words(text):
    words_list = []
    text = re.sub("[\W\d]", "", text) # 替换符号和数字
    words = jieba.lcut(text)
    for word in words:
        if word not in list(stopwords["stopwords"]):
            words_list.append(word)
    return " ".join(words_list)

# 对文本分词
data["BusDA"] = data["BusDA"].apply(cut_words)
data

# 计算余弦相似度矩阵
vectorizer = CountVectorizer(token_pattern=r"(?u)\b\w+\b")
vec = vectorizer.fit_transform(data["BusDA"])
cosine_similarity(vec)

分词后的结果:

余弦相似度矩阵:

array([[1.        , 0.3165504 , 0.31895506, 0.27677875, 0.33998794,
        0.25348823, 0.27488111, 0.29996853, 0.25345615, 0.32091215],
       [0.3165504 , 1.        , 0.65884621, 0.52496836, 0.71573014,
        0.65217931, 0.61471667, 0.57745084, 0.64927521, 0.67862564],
       [0.31895506, 0.65884621, 1.        , 0.6071593 , 0.72656538,
        0.74081512, 0.80501318, 0.56269624, 0.69008168, 0.72926925],
       [0.27677875, 0.52496836, 0.6071593 , 1.        , 0.50823713,
        0.56432137, 0.59490604, 0.46788029, 0.52515139, 0.572396  ],
       [0.33998794, 0.71573014, 0.72656538, 0.50823713, 1.        ,
        0.67640137, 0.66767656, 0.49595091, 0.63913139, 0.74228471],
       [0.25348823, 0.65217931, 0.74081512, 0.56432137, 0.67640137,
        1.        , 0.77904189, 0.54162275, 0.70334395, 0.68416732],
       [0.27488111, 0.61471667, 0.80501318, 0.59490604, 0.66767656,
        0.77904189, 1.        , 0.52515054, 0.68631957, 0.63833877],
       [0.29996853, 0.57745084, 0.56269624, 0.46788029, 0.49595091,
        0.54162275, 0.52515054, 1.        , 0.55504522, 0.57993023],
       [0.25345615, 0.64927521, 0.69008168, 0.52515139, 0.63913139,
        0.70334395, 0.68631957, 0.55504522, 1.        , 0.67550277],
       [0.32091215, 0.67862564, 0.72926925, 0.572396  , 0.74228471,
        0.68416732, 0.63833877, 0.57993023, 0.67550277, 1.        ]])

4. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh python, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh