Stata文本分析:lsemantica-潜在语义分析的文本相似性判别

文摘   教育   2024-10-23 22:00   中国  

👇 连享会 · 推文导航 | www.lianxh.cn

🍓 课程推荐:2024 机器学习与因果推断专题
主讲老师:司继春 (上海对外经贸大学) ;张宏亮(浙江大学)
课程时间:2024 年 11 月 9-10 日 ;16-17日
课程咨询:王老师 18903405450(微信)

 课程特色 · 2024机器学习与因果推断

  • 懂原理、会应用。本次课程邀请了两位老师合作讲授,目的在于最大限度地实现理论与应用的有机结合。为期四天的课程,分成两个部分:第一部分讲解常用的机器学习算法和适用条件,以及文本分析和大语言模型;第二部分通过精讲 4-6 篇发表于 Top 期刊的论文,帮助大家理解各类机器学习算法的应用场景,以及它们与传统因果推断方法的巧妙结合。
  • 以 Top 期刊论文为范例。目前多数人的困惑是不清楚如何将传统因果推断方法与机器学习结合起来。事实上,即便是 MIT 和 Harvard 的大牛们也都在「摸着石头过河」。为此,通过论文精讲和复现来学习这部分内容或许是目前最有效的方式了。张宏亮老师此前在浙江大学按照这一模式教授了「因果推断和机器学习」课程,效果甚佳:学生们能够逐渐建立起研究设计的理念,并在构造识别策略时适当地嵌入机器学习方法。



作者: 赵汗青 (华南理工大学)
邮箱: hqingzh@gmail.com

编者按:本推文部分摘译自如下论文,特此致谢!
Source:Schwarz, C. (2019). lsemantica: A command for text similarity based on latent semantic analysis. The Stata Journal, 19(1), 129-142. -PDF-

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:


目录

  • 1. 潜在语义分析

  • 2. lsemantica 命令

    • 2.1 理论部分

    • 2.2 语法介绍

  • 3. Stata 实例

    • 3.1 英文实例-计算论文标题相似度

    • 3.2 中文实例-计算 MD&A 相似度

  • 4. 相关推文



1. 潜在语义分析

在基于词频的文本相似度分析中,主要存在以下问题:

  • 同一个词汇在不同的语境中可能有不同的含义,即 “一词多义”;
  • 不同词汇在不同的语境中可能表达相同的含义,即 “多词一义”。

为了解决该问题,Deerwester 等 (1990) 提出了潜在语义分析 (latent semantic analysisa, LSA)。该方法的主要特征如下:

  • 它一种基于机器学习来比较单词或文本相似度的算法;
  • 由于理解单词的含义和上下文很重要,LSA 通过考虑单词之间的关系和潜在的多重含义来改进相似度计算结果。

这些属性使得 LSA 有着广泛的应用场景,包括:

  • 计算单词之间相似性
  • 计算文本之间相似性
  • 基于计算机辅助的摘要写作
  • 对论文进行自动评分
  • 评估语篇连贯性

虽然 Stata 中已经提供了 strdist 命令用于计算 Levenshtein 编辑距离、txttool 命令用于文本数据的清理和标记化、以及 ldagibbs 命令可以按相似主题对文本进行分类,但如果要计算文本之间的相似程度,我们还需要 lsemantica 命令。

2. lsemantica 命令

2.1 理论部分

2.1.1 建立 “文档-词汇” 矩阵

LSA 基本原理是通过计算每个文档中词汇分布情况的相似程度,来分析文档间的相似性,因此 lsemantica 命令首先要基于词袋模型创建一个 “文档-词汇” 矩阵 (document-term matrix)。


在矩阵 中,行数 代表需要分析的文档的数量,列数 代表分词后所有文档中的词汇数量。 代表词汇 在文档 中出现的次数。

2.1.2 对 “文档-词汇” 矩阵重新加权

接着,lsemantica 根据 TFIDF (termfrequency-inverse-document-frequency) 对矩阵 中的 进行加权。其计算公式如下:


其中, 是第 个词在所有文档中出现的数量。TFIDF 的计算也可以通过 Stata 命令 textfind 实现。TFIDF 加权的意义在于降低那些同时出现在多个文档中的单词权重,因为这些单词对于文档的整体意义通常不够重要。TFIDF加权后,矩阵 变成如下矩阵:


2.1.3 对 “文档-词汇” 矩阵进行截断奇异值分解

