word2vec的实现

在目前的行业应用中我们可以使用skip-gram 和 CBOW 模型来进行此过程。在gensim中已经集成了这个算法。下面使用搜狗实验室的新闻语料集合来实现word2vector

使用的数据:搜狗实验室的搜狗新闻语料库

格式说明:

数据格式为

<doc>

<url>页面URL</url>

<docno>页面ID</docno>

<contenttitle>页面标题</contenttitle>

<content>页面内容</content>

</doc>

注意:content字段去除了HTML标签,保存的是新闻正文文本

对提取关键数据文本:语料库中提供了很多的数据项,执行cat news_sohusite_xml.dat | iconv -f gbk -t utf-8 -c | grep "<content>" > corpus.txt 可以只得到content标签的内容,得到文件名为corpus.txt的文件(注意在linux下打开),语聊的格式如下:

[图片上传失败...(image-424924-1585921968718)]

1. 数据预处理

content = ['hello,你好呀','  dadjofjaojfaTest我是英文中隐藏的汉字','如果想  d联系炼我,那就打电话:110!!!','我爱学NLP,!^-^']
# 让文本只保留汉字
def is_chinese(uchar):
    if uchar >= u'\u4e00' and uchar <= u'\u9fa5':
        return True
    else:
        return False

def format_str(content):
    content_str = ''
    for i in content:
        if is_chinese(i):
            content_str = content_str + i
    return content_str

# 参函数传入的是每一句话
chinese_list = []
for line in content:
    chinese_list.append(format_str(line))
print(chinese_list)

'''
output:['你好呀', '我是英文中隐藏的汉字', '如果想联系炼我那就打电话', '我爱学']
'''

2. 分词

中文文件直接传给word2vec是需要分词的,这样才可以较好的表达文本的意思。分词可以采用jieba分词实现。

对原始文本内容进行分词,python 程序如下:

filePath = 'D:\\ML_learning\\NLP_data\\corpus.txt'
fileSegWordDonePath = 'D:\\ML_learning\\NLP_data\\corpusSegDone.txt'
fileTrainRead = pd.read_csv(filePath)
fileTrain = pd.Series(fileTrainRead.iloc[:,0])
f = lambda x: x[9:-11]
fileTrain = fileTrain.apply(f)

fileTrain.dropna(how='any')

fileTrainSeg = []
for line in fileTrain:
    data = jieba.cut(line, cut_all=False)
    # print(list(data))
    fileTrainSeg.append(" ".join(list(data)))

output_list = pd.Series(fileTrainSeg)
output_list.to_csv(fileSegWordDonePath, encoding='utf-8')

可以使用Pandas的特性快速批量的对数据进行格式化:

  • 使用pd.apply() 来对每行数据进行处理, 一句语句就可以删除所有string的起始的<content> 和结尾的</content>
  • 使用dropna 来去除数据为空的行
  • 上面的代码中,pandas的Series是一种类似于一维数组的对象,由一组数据和一组与之相关的数据标签(索引)组成,比如:

    pd.Series(0,index=['a','b','c'])
    '''
    执行结果:
    a    0
    b    0
    c    0
    '''
    
  • jieba分词有三种模式:全模式、精确模式、搜索引擎模式。全模式和精确模式通过jieba.cut实现

    # 全模式
    seg_list = jieba.cut("他来到苏州了", cut_all=True)
    print("【全模式】:" + "/ ".join(seg_list))  
    '''
    【全模式】:他/ 来到/ 苏州/ 了
    '''
    

3. 构建词向量

from gensim.models import word2vec
import pandas as pd

mopdelfilePath = 'D:\\ML_learning\\NLP_data\\model.bin'
fileSegWordDonePath = 'D:\\ML_learning\\NLP_data\\corpusSegDone.txt'

fileTrainRead = pd.read_csv(fileSegWordDonePath)
train_sentences = pd.Series(fileTrainRead.iloc[:, 1])
f = lambda x: str(x).split(" ")
train_sentences = train_sentences.apply(f)

