jieba分词和word2vec词向量

计算机只能识别和计算数字,我们在处理语言文本时(不仅语言文本,要传入模型计算的数据都是数字或者向量),首要的工作是数据的预处理。最开始是One-Hot Encoder编码,很显然这没有考虑词的含义和词与词的关系。所以根据需求可以有不同的处理方式,最常见的,效果也比较好的就是词向量word2vec具体展开请看这里。
很显然,词向量分为向量。英文有天然的词分隔符空格,中文却不是,不同的断句截然不同的意思。具体中文的分词原理请看这篇文章中文分词原理,这里不过多展开。下面来详细的介绍jieba分词的工作方式。

我们的目的很清楚,把语言文本分词,然后制作成向量。

下面一步步来做:
分词,我们要想,我们根据什么来分,什么是标准?所以第一步我们要导入分词的字典,根据我们的业务场景,可以自行定义也可以导入默认的。

step1 导入字典jieba.load_userdict(filename)

在使用的时候,自定义的词典格式和jieba分词器默认的词典格式必须保持一致,即:一个词占一行,每一行分成三部分,一部分为词语,一部分为词频,最后为词性(可以省略),用空格隔开,最重要的一点要用UTF-8!。比如默认词典下:

>>> st = '李大海在上海的人民广场吃炸鸡'
>>> ge1 = jieba.cut(st)
>>> '/'.join(ge1)
'李大海/在/上海/的/人民广场/吃/炸鸡'

自定义词典(不考虑词频):

李大海 1 
人民 1 
广场 1 

导入自定义词典:

>>> jieba.load_userdict('dict.txt')
>>> eg = jieba.cut(st)
>>> '/'.join(eg)
'李大海/在/上海/的/人民广场/吃/炸鸡'

这里有个问题,顺便拓展一下。我们发现人民广场即使是我们添加了自定义的字典也分不开,这是为什么?这是因为自定义的字典只是添加,我只是添加了李大海人民广场,并没有把原来字典里的人民广场拆开。下面介绍几个方法:

  • jieba.del_word()----删除原来的词
>>> jieba.del_word("人民广场")
>>> eg = jieba.cut(st)
>>> '/'.join(eg)
'李大海/在/上海/的/人民/广场/吃/炸鸡'
  • jieba.del_word()----添加和修改词频
>>> jieba.add_word("人民广场")
>>> eg = jieba.cut(st)
>>> '/'.join(eg)
'李大海/在/上海/的/人民广场/吃/炸鸡'
>>> jieba.add_word("人民广场",0)
>>> eg = jieba.cut(st)
>>> '/'.join(eg)
'李大海/在/上海/的/人民/广场/吃/炸鸡'
  • jieba.suggest_ferq()----自行修正(推荐)
>>> jieba.suggest_freq(('人民','广场'),True)
0
>>> eg = jieba.cut(st)
>>> '/'.join(eg)
'李大海/在/上海/的/人民/广场/吃/炸鸡'
>>>

ok导入词典就介绍到这里。第二步就是分词:

step 2 分词jieba.cut()jieba.cut_for_search

  • jieba.cut()

>>> st = '李大海在上海的人民广场吃炸鸡'
# 非全模式,默认的
>>> ge = jieba.cut(st,cut_full=False)
>>> '/'.join(ge)
'李大海/在/上海/的/人民/广场/吃/炸鸡'
# 全模式
>>> eg = jieba.cut(st,cut_all=True)
>>> '/'.join(eg)
'李大海/大海/在/上海/的/人民/广场/吃/炸鸡'
>>>

全切模式是把切出来的长词再切分,长词的定义是词里面还有词儿,并不是长得长。。。

  • jieba.cut_for_search()

>>> eg = jieba.cut_for_search(st)
>>> '/'.join(eg)
'大海/李大海/在/上海/的/人民/广场/吃/炸鸡'

这个是搜索模式分词,效果和全模式的cut相似。
最后总结一下jieba的分词模式,一共是两个分词方法,三个分词模式:

  • 精确模式jieba.cut(cut_all=False),试图将句子最精确地切开,适合文本分析;
  • 全模式jieba.cut(cut_all=True),把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
  • 搜索引擎模式jieba.cut_for_search(),在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。 支持繁体分词。

最后介绍几个jieba的关键字提取方法:

>>> from collections import Counter
>>> import jieba.analyse
>>> import jieba
>>> st
'计算机只能识别和计算数字,我们在处理语言文本时(不仅语言文本,要传入模型计算的数据都是数字或者向量),首要的工作是数据 的预处理。根据需求可以有不同的处理方式,最常见的,效果也比较好的就是词向量。'
>>> eg = jieba.cut(st)
>>> ls = list(eg)
['计算机', '只能', '识别', '和', '计算', '数字', ',', '我们', '在', '处理', '语言', '文本', '时', '(', '不仅', '语言', '文本', ',', '要', '传入', '模型', '计算', '的', '数据', '都', '是', '数字', '或者', '向量', ')', ',', '首要', '的', '工作', '是', '数据', '的', '预处理', '。', '根据', '需求', '可以', '有', '不同', '的', '处理', '方式', ',', '最', '常见', '的', ',', '效果', '也', '比较', '好', '的', '就是', '词', '向量', '。']
>>> Counter(ls)
Counter({'的': 6, ',': 5, '计算': 2, '数字': 2, '处理': 2, '语言': 2, '文本': 2, '数据': 2, '是': 2, '向量': 2, '。': 2, '计算机': 1, '只能': 1, '识别': 1, '和': 1, '我们': 1, '在': 1, '时': 1, '(': 1, '不仅': 1, '要': 1, '传入': 1, '模型': 1, '都': 1, '或者': 1, ')': 1, '首要': 1, '工作': 1, '预处理': 1, '根据': 1, '需求': 1, '可以': 1, '有': 1, '不同': 1, '方式': 1, '最': 1, '常见': 1, '效果': 1, '也': 1, '比较': 1, '好': 1, '就是': 1, '词': 1})
>>> jieba.analyse.extract_tags(st,8)
['向量', '文本', '数字', '语言', '计算', '处理', '预处理', '数据']

可以看到这个方法基本是根据词频来筛选关键字的,但是出去了一些常用的Stop Word(停用词)可以使用jieba.analyse.set_stop_words(file_name)这个方法来自定义停用词,自定义文本是每个词独占一行。

>>> jieba.analyse.textrank(st,8)
['计算', '数据', '数字', '文本', '语言', '传入', '处理', '预处理']

这个方法考虑了词与词的连接,等于是考虑了语意。对于jieba的关键字提取,这篇博客有比较详细实例的介绍。

step 3 分词完成了之后,就要进行词向量的制作

这里使用gensim.models模块中的word2vec模块来简易制作。gensim是一个强大的模块,具体介绍请看这里。
在分词完毕之后,如果数据量大建议写成文件保存,小的话直接可以用来制作词向量(建议都写成文件保存)。话不多说进入正题:

  • 首先需要把数据处理成gensim可以处理的格式
    • 先说最简单的一种
      直接处理成列表嵌套的方式,即:[ [分词好的第一句],[分词好的第二句],.....]。这种形式
    • word2vec.LineSentence(source, max_sentence_length=10000, limit=None)
      这个方法读取的是分词处理好的文本,文本格式为:一句话独占一行,且每句好都是分词好,由空格隔开的。
    • word2vec.PathLineSentences(source,max_sentence_length = 10000,limit = None )
      与LineSentence类一样,不过这里是处理根目录下的所有文件,每个文件的格式和LineSentence方法中的要求一样,语料库特别大的时候推荐使用这个方法,防止内存过载。
    • word2vec.Text8Corpus(fname,max_sentence_length = 10000 )
      这个方法是也是同上,文本容量很大的时候不推荐使用这个方法。

以上这些方法都是生成一个可迭代的对象,封装的内容是分词后的单词组成的列表。这几个方法的不同是,LineSentence是每行封装成一个列表,这个列表的最大长度是max_sentence_length。而Text8Corpus是对整个语料库进行分割,每次都是max_sentence_length这个长度的列表。

  • source
    可以接收一个列表(第一个方法中的格式)或者是分此后的文件路径。
  • max_sentence_length
    封装的每个列表的最大长度
from gensim.models.word2vec import LineSentence,PathLineSentences,Text8Corpus

s = [ ['你','好','吗'] ,['你','好','吗'],['你','好','吗'],['你','好','吗'] ]

s = LineSentence('\data.txt')

s = PathLineSentences('\data.txt')

s = Text8Corpus('\data.txt')

数据准备好了就可以进行下一步了:

  • 训练词向量模型
    • word2vec.Word2Vec(sentences=None, size=100, window=5, min_count=5)
      • sentences
        就是上面的准备好的数据,可以是简单的list或这个是其他几个方法生成的可迭代对象。
      • size
        生成词向量的大小,也就是特征向量的维数
      • window
        一个词上下文的最大关联距离,简单说就是考虑上下文几个词对这个词有影响
      • min_count
        忽略词频小于这个值的词

还有一些学习率等参数,不太需要调节的参数,需要的时候查官方文档

from gensim.models import word2vec
# 训练模型
model = word2vec.Word2Vec(s)
# 保存模型
model.save('lang_model')

对于训练好的模型,有一些基本操作:

# 加载模型
model = word2vec.Word2Vec.load('lang_model')
# 查看某一个词的向量(要在词典内)
print(model['你好'])
# 查看某个词关系密切的几个词
print(model.most_similar(u'你好',topn=10))
# 查看构成的词汇表
print(model.wv.vocab.keys())

到这里,我们等于是把原来的文本数据中的每一个词,制作了一个映射。而不是简单的用一个数字到代表它,更加考虑了词的含义和词与词之间的影响。不过已经可以用这个模型做许多事情了。

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

推荐阅读更多精彩内容