当文档较多时,即 较大时,计算量会比较大。为了降低算力,lsemantica 命令会对矩阵 进行奇异值分解,并得到 正交矩阵 方阵 、以及 正交矩阵

之后,lsemantica 对分解后的矩阵进行截断降维。矩阵 的奇异值从高到低排,去掉其中最小特征值相关的行和列,仅保留用户选择的 ,这使得矩阵的维度变为 。因此矩阵 变成 ,矩阵 变为 ,矩阵 变成 (见下图的阴影部分)。

值得注意的是, 的数量通常是根据词汇表的大小来选择的,Martin 和 Berry (2007) 认为 100~1000 通常会产生良好的效果。降维过程的最终结果是,产生矩阵 的低阶近似矩阵 。这一过程是 LSA 中最重要的步骤,因为它将原本的语义空间压缩到 这一最重要的部分。

2.1.4 用截断后的矩阵构造语义空间

lsemantica 基于 得到的  “文档-成分” 矩阵来计算文档相似性,该矩阵是矩阵 的降维语义空间。通过 lsemantica cosine 对该矩阵的各个行向量计算余弦相似度,可以得到各个文档之间的相似度。除此之外,lsemantica 还可以保存 “单词-成分” 矩阵 ,并通过命令 lsemantica_word_comp 读取。该矩阵主要用于判断单个单词之间的词义相似度,即用于识别多词同义的情形。

2.2 语法介绍

*命令安装
net install st0552.pkg, replace
*语法介绍
lsemantica varname, components(integer) tfidf min char(integer) ///
stopwords(string) min freq(integer) max freq(real) ///
name new var(string) mat save path(string)
  • components(integer) 指定语义空间应该减少到的组件数量。组件的数量通常基于词汇表的大小来选择,默认值为 components(300)
  • tfidf 指定在应用截断奇异值分解之前是否应该使用 tfidf 重新加权。在大多数情况下,tfidf 重新加权将改善结果;
  • min_char(integer) 允许从文本中删除短词。字符少于最小字符的单词将从 LSA 中排除。默认值为 min_char(0)
  • stopwords(string) 指定要从 lsemantica 中排除停用词;
  • min_freq(integer) 允许删除出现在较少文档中的单词。默认值为min_freq(0)
  • max_freq(real) 允许删除文档中频繁出现的单词。默认值为 max_freq(1)
  • name_new_var(string) 指定 lsemantica 创建的输出变量的名称。这些变量包含每个文档的组件。默认情况下,变量的名称前缀是 component;
  • mat_save 指定是否应保存单词成分矩阵 。这个矩阵描述了单词之间的语义关系。默认情况下,不会保存矩阵;
  • path(string) 设置保存单词分量矩阵的路径。

3. Stata 实例

3.1 英文实例-计算论文标题相似度

本例子的数据集为 1980-2016 年在经济期刊上发表的 41349 篇文章的标题。在进行 LSA 之前,先删除标题中的非字母数字字符,并列出前三篇文章清洗后的标题。

