152
7
显著搭配
语料库读取器可以直接读取
n
-gram
,可以用
n
-gram
代替简单的词汇表作为向
量元素对文本进行向量化,从而将这些特征结合到后续模型中。不过,用原
n
-gram
会产生非常多的候选词,其中大部分都是无关项。例如,句子“
I
got lost in the corn maze during the fall picnic
(我在秋季野餐期间迷失在玉米
迷宫里)”包含三元组(
'in'
'the'
'corn'
),这不是典型的介词短语,
而三元组(
'I', 'got', 'lost'
)
本身就有意义。
实际上,这在大多数应用中都会造成过高的计算成本而不可用,解决方案
是计算条件概率。例如,在已知出现词条
'during'
的文本中词条(
'the'
'fall'
)出现的可能性有多大?可以通过计算给定
n
-gram
第一个词的条件下
后面
(
n
-1)-gram
的频率来计算经验似然。用这种技术,我们可以将更常用的
n
-gram
('corn', 'maze')
与不太有意义的少见成分加以区分。
一些
n
-gram
相对会更有价值,这一想法导致了文本分析工具包中的另一个工
具:显著搭配。搭配是
n
-gram
的抽象同义词(没有特定的窗口大小),简单
地表示一个词序列,其共现的可能性是由偶然机会以外的因素引起的。通过
条件概率,我们可以检验特定搭配是否有意义。
NLTK
包含两个用于发现显著搭配的工具:
CollocationFinder
,用于查找和
排列
n
-gram
配;
NgramAssocMeasures
包含一组用于评价搭配显著性的指标。
两个工具都依赖于
n
的大小,模块包含
bigram
trigram
quadgram
排序实
用程序。遗憾的是,要实现
5-gram
及以上的关联,只能通过继承正确的基类
并用其中的搭配工具作为模板来手动实现。
现在,让我们探索显著四元组的发现。查找、排序大型语料库的
n
-gram
要花费大量时间,所以将结果写入磁盘文件是种很好的做法。我们将创
rank_quadgrams
函数,该函数将语料库作为输入来读取词,以及来自
QuadgramAssocMeasures
的测度,查找和排列四元组,将结果以制表符分隔的
形式写入磁盘文件:
from nltk.collocations import QuadgramCollocationFinder
from nltk.metrics.association import QuadgramAssocMeasures
上下文感知文本分析
153
def rank_quadgrams(corpus, metric, path=None):
"""
用给定的相关性度量从语料库中查找四元组并进行排序。如果提供了
path
参数,
则将四元组写入给定路径,否则将在内存中返回列表
"""
# Create a collocation ranking utility from corpus words.
ngrams = QuadgramCollocationFinder.from_words(corpus.words())
# Rank collocations by an association metric
scored = ngrams.score_ngrams(metric)
if path:
#
以制表符分隔形式形式写入磁盘文件
with open(path, 'w') as f:
f.write("Collocation\tScore ({})".format(metric.__name__))
for ngram, score in scored:
f.write("{}\t{}\n".format(repr(ngram), score))
else:
return scored
例如,可以用如下的似然比度量:
rank_quadgrams(
corpus, QuadgramAssocMeasures.likelihood_ratio, 'quadgrams.txt'
)
这将从样本语料库中生成具有似然得分的四元组,以下是其中的几个样本:
Collocation Score (likelihood_ratio)
('New', 'York', "'", 's') 156602.26742890902
('pictures', 'of', 'the', 'Earth') 28262.697780596758
('the', 'majority', 'of', 'users') 28262.36608379526
('numbed', 'by', 'the', 'mindlessness') 3091.139615301832
('There', 'was', 'a', 'time') 3090.2332736791095
QuadgramAssocMeasures
类提供了多种方法,通过假设检验对显著性进行排
序。
这些方法假设词之间没有关联(例如,零假设),如果零假设为真,则
计算关联发生的概率。如果因为显著性水平太低而拒绝零假设,可以接受替
代假设。
NLTK
QuadgramAssocMeasures
类提供了很多显著性测试工具,如学生
T
验,
Pearson
卡方检验,逐点互信息
Poisson-Stirling
测度,甚至是
Jaccard
指数。
Bigram
对应类包括更多的方法,如
Phi-square
Pearson
相关
的平方),
Fisher
精确检验或
Dice
系数。
154
7
现在设想一个用于流水线的重要区域特征提取变换器,如图
7-2
所示。
N-Gram感知
语料库阅读器
显著搭配 特征向量
分类或聚类
7
-
2
:一种 n-gram 征提取流水线
调用
fit()
时,它会找到候选的显著搭配并对其进行排序,再用
transform()
生成向量,对文档中找到的所有显著搭配的打分进行编码。最后用
FeatureUnion
可以讲这个向量与其他向量进行联合。
from sklearn.base import BaseEstimator, TransformerMixin
class SignificantCollocations(BaseEstimator, TransformerMixin):
def __init__(self,
ngram_class=QuadgramCollocationFinder,
metric=QuadgramAssocMeasures.pmi):
self.ngram_class = ngram_class
self.metric = metric
def fit(self, docs, target):
ngrams = self.ngram_class.from_documents(docs)
self.scored_ = dict(ngrams.score_ngrams(self.metric))
def transform(self, docs):
for doc in docs:
ngrams = self.ngram_class.from_words(docs)
yield {
ngram: self.scored_.get(ngram, 0.0)
for ngram in ngrams.nbest(QuadgramAssocMeasures.raw_freq, 50)
}
模型组成如下:
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
model = Pipeline([
('union', FeatureUnion(

Get 基于Python的智能文本分析 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.