【任务3 - 特征提取】
- 基本文本处理技能
1.1 分词的概念(分词的正向最大、逆向最大、双向最大匹配法);
1.2 词、字符频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库) - 2.1 语言模型中unigram、bigram、trigram的概念;
2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库) - 文本矩阵化:要求采用词袋模型且是词级别的矩阵化
步骤有:
3.1 分词(可采用结巴分词来进行分词操作,其他库也可以);
3.2 去停用词;构造词表。
3.3 每篇文档的向量化。
正向最大(Maximum Matching, MM):
算法思想:
从左到右将待分词文本中的几个连续字符与词表匹配,如果匹配上,则切分出一个词。但这里有一个问题:要做到最大匹配,并不是第一次匹配到就可以切分的 。我们来举个例子:
待分词文本: content[]={“中”,“华”,“民”,“族”,“从”,“此”,“站”,“起”,“来”,“了”,"。"}
词表: dict[]={“中华”, “中华民族” , “从此”,“站起来”}
(1) 从content[1]开始,当扫描到content[2]的时候,发现"中华"已经在词表dict[]中了。但还不能切分出来,因为我们不知道后面的词语能不能组成更长的词(最大匹配)。
(2) 继续扫描content[3],发现"中华民"并不是dict[]中的词。但是我们还不能确定是否前面找到的"中华"已经是最大的词了。因为"中华民"是dict[2]的前缀。
(3) 扫描content[4],发现"中华民族"是dict[]中的词。继续扫描下去:
(4) 当扫描content[5]的时候,发现"中华民族从"并不是词表中的词,也不是词的前缀。因此可以切分出前面最大的词——“中华民族”。
由此可见,最大匹配出的词必须保证下一个扫描不是词表中的词或词的前缀才可以结束。
sudo-code
result = []
right_seq = input_seq
while True:
select_seq,left_seq = get_select_seq(right_seq)
seg_word,seg_word_right = selectMaxLenInDict(select_seq)
result.append(seg_seq)
right_seq = seg_word_right+left_seq
if right_seq=="":
break
def selectMaxLenInDict(_seq):
for idx in range(len(select_seq),1,-1):
word = select_seq[0:idx]
if word in dict:
return word,select_seq[idx:]
return select_seq[0:1],select_seq[1:]
def get_seg_seq(_seq):
if maxlen > len(_seq):
return _seq,""
return _seq[0:maxlen],_seq[maxlen:]
逆向最大
sudo-code:
逆向伪代码
result = []
right_seq = input_seq
while True:
left_seq,select_seq = get_select_seq(right_seq)
seg_word,seg_word_right = selectMaxLenInDict(select_seq)
result.append(seg_seq)
right_seq =left_seq+ seg_word_right
if right_seq=="":
break
def selectMaxLenInDict(_seq):
for idx in range(0,len(select_seq)):
word = select_seq[idx:]
if word in dict:
return select_seq[0:idx],word
return select_seq[0:-1],select_seq[-1]
def get_seg_seq(_seq):
if maxlen > len(_seq):
return _seq,""
return _seq[0:maxlen],_seq[maxlen:]
双向最大匹配法(Bi-directction Matching method,BM)
双向就是结合正向最大和逆向最大的结果,对两个结果进行比较,从而决定正确的分词方式,当前向和逆向分词数量不相等的时候,选择数量较少的那个分词结果。如果分词数量相同,则依次比较分词结果,相应位置如果分词相同,则选取为最后的结果中,如果相应位置分词结果不一样则选取字符较少的那个最为分词结果。
例子:“中华”,“中华名族”,“中间”,“感召”,“感召力”,“感受”
unigram 一元分词,把句子分成一个一个的汉字
bigram 二元分词,把句子从头到尾每两个字组成一个词语
trigram 三元分词,把句子从头到尾每三个字组成一个词语.
>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
... cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})
>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]