nltk.org 使用朴素贝叶斯分类器进行句子分割的示例:.sent 如何分隔句子以及 ML 算法如何改进它?

nltk.org example of Sentence segmentation with Naive Bayes Classifier: how does .sent separate sentences and how does the ML algorithm improve it?

在 nltk.org book (chapter 6) 中有一个示例,他们使用朴素贝叶斯算法将标点符号分类为完成一个句子或未完成一个句子...

他们是这样做的:首先,他们获取一个语料库并使用 .sent 方法获取句子,并从中建立一个索引,其中标点符号(boundaries)将它们分开。

然后他们 "tokenize" 文本(将其转换为单词和标点符号列表)并将以下 algorithm/function 应用于每个标记,以便他们获得 功能列表 在字典中返回:

def punct_features(tokens, i):
    return {'nextWordCapitalized': tokens[i+1][0].isupper(),
        'prevWord': tokens[i-1].lower(),
        'punct': tokens[i],
        'prevWordis1Char': len(tokens[i-1]) == 1}

ML 算法将使用这些特征来将标点符号分类为是否结束一个句子(即作为边界标记)。

使用这个 fn 和 'boundaries' 索引,它们 select 所有标点符号,每个都有其特征,并将它们标记为 True 边界,或 False一个,从而创建一个 标记的特征集列表 :

featuresets1 = [(punct_features(tokens, i), (i in boundaries)) for i in range(1, len(tokens)-1)
               if tokens[i] in '.?!;']
print(featuresets1[:4])

这是打印前四组时可能出现的输出示例:

[({'nextWordCapitalized': False, 'prevWord': 'nov', 'punct': '.', 'prevWordis1Char': False}, False), 
({'nextWordCapitalized': True, 'prevWord': '29', 'punct': '.', 'prevWordis1Char': False}, True), 
({'nextWordCapitalized': True, 'prevWord': 'mr', 'punct': '.', 'prevWordis1Char': False}, False), 
({'nextWordCapitalized': True, 'prevWord': 'n', 'punct': '.', 'prevWordis1Char': True}, False)]

有了这个,他们训练和评估标点符号分类器:

size = int(len(featuresets) * 0.1)
train_set, test_set = featuresets[size:], featuresets[:size]
classifier = nltk.NaiveBayesClassifier.train(train_set)

nltk.classify.accuracy(classifier, test_set)

现在,(1) 这种 ML 算法将如何改进以及改进什么?我无法理解第一个简单算法如何更好地检查标点符号中的下一个标记是否为大写,而前一个是否为小写。事实上,该算法被用来验证一个符号是一个边界......!如果它不能改善它,它可能有什么用处?

与此相关:(2) 这两种算法中的任何一种都是 nlpk 如何真正分离句子的?我的意思是,特别是如果最好的是第一个简单的,nltk 是否理解句子只是两个标点符号之间的文本,后面跟着一个单词,第一个图表大写,前一个单词小写?这是 .sent 方法的作用吗?请注意,这与语言学或更好的说法是牛津词典对句子的定义相去甚远:

"A set of words that is complete in itself, typically containing a subject and predicate, conveying a statement, question, exclamation, or command, and consisting of a main clause and sometimes one or more subordinate clauses."

或者 (3) 像 treebankbrown 这样的原始语料库文本是否已经被手动分割成句子? - 在这种情况下, select 他们的标准是什么?

问题(1):NLTK可能没说清楚,但是分句是个难题。就像你说的,我们可以假设标点符号结束了句子,即前一个字符是小写,当前字符是标点,下一个字符是大写(顺便说一句,中间有空格!不要忘记!)。但是,请考虑这句话:

"Mr. Peter works at a company called A.B.C. Inc. in Toronto. His net salary per month is 44.21. 22 years ago, he came to Toronto as an immigrant." - 现在,按照我们上面的规则,这将如何拆分?

Wikipedia page on sentence boundary disambiguation illustrates a few more of these issues. In the NLP textbook "Speech and Language Processing" by Jurafsky and Martin, they also have a chapter on Text normaliazation,以及更多示例,说明为什么 word/sentence 分段可能具有挑战性 - 这可能对您了解这一点很有用。我假设我们正在讨论英语分割,但显然其他语言存在其他问题(例如,某些语言没有大写)。

问题2:nlpk这两种算法是如何真正分离句子的? NLTK 使用一种无​​监督的句子分割方法,称为 PunktSentenceTokenizer

Q3:像treebank或brown这样的原始语料库文本是否已经被手动分句了? - 是的,这些是手动分成句子的。这些是 NLP 中用于开发语言工具(例如 POS 标记器、解析器等)的一些常见语料库。选择这些的一个原因可能是它们已经在 NLTK 中可用,我们不必寻找另一个人工注释的语料库来做句子边界检测的监督学习。

被接受的(否则很好的)答案遗漏的一件事是 NaiveBayes 算法在应用您描述的规则之外所做的事情的解释。

任何这种类型的分类器都被赋予了几个特征,它必须决定它们作为分类线索的重要性。 下一个大写字母 = 非常重要,前一个小写字母 = 重要但不太重要,space 在这个标点符号之后 = important 等。机器学习算法使用 some 方法为每个特征分配权重(=重要性),以便算法可以提供最好的结果。有些人可以一步完成,其他人可以一步一步完成,每次迭代都会比以前的结果有所改进 ("hill climbing")。

每种机器学习算法的细节都不同,朴素贝叶斯的细节在这里并不重要。但为了完整性:它是一种基于假设(通常与现实相反,但很方便)的统计计算,即每个特征在统计上独立于所有其他特征。