model = word2vec.Word2Vec(train_sentences, size=300)
model.save(mopdelfilePath)

上面的代码将读入分词文件,并将其传入到word2vec中用来构建词向量,最后将构建出来的词向量保存。这里我们设置word2vec创建300维的词向量。

Word2Vec 参数:

  • min_count
model = Word2Vec(sentences, min_count=10) # default value is 5

在不同大小的语料集中,我们对于基准词频的需求也是不一样的。譬如在较大的语料集中,我们希望忽略那些只出现过一两次的单词,这里我们就可以通过设置min_count参数进行控制。一般而言,合理的参数值会设置在0~100之间。

  • size
model = Word2Vec(sentences, size=200) # default value is 100

size参数主要是用来设置神经网络的层数,Word2Vec 中的默认值是设置为100层。更大的层次设置意味着更多的输入数据,不过也能提升整体的准确度,合理的设置范围为 10~数百。

  • workers
model = Word2Vec(sentences, workers=4) # default = 1 worker = no parallelization

workers参数用于设置并发训练时候的线程数,不过仅当Cython安装的情况下才会起作用:

4. 显示并使用词向量

from gensim.models import word2vec
mopdelfilePath = 'D:\\ML_learning\\NLP_data\\model.bin'
model = word2vec.Word2Vec.load(mopdelfilePath)
print(model.wv['中国'])

可以得到如下结果(300维的一个向量):

[ 2.2904966 -2.2582266 -2.7562246 1.2342433 2.717599 1.377568
2.720106 0.9635297 -1.6690013 1.2432543 2.7351687 2.4857194

....

0.6931309 -1.1371846 -0.8067352 2.2179334 -1.1542435 1.1875417
0.76617193 1.3922322 -2.2338731 0.97370434 1.9159969 -1.706138 ]

保存 and 加载词向量的三种不同格式:

  1. 以model.save()方法保存词向量(上面用的方法)
  • model.save(mopdelfilePath)
  • word2vec.Word2Vec.load(model)
  1. 保存为二进制的词向量
  • model.wv.save_Word2Vec_format(embedding_path,binary=True)
  • model.wv.save_Word2Vec_format(embedding_path,binary=False)
  • gensim.models.KeyedVectors.load_word2vec_format(embedding_path,binary=True)
  1. 使用numpy进行保存和加载

    保存数组数据的文件可以是二进制格式或者文本格式,二进制格式的文件可以是Numpy专用的二进制类型和无格式类型

5. 查看词表中的词

from gensim.models import word2vec
mopdelfilePath = 'D:\\ML_learning\\NLP_data\\model.bin'
model = word2vec.Word2Vec.load(mopdelfilePath)
index = 1000
print (model.wv.index2word[1000])

得到结果如下:

存款

可以得到词表中第1000个词为: 存款

model.wv['sky']: 表示输出sky这个词的特征映射结果

model.wv.index2words: 输出经过映射后的特征名,输出经过映射词的名字

6. 显示空间距离相近的词

一个好的词向量可以实现词义相近的一组词在词向量空间中也是接近的,可以通过显示词向量空间中相近的一组词并判断它们语义是否相近来评价词向量构建的好坏:

from gensim.models import word2vec
mopdelfilePath = 'D:\\ML_learning\\NLP_data\\model.bin'
model = word2vec.Word2Vec.load(mopdelfilePath)
 
indexes = model.wv.most_similar_cosmul('中国')
for index in indexes:
    print(index)

得到的结果如下 与给定词最相近的词以及相似度:

('我国', 0.8150987029075623)
('亚洲', 0.794571578502655)
('印度', 0.7809259295463562)
('国内', 0.7792256474494934)
('日本', 0.7718893885612488)
('美国', 0.7644745707511902)
('全球', 0.7569549083709717)
('本国', 0.7533475160598755)

model.wv.most_similar_cosmul使用余弦相似度来度量各个单词之前的相似度

7. 查找异类词

model.wv.doesnt_match(['中国','美国','叙利亚','水果'])

上面的输出如下:

'水果'

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容