. *数据获取
. cap mkdir tmp //建立临时文件夹
. cd "./tmp"
. net get st0552.pkg, replace ///
> from(http://www.stata-journal.com/software/sj19-1/)
. use example_data.dta, clear
. gen text_strings = title
. *剔除非字母和数字字符
. replace text_strings=strlower(text_strings)
. replace text_strings = ustrregexra(text_strings, "[^a-zA-Z ]", "")
. replace text_strings = stritrim(text_strings)
. list text_strings in 1/3
+------------------------------------------------------------------+
| text_strings |
|------------------------------------------------------------------|
1. | what is labor supply and do taxes affect it |
2. | tax rules and the mismanagment of monetary policy |
3. | a consistent characterization of a nearcentury of price behavior |
+------------------------------------------------------------------+

首先,lsemantica 生成 “文档-词汇” 矩阵,从数据中删除小于 4 个字符的单词和出现在少于 10 个文档或超过一半文档中的单词,并将定义的停止词列表 stopwords 中的单词从数据中删除。

然后,lsemantica 使用 TFIDF 对生成的 “文档-词汇” 矩阵进行重新加权。每当处理了 10% 的词汇表时,该命令都会报告。

. *自定义被排除的单词列表 (停止词)
. global stopwords "a able about across after all almost also
> am among an and any are as at be because been but by can
> cannot could dear did do does either else ever every for
> from get got had has have he her hers him his how however
> i if in into is it its just east let like likely may me
> might most must my neither no nor not of off often on
> only or other our own rather said say says she should
> since so some than that the their them then there these
> they this tis to too twas us wants was we were what when
> where which while who whom why will with would yet you your"

. *进行潜在语义分析
. lsemantica text_strings, components(300) min_char(4) ///
> min_freq(10) max_freq(0.5) tfidf stopwords("$stopwords") ///
> path("$path") mat_save

如果某些文档在文本清洗后没有剩下的单词文本,这些样本将被删除。因为它们干扰了截断奇异值分解。lsemantica 会报告哪些文档已经从数据中删除,以及词汇表的大小。在本示例中,167 个文档被删除。

需要注意的是,在 lsemantica 计算截断奇异值分解的过程中需要较多的算力,可能会运行较长时间,有时候 Stata 会变得无响应。其计算时长时间随着 “文档-词汇矩阵” 的大小而增加,即随着文档数量和词汇表的大小而增加。

lsemantica 运行完毕后,可以使用 lsemantica_cosine 命令计算分量向量之间的余弦相似度,即各文档间相似度。lsemantica_cosine 计算了与其他文档标题的平均相似度以及最大和最小相似度。

. lsemantica_cosine component_1-component_300, mean_cosine     ///
> min_cosine max_cosine find_similar(10) find_similar_cosine(10)

. *查看平均相似度描述性统计
. summarize mean_similarity, detail
mean_similarity
-------------------------------------------------------------
Percentiles Smallest
1% .004445 .0019212
5% .0064652 .002039
10% .0078351 .0022063 Obs 41,187
25% .0106501 .0023181 Sum of Wgt. 41,187

50% .0145226 Mean .0151535
Largest Std. Dev. .0060212
75% .018957 .0410298
90% .0232855 .0423272 Variance .0000363
95% .0260129 .0429791 Skewness .573504
99% .0315491 .0431718 Kurtosis 3.174497

. *查看最大相似度描述性统计
. summarize max_similarity, detail
max_similarity
-------------------------------------------------------------
Percentiles Smallest
1% .566003 .3102426
5% .6279272 .3372106
10% .6633787 .3501289 Obs 41,187
25% .7301425 .3673398 Sum of Wgt. 41,187

50% .8161867 Mean .8236289
Largest Std. Dev. .1225668
75% .94531 1
90% .9939191 1 Variance .0150226
95% .9984688 1 Skewness -.1232839
99% 1 1 Kurtosis 2.12262

. *查看最小相似度描述性统计
. summarize min_similarity, detail
min_similarity
-------------------------------------------------------------
Percentiles Smallest
1% -.2540156 -.4333508
5% -.192361 -.4333508
10% -.1627325 -.4326484 Obs 41,187
25% -.1244975 -.4326484 Sum of Wgt. 41,187

50% -.0941637 Mean -.1053932
Largest Std. Dev. .0439186
75% -.0745706 -.0296279
90% -.0628191 -.0296218 Variance .0019288
95% -.0572771 -.0287106 Skewness -1.664787
99% -.0482183 -.0284858 Kurtosis 7.269679

由于余弦相似度矩阵的维数一般比较大 (DxD),因此将其存储在 Mata 中。如果需要,可以在 lsemantica_cosine 命令后使用 getmata (cosin_*) = cosine_sim 从 Mata 中检索完整的余弦相似矩阵。当然,也可以将其储存为 mata 文件,以便下次读取使用。

. *在 Stata 中运行 Mata 命令,以下代码需要同时运行
. *Stata 中运行 Mata,保存和读取余弦相似矩阵
. mata
------------------- mata (type end to exit) ---------
: // 保存 Mata 文件
: mata matsave cosine cosine_sim, replace
(saving cosine_sim[41187,41187])
file cosine.mmat saved

: // Mata 读取文件
: mata matuse cosine, replace
(loading cosine_sim[41187,41187])
: end
-----------------------------------------------------

此外,lsemantica_cosine 可以为数据中的每一篇文章找到最相似的文章。在这个例子中,计算了 10 篇最相似的文章。然后,列出数据中第一篇文章的五个最相似的文章标题。可以看到,LSA 准确地识别了所有讨论劳动力供应问题的高度相似的文章。

. list most_similar_* cosine_most_similar_* if _n ==1

+---------------------------------------------------------------------------++
| 28468 | 513 | 6288 | 27267 | 34267 | 26707 | 38850 | 29322 | 29305 | 38932 |
+----------------------------------------------------------------------------+

. list title if _n==1 | _n==28468 | _n==513 | _n==6288 | _n==27267 | _n==34267

+----------------------------------------------------------------------+
| title
| ----------------------------------------------------------------------
| 1.| What Is Labor Supply and Do Taxes Affect It?
| 513.| Family Labor Supply with Taxes
| 6288. | The Effect of Taxes on Labor Supply in the Underground Economy
| 27267.| Low-Skilled Immigration and the Labor Supply of Highly Skilled Women
| 28468.| Labor Supply and Taxes: A Survey
| 34267.| Worktime Regulations and Spousal Labor Supply
+----------------------------------------------------------------------+

lsemantica 可以计算与原始文章高度相似的文章数量。在这个例子中,选择了余弦相似度为 0.7 5的截止值,通过 Mata 代码生成一个名为 high_sim_articles 的新变量,即余弦相似度大于 0.75 的文档的数量。

. sort pub_year
. mata
----------------- mata (type end to exit) ----------------
: pub_year = st_data(., "pub_year")

: high_sim_paper= J(0,1,.)

: for (y=1980 ; y<=2016 ; y++){
> cosine_submat = select(cosine_sim, pub_year:==y)
> cosine_submat = select(cosine_submat',pub_year:>=y)'
> high_sim = rowsum(( cosine_submat:>=J(rows(cosine_submat),
> cols(cosine_submat), 0.75) ))
> high_sim_paper = high_sim_paper \ high_sim

: var = st_addvar("double", "high_sim_paper")
: st_store(., "high_sim_paper", high_sim_paper)
: end
----------------------------------------------------------

对引用数量和高相似文章数量的回归分析表明,两个变量之间存在显著的正相关关系,即高相似文章数量越多的文章越多文章引用。

. reg citations high_sim_paper i.pub_year

Source | SS df MS Number of obs = 41,182
-------------+---------------------------------- F(37, 41144) = 79.43
Model | 34007739.4 37 919128.091 Prob > F = 0.0000
Residual | 476071505 41,144 11570.861 R-squared = 0.0667
-------------+---------------------------------- Adj R-squared = 0.0658
Total | 510079244 41,181 12386.2763 Root MSE = 107.57

--------------------------------------------------------------------------------
citations | Coef. Std. Err. t P>|t| [95% Conf. Interval]
---------------+----------------------------------------------------------------
high_sim_paper | -.0244854 .4637143 -0.05 0.958 -.9333754 .8844046
pub_year |
1981 | 18.96915 15.03021 1.26 0.207 -10.49039 48.4287
(output omitted)
2016 | -44.62202 10.75611 -4.15 0.000 -65.70423 -23.53981
_cons | 48.41729 10.50983 4.61 0.000 27.81779 69.0168
--------------------------------------------------------------------------------

最后,lsemantica 可以比较词语的语义关系和相似度。使用lsemantica_word_comp,可以导入 lsemantica 存储的 “单词-成分” 矩阵。同样,lsemantica 余弦可以用于计算数据中单词之间的余弦相似度,以找到最相似的单词。例如,在下例中,lsemantica 识别出 “division”、“force”、“frictional”、“labor”、“monopsony” 和“segemented” 这几个词是相互关联的。

. lsemantica_word_comp using "word_comp.mata"
. lsemantica_cosine component_1-component_300, ///
> find_similar(10) find_similar_cosine(10)
. list most_similar_* if _n ==1516, noheader table

+------------------------------+-----------------------------+
| 1768 812 1144 2465 1111 291 1394 1309 2253 2232 |
+------------------------------------------------------------+

. list word if _n==1516 | _n==812 | _n==1144 | _n==2465 | _n==1111 | _n==1768

+--------------------+
| | words |
| ----- |------------|
| 812. | division |
| 1111. | force |
| 1144. | frictional |
| 1516. | labor |
| 1768. | monopsony |
| 2465. | segmented |
+--------------------+

3.2 中文实例-计算 MD&A 相似度

本实例仅分析平安银行 (证券代码 000001) 2001-2019 年的管理层讨论与分析的文本 (MD&A) 数据。同样,在 LSA 之前进行文字清洗,仅保留中文。

. use "https://gitee.com/arlionn/data/raw/master/
> data01/lsemantica/MD_A.dta", clear
. gen text_strings = mda
. *仅保留中文字符
. replace text_strings=ustrregexra(text_strings,"[^\u4e00-\u9fa5]+"," ")
. *去除中文数字
. replace text_strings=ustrregexra(text_strings,"[一二三四五六七八九十]+"," ")

由于中文和英文单词不同,没有空格用于区分各个单词,故这里需要在 Stata 中调用 Python 中的 jieba 库,对文本进行分词。

*调用python进行中文分词
python
import jieba
from sfi import Data
import pandas as pd
dct = Data.getAsDict('Symbol text_strings')
txtdf =pd.DataFrame(dct)
txtdf['text_strings']=txtdf['text_strings'].apply(lambda x:" ".join(jieba.cut(x, cut_all=False)))
from sfi import Data
Data.setObsTotal(len(txtdf))
Data.addVarStr("text",100)
Data.store("text",None,txtdf['text_strings'],None)
end

接着进行 LSA 分析,先计算 “文档-词汇” 矩阵,由于本示例中只有 19 条文本,词汇量较少,故只能提取出较少成分,否则在 SVD 分解过程中会报错,故这里 components(15)。同时纳入计算的词汇标准也降低,最小字符长度定义为 1,词频范围 0~1。

. lsemantica text, components(15) min_char(1) ///
> min_freq(0) max_freq(1)
*计算向量间余弦相似度
. lsemantica_cosine component_1-component_10, ///
> mean_cosine min_cosine max_cosine find_similar(5) ///
> find_similar_cosine(5)
. list most_similar_* if _n ==1, noheader
+------------------------------------------------------+
1. | 2 3 4 8 9 |
+------------------------------------------------------+

. list Year if _n==1 | _n==2 |_n==3 |_n==4 |_n==2 |_n==8

+-------------+
| | Year |
| ---- |------|
| 1. | 2001 |
| 2. | 2002 |
| 3. | 2003 |
| 4. | 2004 |
| 8. | 2008 |
+-------------+

从 Mata 中获取余弦相似度矩阵,生成变量 cosin_1-cosin_19,分别表示与 2001~2019 年管理层讨论与分析文本的相似度。通过循环构建变量 Similarity 表示与上一年年报中管理层讨论与分析文本的相似度,并查看其描述性统计。

. getmata (cosin_*) = cosine_sim
. gen Similarity=.
. foreach num of numlist 1/19 {
. replace Similarity=cosin_`num' if _n==(`num'+1)
}

. summarize Similarity,detail

Similarity
-------------------------------------------------------------
Percentiles Smallest
1% .0898155 .0898155
5% .0898155 .1218855
10% .1218855 .2486546 Obs 18
25% .4395948 .3753533 Sum of Wgt. 18

50% .7880501 Mean .689412
Largest Std. Dev. .3095546
75% .9507129 .9534972
90% .9966181 .995663 Variance .095824
95% .9967352 .9966181 Skewness -.7702948
99% .9967352 .9967352 Kurtosis 2.224078

4. 相关推文

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

  • 专题:文本分析-爬虫
    • textfind:文本分析之词频分析-TF-IDF
    • Stata文本分析之-tex2col-命令-文字变表格
    • Stata爬虫-正则表达式:爬取必胜客
    • Python爬虫: 《经济研究》研究热点和主题分析
    • Stata: 正则表达式和文本分析
  • 专题:Python-R-Matlab
    • Python: 使用正则表达式从文本中定位并提取想要的内容


🍓 课程推荐:2024 机器学习与因果推断专题
主讲老师:司继春 (上海对外经贸大学) ;张宏亮(浙江大学)
课程时间:2024 年 11 月 9-10 日 ;16-17日
课程咨询:王老师 18903405450(微信)

尊敬的老师 / 亲爱的同学们:

连享会致力于不断优化和丰富课程内容,以确保每位学员都能获得最有价值的学习体验。为了更精准地满足您的学习需求,我们诚挚地邀请您参与到我们的课程规划中来。请您在下面的问卷中,分享您 感兴趣的学习主题或您希望深入了解的知识领域 。您的每一条建议都是我们宝贵的资源,将直接影响到我们课程的改进和创新。我们期待您的反馈,因为您的参与和支持是我们不断前进的动力。感谢您抽出宝贵时间,与我们共同塑造更加精彩的学习旅程!https://www.wjx.cn/vm/YgPfdsJ.aspx# 再次感谢大家宝贵的意见!

New! Stata 搜索神器:lianxh 和 songbl  GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
  . ssc install lianxh
  . ssc install songbl
👉  使用:
  . lianxh DID 倍分法
  . songbl all

🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。

连享会
连玉君老师团队分享,主页:lianxh.cn。白话计量,代码实操;学术路上,与君同行。
 最新文章