最近看了一篇NDSS会议上的一篇论文,有关web安全方向和nlp方向的,论文题目为《Game of Missuggestions: Semantic Analysis of Search-Autocomplete Manipulations》。正好自己也想学学nlp。为将来毕业做准备。。。
也算一个小白。。看到论文使用了词向量word2vec算法,便去研究了一下算法原理。
看了很多中英文博客,以及别人推荐的一篇很好的论文《word2vec Parameter Learning Explained》。
word2vec网上资料一大堆,,就不详细赘述了。
之后看完原理就小小实战了一下。python 有一个库gensim 可以直接调用进行训练模型。
选取了wiki的中文语料库进行训练。
数据下载地址为 : https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2
之后便需要进行数据预处理了。使用gensim.Wikicorpus()函数可以处理上述数据。之后i使用get_texts函数可以将语料库中的一篇文章转为text文本格式的一行方便处理。具体使用方法可以参考官方文档。
import logging
from gensim.corpora import WikiCorpus
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
logging.info("------------ the program is running -------------")
path_to_wiki_dump = "C:/nlp/gensim_demo/demo_data/zhwiki-latest-pages-articles.xml.bz2"
wiki_corpus = WikiCorpus(path_to_wiki_dump, dictionary={})
num = 0
with open('wiki_text.txt', 'w', encoding='utf-8') as output:
for text in wiki_corpus.get_texts(): # get_texts() 将 wiki的一篇文章转为textd的一行
output.write(' '.join(text) + '\n')
num += 1
if num % 10000 == 0:
logging.info("已处理 %d 文章" % num)
if __name__ == '__main__':
main()
将数据转为text的时候,发现是繁体字居多,这个时候可以使用opencc 工具来进行转为简体字。
转为简体字后需要进行分词处理更方便word2vec来训练模型。分词采用了jieba分词。
import jieba
import logging
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
stopword_set = set()
output = open('wiki_seg.txt', 'w', encoding='utf-8')
with open('wiki.zh.jian.txt', 'r', encoding='utf-8') as content:
for texts_num, line in enumerate(content): # enumerate 给 line前加序号
line = line.strip('\n')
words = jieba.cut(line, cut_all=False)
for word in words:
if word not in stopword_set:
output.write(word + ' ')
output.write('\n')
if (texts_num + 1) % 10000 == 0:
logging.info("已完成前 %d 行的断词" % (texts_num + 1))
output.close()
if __name__ == '__main__':
main()
分词结束后,就可以开始进行训练模型了。
from gensim.models import word2vec
import logging
def main():
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.LineSentence("wiki_seg.txt")
model = word2vec.Word2Vec(sentences, size=250, min_count=5) # size 用来设置神经网络的层数
model.save("chinese_wiki_word2vec.model")
if __name__ == "__main__":
main()
训练好模型后,将其保存。
加载模型 之后可以看到下图的训练结果。