Stata连享会 主页 || 视频 || 推文 || 知乎 || Bilibili 站
温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。
New!
lianxh
命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc
,ihelp
,rdbalance
,gitee
,installpkg
⛳ Stata 系列推文:
作者:王卓 (合肥工业大学)
邮箱:2020171526@mail.hfut.edu.cn
目录
文本分析目前是经济金融领域炙手可热的研究工具,这种非结构化数据 (unstructured data) 能够为金融学领域提供更丰富的研究内容和研究视角。已有大量文献通过文本挖掘的方式,将非标准数据转化为可量化的指标,对非传统领域的经济现象展开研究。但是直接的文本不属于计算机可读语言,必须将文本转化为特征数值输入才可以对文本进行进一步分析。这篇文章针对文本“数值化”的方法之一 Word2Vec 进行简要介绍和简单的案例操作。
Word2Vec 模型由谷歌于 2013 年创建,是一种无监督的,基于预测性深度学习的模型 (其实并不深度),主要用于计算和生成高质量、分布式和连续稠密向量表示的词汇,以捕获上下文和语义的相似度。该模型可以吸收大量文本语料库,创建可能的词汇表,并为代表该词汇表的向量空间中的每个单词生成稠密的词嵌入 (Embedding)。
为了更好的理解 Word2Vec 的特点和优势,这部分主要从词向量,Word2Vec 模型两大方面进行简单介绍。
词向量,简单的说就是将文字这种人类语言转化为计算机可理解的语言。这个过程就是把语言这种符号信息转化为向量形式的数字信息,即将自然语言问题转换为机器学习的问题。主流的词向量主要有独热编码 (one-hot Representation) 模型和分布式表征 (distributed representation) 模型。
独热编码:是用一个很长的向量来表示一个词,向量长度为词典的大小 N。每个向量中数值为 1,表示该词语在词典的位置,向量其余维度全部为 0。
例如,我们需要分析的文本有两句话:“你今天学习了吗”和“你论文写完了吗”。在去除停用词 (即一些没有实际含义的虚词) 后,第一句话里有“你”、“今天”、“学习”三个词,第二句话里有“你”、“论文”、“写”三个词,此时我们的词典里共有 5 个词,即词典大小为 5。
独热编码后,“你”可以表示为 [1,0,0,0,0],“学习”可以表示为 [0,0,1,0,0]。不难理解,第一句话词向量可以表示为 [1,1,1,0,0],第二句可以表示为 [1,0,0,1,1]。两个向量均出现 1 的位置即代表“你”。
虽然这种编码方式简洁、易理解,但当词点大小 N 太大时,在文本语言模型构建时会出现“维度灾难”,而且每个词都是独立的,考虑不到上下文词汇的相关性。
分布式表征:其核心思想是词语的语义是通过上下文信息来确定的,即相同语境出现的词,其语义也相近。也就是说该模型最大的贡献就是让相关或者相似的词,在距离上更接近了。
具体来说,不同于独热编码的稀疏表示,分布式表征是一种固定长度的稠密词向量。一般形式如 [0.618, −0.401, −0.401, 0.419, …]。分布式表征词向量编码一定程度上解决了独热编码忽略词汇上下文的问题,而且词典的长度是固定的,也避免了词向量维度过大导致的计算问题。
本文介绍的 Word2Vec 模型是生成分布式表征词向量模型的方式之一 (其他生成方式还有 LSA 矩阵分解模型、PLSA 潜在语义分析概率模型、LDA 文档生成模型等)。看不懂,没关系。总的来说就是分布式表征可以做到算的又快又好,而 Word2Vec 正好可以产生分布式表征的词向量。
Word2Vec 的含义就如他的名字所示:将词转化为向量。其过程大致是将 word 映射到一个新的空间中,并以多维的连续实数向量进行表示,这叫做词嵌入 (Word Represention 或 Word Embedding)。
一般的机器学习或深度学习模型中,我们训练的样本一般都有输入值
Word2vec 作为语言模型的一种,虽然他最终目的不是训练一个完美的
Skip-gram 即跳词模型,训练时词汇
从
需要提到一点的是,这个词向量的维度 (与隐含层节点数一致) 一般情况下要远远小于词语总数的大小,所以 Word2vec 本质上是一种降维操作,即把词语从 one-hot encoder 形式的表示降维到 Word2vec 形式的表示。
例如,小明不小心打翻墨水,遮住了书中的部分文字。其中有一段文字变成了:
深蓝的___中挂着一轮金黄的___,下面是海边的___,都种着一望无际的碧绿的___,其间有一个十一二岁的少年,项带银圈,手捏一柄钢叉,向一匹猹尽力的刺去,那猹却将身一扭,反从他的胯下逃走了。这少年便是闰土。
小明想用本文分析的方法来填空。他用一个通过鲁迅全部作品训练好的 Word2Vec 模型,分别将“深蓝”、“金黄”、“海边”、“碧绿”输入进去,对于“深蓝”,模型会分别输出“天空”和一系列模型预测可能相关的词汇,以及这些词汇的相似度数值。如下图:
CBOW (continuous bag-of-words) 的目标是根据上下文来预测当前词语的概率,且上下文所有的词对当前词出现概率的影响的权重是一样的,因此叫 continuous bag-of-words 模型。与 Skip-gram 模型不同,CBOW 输入变成了多个单词,所以要对输入进行处理,一般是求和然后平均。
总之,Word2Vec 本质上是一个语言模型,训练模型时考虑了单个词的上下文,且对词汇向量进行了降维处理。多次迭代后训练得到模型的权重向量即为 Word2Vec 的词向量。
上面的理论内容略显复杂,但其实 Word2Vec 真正应用的时候只需要调用 Python 的 gensim
库即可,安装过程如下:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gensim
import gensim
为了保证代码的可复现性,本案例利用《红楼梦》展示 Word2Vec 的基础应用。红楼梦 TXT 下载地址为 地址1 和 地址2。
# -*- coding: utf-8 -*-
"""
Created on May 01 2022
@author: ZoeWang
"""
# 导入第三方库
import jieba
import re
import numpy as np
from sklearn.decomposition import PCA
import gensim
from gensim.models import Word2Vec
import matplotlib.pyplot as plt
import matplotlib
# 数据预处理
f = open(r"hongloumeng.txt",encoding='utf-8')
lines = []
for line in f:
temp = jieba.lcut(line)
words = []
for i in temp:
# 去除不必要字符
i = re.sub("[\s+\.\!\/_.$%^*(++\"\'“”《》]+|[+——!,。?、\
~·@#¥%……&* ( ) '------------';:‘]+","",i)
if len(i) > 0:
words.append(i)
if len(words) > 0:
lines.append(words)
print(lines[:3]) # 展示前三段的分词结果
[['第一回', '甄士隐', '梦幻', '识通灵', '贾雨村', '风尘', '怀', '闺秀'],
['此', '开卷', '第一回', '也', '作者', '自云', '因曾', '历过', '一番',
'梦幻', '之后', '故', '将', '真事', '隐去', '而', '借', '通灵', '之',
'说', '撰此', '石头记', '一书', '也', '故曰', '甄士隐', '云云', '但书',
'所记', '何事', '何人', '自又云', '今', '风尘碌碌', '一事无成', '忽',
'念及', '当日', '所有', '之', '女子', '一一', '细考', '较', '去', '觉其',
'行止', '见识', '皆', '出于', '我', '之上', '何', '我', '堂堂', '须眉',
'诚不若', '彼', '裙钗', '哉', '实愧', '则', '有余', '悔', '又', '无益',
'之大', '无可如何', '之日', '也', '当', '此', '则', '自欲', '将', '已往',
'所赖', '天恩祖', '德', '锦衣', '纨绔', '之', '时', '饫甘餍肥', '之', '日',
'背', '父兄', '教育', '之恩', '负', '师友', '规谈', '之德', '以至', '今日',
'一技无成', '半生', '潦倒', '之罪', '编述', '一集', '以告', '天下人', '我',
'之', '罪固', '不免', '然', '闺阁', '本自', '历历', '有人', '万', '不可',
'因', '我', '之', '不肖', '自护己', '短', '一并', '使', '其', '泯灭',
'也', '虽', '今日', '之茅', '椽蓬', '牖', '瓦灶', '绳床', '其', '晨夕',
'风露', '阶柳庭花', '亦', '未有', '妨', '我', '之', '襟怀', '笔墨',
'者', '虽', '我', '未学', '下笔', '无', '又', '何妨', '用', '假语',
'村言', '敷', '演出', '一段', '故事', '来', '亦可', '使', '闺阁', '昭传',
'复可悦', '世之目', '破人', '愁闷', '不', '亦', '宜乎', '故曰', '贾雨村', '云云'],
['此回', '凡用', '梦', '用', '幻', '等', '字', '是', '提醒', '阅者', '眼目',
'亦', '是', '此书', '立意', '本旨']]
# 调用 Word2Vec 建立模型
# 常用参数
# vector_size: 词向量的维度;
# window: 上下文窗口长度;
# min_count: 少于该字段的次数的单词会被丢弃
model = Word2Vec(lines, vector_size = 20, window=3, min_count=3, \
epochs=7,negative=10) # 这里为了训练速度,对参数值设置较低
# 输入一个路径,保存训练好的模型,其中./data/model目录事先要存在
model.save("./data/model/word2vec_gensim")
# 查看 “林黛玉” 的词向量
print(model.wv.get_vector("林黛玉"))
# 查看与“林黛玉”最相近的前10个词
print(model.wv.most_similar('林黛玉',topn=10))
# 查看“林黛玉”与“贾宝玉”的相似度
print(model.wv.similarity('林黛玉', '贾宝玉'))
以下结果展示了经过训练后“林黛玉”词向量表示,“林黛玉”相似度前 10 的词语,以及“林黛玉”与“贾宝玉”的相似度。
[-1.9263046 1.2421334 -1.0091485 -0.13790976 0.11818279 -2.8261106
0.6490951 -0.40219253 0.26743338 -0.75846136 0.3968666 -0.6893399
-0.39468396 0.38637197 1.9181769 -0.25307047 -0.17784327 0.5558692
0.5961813 -0.10329818]
[('宝玉', 0.9402182698249817), ('尤二姐', 0.9391377568244934), ('赵姨娘', 0.9354947209358215),
('香菱', 0.9352374076843262), ('探春', 0.9203108549118042), ('紫鹃', 0.9188699722290039),
('凤姐', 0.9174630641937256), ('湘云', 0.9170628786087036), ('雨村', 0.9147610068321228),
('拍', 0.9131830930709839)]
0.6685995
接下来,我们以更直观的画图形式展现 Word2Vec 模型结果。这里我们用到了 PCA 降维,主要是为了将多维词向量投影在二维平面上。
rawWorVec = []
word2ind = {}
for i,w in enumerate(model.wv.index_to_key): #生成序号,词语
rawWorVec.append(model.wv[w]) #词向量
word2ind[w] = i
rawWorVec = np.array(rawWorVec) #降维之前的20维数组
X_reduced = PCA(n_components=2).fit_transform(rawWorVec) #降维之后的2维数组
fig = plt.figure(figsize = (16,16))
ax = fig.gca()
ax.set_facecolor('white')
ax.plot(X_reduced[:,0],X_reduced[:,1],'.',markersize=1,alpha=0.3,color='black')
words = ['紫鹃','香菱','王熙凤','林黛玉','贾宝玉'] # 绘制单个词汇的向量
zhfont1 = matplotlib.font_manager.FontProperties(fname='C:\\Windows\\Fonts\\simhei.ttf',size=10)
for w in words:
if w in word2ind:
ind = word2ind[w]
xy = X_reduced[ind]
plt.plot(xy[0],xy[1],'.',alpha=1,color='green',markersize=10)
plt.text(xy[0],xy[1],w,alpha=1,color='blue',fontproperties=zhfont1)
下图展示了词向量可视化的结果,不难发现相似度高的词语距离比较近
Note:产生如下推文列表的 Stata 命令为:
lianxh 文本 机器, m
安装最新版lianxh
命令:
ssc install lianxh, replace
免费公开课
最新课程-直播课
专题 | 嘉宾 | 直播/回看视频 |
---|---|---|
⭐ 最新专题 | 文本分析、机器学习、效率专题、生存分析等 | |
研究设计 | 连玉君 | 我的特斯拉-实证研究设计,-幻灯片- |
面板模型 | 连玉君 | 动态面板模型,-幻灯片- |
面板模型 | 连玉君 | 直击面板数据模型 [免费公开课,2小时] |
⛳ 课程主页
⛳ 课程主页
关于我们
课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法
等
连享会小程序:扫一扫,看推文,看视频……
扫码加入连享会微信群,提问交流更方便
✏ 连享会-常见问题解答:
✨ https://gitee.com/lianxh/Course/wikis
New!
lianxh
和songbl
命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh