英文:单词组成句子,单词之间由空格隔开 中文:字、词、句、段、篇 词:有意义的字组合 分词:将不同的词分隔开,将句子分解为词和标点符号 英文分词:根据空格 中文分词:三类算法 中文分词难点:歧义识别、未登录词 中文分词的好坏:歧义词识别和未登录词的识别准确率 分词工具:Jieba,SnowNLP,NlPIR,LTP,NLTK
词性也称为词类或词汇类别。用于特定任务的标记的集合被称为一个标记集 词性:词类,词汇性质,词汇的语义功能,词汇的所属类别 词性取决于:1.选定的词的类别体系 2.词汇本身在语句中上下文的语法语义功能 一个词汇有多个不同的词性,词性兼类现象 词性唯一:单性词 词性多于2个:兼类词 词性标注:将单词按它们的词性分类并进行相应地标注的过程,称为词语性质标注、词性标注或简称标注。 词性标注器:一个标注器能够正确识别一个句子的上下文中的这些词的标记 词性标注方法:三类
通用词性标记集 标记 含义 英文示例 ADJ 形容词 new, good, high, special, big, local ADP 介词 on, of, at, with, by, into, under ADV 副词 really, already, still, early, now CONJ 连词 and, or, but, if, while, although DET 限定词,冠词 the, a, some, most, every, no, which NOUN 名词 year, home, costs, time, Africa NUM 数词 twenty-four, fourth, 1991, 14:24 PRT 小品词 at, on, out, over per, that, up, with PRON 代词 he, their, her, its, my, I, us VERB 动词 is, say, told, given, playing, would . 标点符号 . , ; ! X 其它 ersatz, esprit, dunno, gr8, univeristy
1.最简单的标注器是为每个词符分配同样的标记。这似乎是一个相当平庸的一步,但它建立了标注器性能的一个重要的底线。为了得到最好的效果,我们用最有可能的标记标注每个词。让我们找出哪个标记是最有可能的
tags = [tag for (word, tag) in brown.tagged_words(categories='news')] nltk.FreqDist(tags).max() 'NN' 2.创建一个将所有词都标注成NN的标注器 raw = 'I do not like green eggs and ham, I do not like them Sam I am!' tokens = word_tokenize(raw) default_tagger = nltk.DefaultTagger('NN') default_tagger.tag(tokens) [('I', 'NN'), ('do', 'NN'), ('not', 'NN'), ('like', 'NN'), ('green', 'NN'), ('eggs', 'NN'), ('and', 'NN'), ('ham', 'NN'), (',', 'NN'), ('I', 'NN'), ('do', 'NN'), ('not', 'NN'), ('like', 'NN'), ('them', 'NN'), ('Sam', 'NN'), ('I', 'NN'), ('am', 'NN'), ('!', 'NN')] 3.不出所料,这种方法的表现相当不好。在一个典型的语料库中,它只标注正确了八分之一的标识符,正如我们在这里看到的: default_tagger.evaluate(brown_tagged_sents) Out[13]: 0.13089484257215028 默认的标注器给每一个单独的词分配标记,即使是之前从未遇到过的词。碰巧的是,一旦我们处理了几千词的英文文本之后,大多数新词都将是名词。正如我们将看到的,这意味着,默认标注器可以帮助我们提高语言处理系统的稳定性。
正则表达式标注器基于匹配模式分配标记给词符。例如,我们可能会猜测任一以ed结尾的词都是动词过去分词,任一以's结尾的词都是名词所有格。可以用一个正则表达式的列表表示这些:
patterns = [ ... (r'.ing$', 'VBG'), # gerunds ... (r'.ed$', 'VBD'), # simple past ... (r'.es$', 'VBZ'), # 3rd singular present ... (r'.ould$', 'MD'), # modals ... (r'.'s$', 'NN$'), # possessive nouns ... (r'.s$', 'NNS'), # plural nouns ... (r'^-?[0-9]+(.[0-9]+)?$', 'CD'), # cardinal numbers ... (r'.*', 'NN') # nouns (default) ... ] 请注意,这些是顺序处理的,第一个匹配上的会被使用。现在我们可以建立一个标注器,并用它来标记一个句子。做完这一步会有约五分之一是正确的。 regexp_tagger.evaluate(brown_tagged_sents) Out[21]: 0.20326391789486245
尝试使用二元标注器标注标识符。 如果二元标注器无法找到一个标记,尝试一元标注器。 如果一元标注器也无法找到一个标记,使用默认标注器。
t0 = nltk.DefaultTagger('NN')
t1 = nltk.UnigramTagger(train_sents, backoff=t0)
t2 = nltk.BigramTagger(train_sents, backoff=t1)
t2.evaluate(test_sents)
0.844513...
判断一封电子邮件是否是垃圾邮件。 从一个固定的主题领域列表中,如“体育”、“技术”和“政治”,决定新闻报道的主题是什么。 决定词bank给定的出现是用来指河的坡岸、一个金融机构、向一边倾斜的动作还是在金融机构里的存储行为。
有监督分类框架 (a)在训练过程中,特征提取器用来将每一个输入值转换为特征集。这些特征集捕捉每个输入中应被用于对其分类的基本信息,我们将在下一节中讨论它。特征集与标签的配对被送入机器学习算法,生成模型。(b)在预测过程中,相同的特征提取器被用来将未见过的输入转换为特征集。之后,这些特征集被送入模型产生预测标签。
创建一个分类器的第一步是决定输入的什么样的特征是相关的,以及如何为那些特征编码。
def gender_features(word): ... return {'last_letter': word[-1]} 这个函数返回的字典被称为特征集,映射特征名称到它们的值。特征名称是区分大小写的字符串,通常提供一个简短的人可读的特征描述,例如本例中的'last_letter'。特征值是简单类型的值,如布尔、数字和字符串。
from nltk.corpus import names labeled_names = ([(name, 'male') for name in names.words('male.txt')] + ... [(name, 'female') for name in names.words('female.txt')]) import random random.shuffle(labeled_names)
featuresets = [(gender_features(n), gender) for (n, gender) in labeled_names] train_set, test_set = featuresets[500:], featuresets[:500] classifier = nltk.NaiveBayesClassifier.train(train_set)
classifier.classify(gender_features('Neo')) 'male' classifier.classify(gender_features('Trinity')) 'female'
print(nltk.classify.accuracy(classifier, test_set))
classifier.show_most_informative_features(5) Most Informative Features last_letter = 'a' female : male = 33.2 : 1.0 last_letter = 'k' male : female = 32.6 : 1.0 last_letter = 'p' male : female = 19.7 : 1.0 last_letter = 'v' male : female = 18.6 : 1.0 last_letter = 'f' male : female = 17.3 : 1.0
def gender_features2(name): features = {} features["first_letter"] = name[0].lower() features["last_letter"] = name[-1].lower() for letter in 'abcdefghijklmnopqrstuvwxyz': features["count({})".format(letter)] = name.lower().count(letter) features["has({})".format(letter)] = (letter in name.lower()) return features
gender_features2('John') {'count(j)': 1, 'has(d)': False, 'count(b)': 0, ...}
用于训练有监督分类器的语料数据组织图。语料数据分为两类:开发集和测试集。开发集通常被进一步分为训练集和开发测试集。
errors = [] for (name, tag) in devtest_names: guess = classifier.classify(gender_features(name)) if guess != tag: errors.append( (tag, guess, name) ) for (tag, guess, name) in sorted(errors): ... print('correct={:<8} guess={:<8s} name={:<30}'.format(tag, guess, name))
train_set = [(gender_features(n), gender) for (n, gender) in train_names] devtest_set = [(gender_features(n), gender) for (n, gender) in devtest_names] classifier = nltk.NaiveBayesClassifier.train(train_set) print(nltk.classify.accuracy(classifier, devtest_set))
通过增加特征提取函数,我们可以修改这个词性标注器来利用各种词内部的其他特征,例如词长、它所包含的音节数或者它的前缀。然而,只要特征提取器仅仅看着目标词,我们就没法添加依赖词出现的上下文语境特征。然而上下文语境特征往往提供关于正确标记的强大线索——例如,标注词"fly",如果知道它前面的词是“a”将使我们能够确定它是一个名词,而不是一个动词。
为了采取基于词的上下文的特征,我们必须修改以前为我们的特征提取器定义的模式。不是只传递已标注的词,我们将传递整个(未标注的)句子,以及目标词的索引。
[1] 。<tt class="doctest">history</tt>中的每个标记对应<tt class="doctest">sentence</tt>中的一个词。但是请注意,<tt class="doctest">history</tt>将只包含我们已经归类的词的标记,也就是目标词左侧的词。因此,虽然是有可能查看目标词右边的词的某些特征,但查看那些词的标记是不可能的(因为我们还未产生它们)。
sents = nltk.corpus.treebank_raw.sents()
>>> tokens = []
>>> boundaries = set()
>>> offset = 0
>>> for sent in sents:
... tokens.extend(sent)
... offset += len(sent)
... boundaries.add(offset-1)
tokens是单独句子标识符的合并列表,boundaries是一个包含所有句子边界词符索引的集合。
def punct_features(tokens, i):
... return {'next-word-capitalized': tokens[i+1][0].isupper(),
... 'prev-word': tokens[i-1].lower(),
... 'punct': tokens[i],
... 'prev-word-is-one-char': len(tokens[i-1]) == 1}
featuresets = [(punct_features(tokens, i), (i in boundaries))
... for i in range(1, len(tokens)-1)
... if tokens[i] in '.?!']
>>> 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)
0.936026936026936
识别文字蕴含(RTE)是判断文本T的一个给定片段是否蕴含着另一个叫做“假设”的文本 迄今为止,已经有4个RTE挑战赛,在那里共享的开发和测试数据会提供给参赛队伍。这里是挑战赛3开发数据集中的文本/假设对的两个例子。标签True表示蕴含成立,False表示蕴含不成立。
未完待续......