赞
踩
文本正则化的目的是将文本转换成一种更方便使用、更标准的表达形式。正则表达是一个其中的一个强有力的工具。对于大部分语言的处理,通常第一步需要做分词,这一类任务叫做 Tokenization。另一个很重要的步骤是 Lemmatization(词形还原,例如英文中 is, are, am 都是 be,对于中文这一步,主要是简繁转换等,主要用于处理词法复杂的语言)。Stemming(词干提取,通常是是分离后缀)。文本正则化通常也包含句子分割,例如以句号或者感叹号分割。
编辑距离是基于编辑的次数(增删改)比较给定两个字符串之间的相似度。
类似于 Unix 下的 grep 或 Emacs。
要习惯使用在线正则表达式测试自己的表达式写的是否正确。https://regex101.com/
| 竖线,析取表达式,表示或的意思,例如 “cat|dog” 表示 “cat” or “dog”
() 小括号,将需要优先处理的部分括起来,例如 “gupp(y|ies)” 表示 “guppy” or “guppies”
优先级顺序:
默认的是贪婪模式,尽可能匹配符合条件的最长字符串,若想使用非贪婪模式,可以在 * 或 + 后面加一个 ?,则会尽可能短的进行匹配。
Python 正则表达式可以参照这里,也可以通过 “help(re)” 的方式查看完整的 API 文档。
略
这是一个基线方法,用于对比其他更先进的算法。该算法需要提供一个分词词典。
基本思想是从[start, end] 看看在不在词典中,不在则 [start, end-1] 直到剩 start 那就单独分离一个字
整个算法伪代码如下:
# http://lion137.blogspot.com/2017/01/text-segmentation-maximum-matching-in.html D = ['danny', 'condo', 'a', 'the', 'to', 'has', 'been', 'unable', 'go', 'at'] def max_match(sentence, dictionary): if not sentence: return "" for i in range(len(sentence), -1, -1): first_word = sentence[:i] remainder = sentence[i:] if first_word in dictionary: return first_word + " " + max_match(remainder, dictionary) first_word = sentence[0] remainder = sentence[1:] return first_word + max_match(remainder, dictionary) print(max_match('atcondogo', D))
一般用 word error rate 评估分词的质量,该算法的一个问题是无法解决 unknown words,中文分词通常使用统计序列模型。
词形还原是用来检测两个单词是否具有相同的根,单词一般分为词素和词根两部分,词素代表该单词的主要意思,词根是额外的信息。
词形还原算法是比较复杂的,但我们可以整一个比较简单的粗糙的,比如直接去掉词缀,这种提取词干的方式较 stemming。最常用的 stemming 算法是 Porter stemmer,该算法是基于一些简单的规则进行处理的,例如,去掉以 “ing” 结尾,将 “sses” 替换成 “ss” 等。算法细节以及各种代码实现可以参照这里。
下面举一个 NLTK 工具包中的例子:
import nltk
from nltk.stem.porter import *
stemmer = PorterStemmer()
tokens = ['compute', 'computer', 'computed', 'computing']
for token in tokens:
print(token + ' --> ' + stemmer.stem(token))
"""
compute --> comput
computer --> comput
computed --> comput
computing --> comput
"""
稍微高级一点的版本叫 “Snowball Stemmer”,
from nltk.stem.snowball import SnowballStemmer
stemmer = SnowballStemmer(language="english")
tokens = ['compute', 'computer', 'computed', 'computing']
for token in tokens:
print(token + " --> " + stemmer.stem(token))
"""
compute --> comput
computer --> comput
computed --> comput
computing --> comput
"""
Stem 处理后的单词可能是非字典中的单词,所以是时候使用 Lemmatization 这个大招了。
我们借助 SpaCy 这个强大的工具包,借助 lemma_ 属性即可。
import spacy
nlp = spacy.load("en_core_web_sm")
sentence = nlp("compute computer computed computing")
for word in sentence:
print(word.text, word.lemma_)
"""
compute compute
computer computer
computed compute
computing computing
"""
Stem 和 Lemma 有一个附加的好处是,可以在一定程度上解决 unknown words。例如训练集中可能含有 low 和 lowest,不包含 lower,lower 出现在测试集中。但这么做可能会损失一些重要信息,例如对于词性标注,我们需要保持这种区别。
为了解决这个问题,我们采用另一种分词手法,保留大部分单词,以及诸如 “-er” 等内容,这样不认识的单词可以通过零碎的部件拼接。
import re import collections def get_stats(voc): dict_pairs = collections.defaultdict(int) for word, freq in voc.items(): symbols = word.split() for index in range(len(symbols) - 1): dict_pairs[symbols[index], symbols[index+1]] += freq return dict_pairs def merge_vocab(pair, v_in): v_out = {} bigram = re.escape(' '.join(pair)) p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)') for word in v_in: w_out = p.sub("".join(pair), word) v_out[w_out] = v_in[word] return v_out vocab = {'l o w </w>': 5, 'l o w e s t </w>': 2, 'n e w e r </w>': 6, 'w i d e r </w>': 3, 'n e w </w>': 2} num_merges = 8 for i in range(num_merges): pairs = get_stats(vocab) best = max(pairs, key=pairs.get) vocab = merge_vocab(best, vocab) print(best)
计算两个单词之间,通过增、改、插 等手段的最小变换次数。例如:
上面两个单词的编辑距离为 5,有的操作中不存在“改”,因为一个“改”可以由一个“删”和一个“插”组合而成,这样算则两个单词的编辑距离为 8.
寻找编辑距离的过程可以视为一个查找问题。所有的编辑可能空间是巨大的,所以我们不能暴力查找,这种问题的求解通常是采用动态规划算法
import numpy as np def normal_leven(str1, str2): len_str1 = len(str1) + 1 len_str2 = len(str2) + 1 matrix = np.zeros((len_str1, len_str2)) matrix[0, :] = range(len_str2) matrix[:, 0] = range(len_str1) for i in range(1, len_str1): for j in range(1, len_str2): if str1[i-1] == str2[j-1]: cost = 0 else: cost = 2 matrix[i, j] = min(matrix[i-1, j] + 1, matrix[i, j-1] + 1, matrix[i-1, j-1] + cost) return matrix[-1, -1] print(normal_leven("intention", "execution"))
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。