在 nltk.org 的书(第 6 章)中有一个示例,他们使用 NaiveBayesian 算法将标点符号分类为完成一个句子或未完成一个......
这就是他们所做的:首先,他们获取一个语料库并使用 .sent 方法来获取句子并从中建立一个索引,用于将它们分开的标点符号 (the boundaries
) 所在的位置。
然后他们“标记”文本(将其转换为单词和标点符号列表)并将以下算法/函数应用于每个标记,以便他们获得字典中返回的特征列表:
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' 索引,他们选择所有标点符号,每个都有其特征,并将它们标记为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)这两种算法中的任何一种是如何真正分离句子的?我的意思是,特别是如果最好的是第一个简单的,nltk 是否理解句子只是两个标点符号之间的文本,后面跟着一个单词,第一个图表是大写字母,前一个单词是小写字母?这是 .sent 方法的作用吗?请注意,这与语言学或牛津词典更好地说是如何定义句子的方式相去甚远:
“一组本身完整的词,通常包含一个主语和谓语,传达一个陈述、问题、感叹词或命令,并由一个主要从句和有时一个或多个从句组成。”
或者(3)原始语料库文本是否像treebank
或brown
已经被手动分割?- 在这种情况下,选择它们的标准是什么?