赞
踩
中文的词向量训练和英文的差不多,输入数据的格式都一样,均需要可迭代的句子列表。但有一点需要注意的是,在英文句子里,单词之间自然地就很清楚哪个是哪个单词了,而中文句子则不然,计算机需要知道哪个部分称之为一个“词”。
所以,中文词向量的训练关键在于分词的处理。通常使用jieba分词工具库来对语料库进行处理。下面来看一些简单例子:
- import os
-
- # jieba分词库
- import jieba
- import jieba.analyse
-
- # gensim词向量训练库
- from gensim.test.utils import common_texts, get_tmpfile
- from gensim.models import Word2Vec
- from gensim.models import word2vec
- with open('./倚天屠龙记.txt', encoding='utf-8') as f1:
-
- document = f1.read() # 一行一行地读取小说文本的句子
-
- document_cut = jieba.cut(document, cut_all=False) # 分词
-
- result = ' '.join(document_cut).replace(',', '').replace('。', '').replace('?', '').replace('!', '') \
- .replace('“', '').replace('”', '').replace(':', '').replace(';', '').replace('…', '').replace('(', '').replace(')', '') \
- .replace('—', '').replace('《', '').replace('》', '').replace('、', '').replace('‘', '') \
- .replace('’', '') # 词与词之间用空格隔开并去掉标点符号
-
- with open('./倚天屠龙记_segment.txt', 'w', encoding="utf-8") as f2:
-
- f2.write(result) # 得到分词之后的文本语料库
- #加载语料
- sentences = word2vec.LineSentence('./倚天屠龙记_segment.txt')
- #创建临时文件
- path = get_tmpfile("word2vec_1.model")
- #训练语料
- model_1 = word2vec.Word2Vec(sentences, sg=1, vector_size=100, negative=3, sample=0.001, hs=1, window=5, min_count=1, workers=4)
这里说一下相关参数:
1. sentences:预处理后的训练语料库。是可迭代列表,但是对于较大的语料库,可以考虑直接从磁盘/网络传输句子的迭代。
2. sg:skip-gram算法,对低频词敏感;默认sg=0为CBOW算法。
3. vector_size(int) :是输出词向量的维数,默认值是100。这个维度的取值与我们的语料的大小相关,比如小于100M的文本语料,则使用默认值一般就可以了。如果是超大的语料,建议增大维度。值太小会导致词映射因为冲突而影响结果,值太大则会耗内存并使算法计算变慢,一般值取为100到200之间,不过见的比较多的也有300维的。
4. window(int):是一个句子中当前单词和预测单词之间的最大距离,window越大,则和某一词较远的词也会产生上下文关系。默认值为5。window越大所需要枚举的预测此越多,计算的时间越长。
5. min_count:忽略所有频率低于此值的单词。默认值为5。
6. workers:表示训练词向量时使用的线程数,默认是当前运行机器的处理器核数。
还有关采样和学习率的,一般不常设置:
1. negative和sample可根据训练结果进行微调,sample表示更高频率的词被随机下采样到所设置的阈值,默认值为1e-3。
2. hs=1表示分层softmax将会被使用,默认hs=0且negative不为0,则负采样将会被选择使用。
- # 输出和“张三丰”最相似的前10个词和相似度度量
- for key in model_1.wv.similar_by_word('张三丰', topn=10):
- print(key)
- # 任意查看两个词之间的相似度大小
- model_1.wv.similarity('周芷若', '赵敏')
THUCNews是根据新浪新闻RSS订阅频道2005~2011年间的历史数据筛选过滤生成,包含74万篇新闻文档(2.19 GB),均为UTF-8纯文本格式。包含财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐14个领域。
下载好的数据集文件如下:
例如财经领域中的某篇新闻报道:
每个领域下面都有若干这样的txt文本数据。所以现在需要做的第一步就是如何把这些分散开的语料喂入模型中。
- # 读取一个目录下的所有文件
- class MySentences(object):
- def __init__(self, dirname):
- self.dirname = dirname
-
- def __iter__(self):
- for fname in os.listdir(self.dirname):
- for line in open(os.path.join(self.dirname, fname), encoding='utf-8'):
- yield line.split()
拿财经领域的数据来演示:
- # 针对THUCNews数据集的财经领域
- File = './THUCNews/财经'
- files = os.listdir(File) # 得到该文件夹下的所有文件名(包含后缀),输出为列表形式
- for file in files:
- with open(File + '/' + file, encoding='utf-8') as f1:
-
- # 对每个文档的内容进行分词
- document = f1.read()
- document_cut = jieba.cut(document, cut_all=False)
-
- # 分词之后用空格隔开并去掉标点符号
- result = ' '.join(document_cut).replace(',', '').replace('。', '').replace('?', '').replace('!', '') \
- .replace('“', '').replace('”', '').replace(':', '').replace(';', '').replace('…', '').replace('(', '').replace(')', '') \
- .replace('—', '').replace('《', '').replace('》', '').replace('、', '').replace('‘', '') \
- .replace('’', '')
-
- # 处理好的语料文档的路径
- datapath = './财经/' + file
- with open(datapath, 'w', encoding="utf-8") as f2:
- f2.write(result)
- # 利用自定义的读取一个文件夹下所有文件的函数来加载语料
- sentences = MySentences('./财经')
- #创建临时文件
- path = get_tmpfile("word2vec_2.model")
- #训练语料
- model_2 = word2vec.Word2Vec(sentences, window=5, min_count=1, workers=4)
- # 任意查看与某个词最相似的前5个词语及相似度度量
- for key in model_2.wv.similar_by_word('中国银行', topn=5):
- print(key)
在已经获取模型的前提下可以进行:
1. 获取每个词的词向量
model['词语']
2. 支持词语的加减运算(实际中可能只有少数例子比较符合)
model.most_similar(positive=['woman', 'king'], negative=['man'])
3. 计算两个词之间的余弦距离
model.wv.similarity("好", "还行")
4. 计算余弦距离最接近“word”的10个词,或topn个词
model.most_similar("word")
model.wv.similar_by_word('词语', topn =100) 最接近的100个词
5. 计算两个集合之间的余弦似度
当出现某个词语不在这个训练集合中的时候,会报错
list_sim1 = model.n_similarity(list1, list2)
6. 选出集合中不同类的词语
model.doesnt_match("breakfast cereal dinner lunch".split())
更多方法及版本迁移可以参考gensim的官方文档。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。