NLP(4) | 用词向量技术简单分析红楼梦人物关系用n-gramma生成词向量word2vect进行模型训练

NLP(1) | 词向量one hot编码词向量编码思想

NLP(2) | 中文分词分词的概念分词方法分类CRFHMM分词

NLP(3)| seq to seq 模型


前言:出于种种原因,总是不自觉把爱好和工作相互结合起来,每每感叹于曹雪芹构思的巧妙,语言的精炼,情节的感人……于是蹦出想法,看机器能否读懂“宝黛”之间的爱情。

  • 数据处理

数据当然是伟大的《红楼梦》本身了,下载txt文件。

然后进行编码转化“utf-8”。 然后进行分词,去除其中大量的空格和标点,然后有两种方法进行词向量的构建,分别是n-gram模型训练和word2vect

用n-gramma生成词向量

把数据转化为如下格式:

也就是N=2

上述操作代码如下:

with open("红楼梦.txt",encoding='utf-8') as f:
    text = f.read()
# print(text)
temp = jieba.lcut(text)
words = []
# print(temp)
for i in temp:
    #过滤掉所有的标点符号
    i = re.sub("[\s+\.\!\/_,$%^*(+\"\'””《》]+|[+——!,。?、~@#¥%……&*():]+", "", i)
    if len(i) > 0:
        words.append(i)
# print(len(words))
# print(words)
trigrams = [([words[i], words[i + 1]], words[i + 2]) for i in range(len(words) - 2)]
# 打印出前三个元素看看
print(trigrams[:3])

然后建立词汇表

# 得到词汇表
vocab = set(words)
print(len(vocab))
# 两个字典,一个根据单词索引其编号,一个根据编号索引单词
#word_to_idx中的值包含两部分,一部分为id,另一部分为单词出现的次数
#word_to_idx中的每一个元素形如:{w:[id, count]},其中w为一个词,id为该词的编号,count为该单词在words全文中出现的次数
word_to_idx = {} 
idx_to_word = {}
ids = 0

#对全文循环,构件这两个字典
for w in words:
    cnt = word_to_idx.get(w, [ids, 0])
    if cnt[1] == 0:
        ids += 1
    cnt[1] += 1
    word_to_idx[w] = cnt
    idx_to_word[ids] = w

然后就是模型构建和参数训练,模型结构如下:

1、输入层:embedding层,这一层的作用是:先将输入单词的编号映射为一个one hot编码的向量,形如:001000,维度为单词表大小。 然后,embedding会通过一个线性的神经网络层映射到这个词的向量表示,输出为embedding_dim

2、线性层,从embedding_dim维度到128维度,然后经过非线性ReLU函数

3、线性层:从128维度到单词表大小维度,然后log softmax函数,给出预测每个单词的概率 具体代码可见:https://github.com/dctongsheng/n-grama-and-wordvect-Analysis-of-the-text 迭代训练

word2vect进行模型训练

训练的时候需要把数据重新进行调整,变成句子进行输入

如下: ['因此', '大家', '议定', '每日', '轮流', '做', '晚饭', '之主'], ['天天', '宰猪', '割羊', '屠鹅', '杀鸭', '好似', '临潼斗宝', '的', '一般', '都', '要', '卖弄', '自己', '家里', '的', '好', '厨役', '好', '烹调'],

数据处理的代码如下:

f = open("红楼梦.txt", encoding='utf-8')
f = f.read().split("。")
print(list(f))
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)

然后输入模型,将图像转化为二维空间进行展示

model = Word2Vec(lines, size = 20, window = 2 , min_count = 0)
renwu = model.wv.most_similar('林黛玉', topn = 20)
print(renwu)
rawWordVec = []
word2ind = {}
for i, w in enumerate(model.wv.vocab):
    rawWordVec.append(model[w])
    word2ind[w] = i
rawWordVec = np.array(rawWordVec)
X_reduced = PCA(n_components=2).fit_transform(rawWordVec)

然后绘制图像,并且展示把几个特殊人物,在图像中展现出来'贾宝玉', '林黛玉', '香菱', '贾政', '晴雯', '妙玉', '袭人', '薛宝钗', '王熙凤', '平儿', '贾母', '探春'

