菜鸟学NLP(五)

基本文本处理技能

pic2

基于词典的分词方法(字符串匹配,机械分词方法)

基于词典的方法:字符串匹配、机械分词方法
按照扫描方向的不同:正向匹配 & 逆向匹配
按照长度的不同:最大匹配 & 最小匹配
按照是否与词性标注过程相结合:单纯分词方法 & 分词与标注相结合

正向最大匹配法

pic1
算法流程:
假设词典中最长的单词为 5 个(MAX_LENGTH),那么最大匹配的起始子串字数也为 5 个

(1)扫描字典,测试读入的子串是否在字典中

(2)如果存在,则从输入中删除掉该子串,重新按照规则取子串,重复(1)

(3)如果不存在于字典中,则从右向左减少子串长度,重复(1)

逆向最大匹配法(BMM)

算法流程:

假设词典中最长的单词为 5 个(MAX_LENGTH),那么最大匹配的起始子串字数也为 5 个

(1)扫描字典,测试读入的子串是否在字典中

(2)如果存在,则从输入中删除掉该子串,重新按照规则取子串,重复(1)

(3)如果不存在于字典中,则从左向右减少子串长度,重复(1)

事实证明逆向最大匹配法要优于正向最大匹配法

双向最大匹配法(BM)

双向最大匹配法是将正向最大匹配法得到的分词结果和逆向最大匹配法的到的结果进行比较,从而决定正确的分词方法。据SunM.S. 和 Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子,正向最大匹配法和逆向最大匹配法完全重合且正确,只有大概9.0%的句子两种切分方法得到的结果不一样,但其中必有一个是正确的(歧义检测成功),只有不到1.0%的句子,或者正向最大匹配法和逆向最大匹配法的切分虽重合却是错的,或者正向最大匹配法和逆向最大匹配法切分不同但两个都不对(歧义检测失败)。这正是双向最大匹配法在实用中文信息处理系统中得以广泛使用的原因所在。

综合考虑了正向和逆向最大匹配的结果,加入了一些启发式的规则来对分词结果进行进一步消歧的。

启发式规则:

  1. 如果正反向分词结果词数不同,则取分词数量较少的那个。
  2. 如果分词结果词数相同
    a.分词结果相同,就说明没有歧义,可返回任意一个。
    b.分词结果不同,返回其中单字较少的那个。

最短路径匹配算法

最短路径匹配算法是根据词典,找出字串中所有可能的词(也称全分词),然后构造词语切分有向无环图。这样,每一个词对应图中的一条有向边。若赋给相应的边长一个权值(该权值可以是常数,也可以是构成的词的属性值),然后针对该切分图,在起点到终点的所有路径中,求出最短路径,该最短路径上包含的词就是该句子的切分结果。最短路径匹配算法的规则是使切分处理的词数最少,符合汉语自身的语言规律。但是,同样发现在实际应用中,同样不能正确切分出许多不完全符合规则的句子。

基于统计的分词(无词典)

统计分词的主要思想是把每个词看做是由字组成的,如果相连的字在不同文本中出现的次数越多,就证明这段相连的字很有可能就是一个词。

统计分词一般做如下两步操作:
1.建立统计语言模型(n-gram)
2.对句子进行单词划分,然后对划分结果做概率计算,获取概率最大的分词方式。这里就用到了统计学习算法,如隐马尔科夫模型(HMM),条件随机场(CRF)等

n-gram

N-gram模型思想:第n个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积 。

unigram 一元分词,把句子分成一个一个的汉字
bigram 二元分词,把句子从头到尾每两个字组成一个词语
trigram 三元分词,把句子从头到尾每三个字组成一个词语.

输入的是断好词的文本,每个句子一行。
统计词unigram和bigram的频次,并将它们分别输出到data.unidata.bi两个文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python  

class NGram(object):

def __init__(self, n):
# n is the order of n-gram language model
self.n = n
self.unigram = {}
self.bigram = {}


def scan(self, sentence):
# file your code here
for line in sentence:
self.ngram(line.split())
#unigram
if self.n == 1:
try:
fip = open("data.uni","w")
except:
print >> sys.stderr ,"failed to open data.uni"
for i in self.unigram:
fip.write("%s %d\n" % (i,self.unigram[i]))
if self.n == 2:
try:
fip = open("data.bi","w")
except:
print >> sys.stderr ,"failed to open data.bi"
for i in self.bigram:
fip.write("%s %d\n" % (i,self.bigram[i]))

def ngram(self, words):
# unigram
if self.n == 1:
for word in words:
if word not in self.unigram:
self.unigram[word] = 1
else:
self.unigram[word] = self.unigram[word] + 1

# bigram
if self.n == 2:
num = 0
stri = ''
for i in words:
num = num + 1
if num == 2:
stri = stri + " "
stri = stri + i
if num == 2:
if stri not in self.bigram:
self.bigram[stri] = 1
else:
self.bigram[stri] = self.bigram[stri] + 1
num = 0
stri = ''

if __name__=="__main__":
import sys
try:
fip = open(sys.argv[1],"r")
except:
print >> sys.stderr, "failed to open input file"
sentence = []
for line in fip:
if len(line.strip())!=0:
sentence.append(line.strip())
uni = NGram(1)
bi = NGram(2)
uni.scan(sentence)
bi.scan(sentence)

文本矩阵化

分词

采用jieba分词

1
2
3
4
5
6
import pandas as pd
import jieba
def cut_content(contents):
return list(jieba.cut(contents))
train_data = pd.read_csv('./cnews/cnews.train.txt', sep='\t', names=['label', 'content'])
train_content = train_data['content'].apply(cut_content)

去停用词和构造词表

可以自己写一个停用词表,或者从网上找一个停用词表.
对分词后的内容进行去除停用词.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
stopwords = []
fstop = open('stop_words.txt', 'r',encoding='utf-8',errors='ingnore')
for eachWord in fstop:
stopwords.append(eachWord.strip())
fstop.close()
Data=[]
Vocab=[]
for line in train_data:
X=[]
for word in line:
if word not in stopwords:
X.append(word)
Vocab.append(word)
Data.append(X)

Vocab=set(Vocab)

文档向量化

词袋模型的统计词频:

1
2
3
4
5
6
7
8
9
from sklearn.feature_extraction.text import CountVectorizer  

vectorizer=CountVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]

print (vectorizer.fit_transform(corpus))

-------------本文结束感谢您的阅读-------------