# 绘制所有单词向量的二维空间投影
fig = plt.figure(figsize = (15, 10))
ax = fig.gca()
ax.set_facecolor('black')
ax.plot(X_reduced[:, 0], X_reduced[:, 1], '.', markersize = 1, alpha = 0.3, color = 'white')


# 绘制几个特殊单词的向量
words = ['贾宝玉', '林黛玉', '香菱', '贾政', '晴雯', '妙玉', '袭人', '薛宝钗', '王熙凤', '平儿', '贾母', '探春']
# 设置中文字体,否则无法在图形上显示中文
zhfont1 = matplotlib.font_manager.FontProperties(fname='./华文仿宋.ttf', size=16)
for w in words:
    if w in word2ind:
        ind = word2ind[w]
        xy = X_reduced[ind]
        plt.plot(xy[0], xy[1], '.', alpha =1, color = 'red')
        plt.text(xy[0], xy[1], w, fontproperties = zhfont1, alpha = 1, color = 'yellow')
plt.show()

展示结果如下:

可以看到宝黛钗凤很相近,几乎都分不清了他们的名字了,然后放大之后,震惊……

结论:原来机器也“读懂”了“宝黛”爱情。

补充:由于以上用的数据仅仅来自于《红楼梦》文本本身,如果有另外巨大的语料(微博、人民日报、上海热线、汽车之家等,包含1366130个词向量)训练出来结果如何呢? 篇幅有限直接上结果吧,

参考:

https://cloud.tencent.com/developer/article/1180991

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
本文通过对文本人物关系、文本结构分层、作者行文风格的分析分析中文文本。 针对问题一,我们运用聚类分析和层次分析建立模型从物理结构与逻辑结构两方面来分析文本,我们提取文本中和文本标题中的人名作为特征项,用matlab编程分别统计每个人名在各个段落中的频数。通过运用主成分分析法对文本进行分析我们得出自变量与常数项几乎不相关,因此不需要采取主成分回归分析。通过系统聚类分析,我们得到了聚类图,从中得出了主演人物之间的关系。通过层次划分,我们将样本一划分为两层,样本二划分为两层,样本三划分为两层。最后通过matlab编程统计样本中虚词的频数,并且分别对样本中虚词总体和各个虚词进行统计,运用计算风格学理论,我们得出前八十回与后四十回作者的行文风格存在差异。 针对问题二,我们对聚类分析、层次划分、行文风格进行了检验。对于聚类分析的结果,我们与从对文本概述的文学概括分析得到的人物关系进行比较检验,验证了聚类分析结果是可靠性。对于层次分析,我们通过用Excel对数据做出折线图,对图形进行分析,得出与用层次分析算法得出的相同的人物关系结论。 针对问题三,我们计算了各个样本中主要人物的比重,做出了折线图,从图中我们得出了文本结构一致性的结论,体现了三个样本的相同性。通过计算同一个人物在不同样本中的频数(以黛玉为例),我们得出各个样本由于主题思想的不同主要人物也有差异。
训练中文词向量,可以使用word2vec模型进行训练,具体步骤如下: 1. 准备语料库:从中文维基百科、新闻语料库、微博等网站上下载语料,可以使用jieba等中文分词工具进行分词。得到的文本应该去除停用词、标点符号等干扰项。 2. 安装Python模块:gensim是Python中的一个自然语言处理库,它包含了Word2Vec模型的实现,安装gensim模块即可进行中文词向量训练。 3. 读入语料:利用gensim中的LineSentence读入语料库。 4. 训练模型:创建Word2Vec对象,配置参数,使用模型进行训练。 5. 保存模型:将训练好的模型保存起来,方便后续使用。 具体代码如下: ```python from gensim.models import Word2Vec from gensim.models.word2vec import LineSentence # 读入语料库 sentences = LineSentence('corpus.txt') # 配置参数,训练模型 model = Word2Vec(sentences, size=300, window=5, min_count=5, workers=4) # 保存模型 model.save('word2vec.model') ``` 在训练模型时,需要对参数进行配置,包括: - size:词向量的维度,默认值是100,但对于中文词向量,建议增加到300或更高。 - window:词向量训练时的上下文窗口大小,默认值是5,可以根据具体情况进行调整。 - min_count:指定词频阈值,小于该值的单词将被忽略,默认值为5。 - workers:训练模型时使用的线程数。 通过以上步骤,就可以训练出中文词向量,用于自然语言处理任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值