- 自然语言工具包教程
- 自然语言工具包 - 首页
- 自然语言工具包 - 简介
- 自然语言工具包 - 入门
- 自然语言工具包 - 文本分词
- 训练分词器 & 过滤停用词
- 在Wordnet中查找单词
- 词干提取 & 词形还原
- 自然语言工具包 - 单词替换
- 同义词 & 反义词替换
- 语料库读取器和自定义语料库
- 词性标注基础
- 自然语言工具包 - 一元标注器
- 自然语言工具包 - 组合标注器
- 自然语言工具包 - 更多NLTK标注器
- 自然语言工具包 - 语法分析
- 组块 & 信息提取
- 自然语言工具包 - 转换组块
- 自然语言工具包 - 转换树
- 自然语言工具包 - 文本分类
- 自然语言工具包资源
- 自然语言工具包 - 快速指南
- 自然语言工具包 - 有用资源
- 自然语言工具包 - 讨论
自然语言工具包 - 文本分类
什么是文本分类?
文本分类,顾名思义,就是对文本或文档进行分类的方法。但这里出现了一个问题,为什么我们需要使用文本分类器?一旦检查了文档或文本中单词的使用情况,分类器就能确定应该为其分配什么类别标签。
二元分类器
顾名思义,二元分类器将在两个标签之间做出决策。例如,正面或负面。在这种情况下,文本或文档要么是一个标签,要么是另一个标签,但不能同时是两个标签。
多标签分类器
与二元分类器相反,多标签分类器可以为文本或文档分配一个或多个标签。
带标签与无标签特征集
特征名称到特征值的键值映射称为特征集。带标签的特征集或训练数据对于分类训练非常重要,以便它以后可以对无标签的特征集进行分类。
带标签的特征集 | 无标签的特征集 |
---|---|
它是一个看起来像 (feat, label) 的元组。 | 它本身就是一个特征。 |
它是一个具有已知类别标签的实例。 | 如果没有关联的标签,我们可以称之为实例。 |
用于训练分类算法。 | 训练完成后,分类算法可以对无标签的特征集进行分类。 |
文本特征提取
文本特征提取,顾名思义,就是将单词列表转换为分类器可用的特征集的过程。我们必须将我们的文本转换为“dict”风格的特征集,因为自然语言工具包 (NLTK) 期望“dict”风格的特征集。
词袋 (BoW) 模型
BoW,是NLP中最简单的模型之一,用于从文本或文档中提取特征,以便在建模中使用,例如在机器学习算法中。它基本上从实例的所有单词构建一个单词存在特征集。这种方法背后的概念是,它不关心一个单词出现的次数或单词的顺序,它只关心该单词是否存在于单词列表中。
示例
对于此示例,我们将定义一个名为 bow() 的函数 -
def bow(words): return dict([(word, True) for word in words])
现在,让我们在单词上调用bow()函数。我们将这些函数保存在名为 bagwords.py 的文件中。
from bagwords import bow bow(['we', 'are', 'using', 'tutorialspoint'])
输出
{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}
训练分类器
在前面的部分中,我们学习了如何从文本中提取特征。因此,现在我们可以训练分类器了。第一个也是最简单的分类器是NaiveBayesClassifier类。
朴素贝叶斯分类器
为了预测给定特征集属于特定标签的概率,它使用贝叶斯定理。贝叶斯定理的公式如下。
$$P(A|B)=\frac{P(B|A)P(A)}{P(B)}$$这里,
P(A|B) - 它也称为后验概率,即在第二个事件(即B)发生的情况下,第一个事件(即A)发生的概率。
P(B|A) - 它是第一个事件(即A)发生后第二个事件(即B)发生的概率。
P(A), P(B) - 它也称为先验概率,即第一个事件(即A)或第二个事件(即B)发生的概率。
为了训练朴素贝叶斯分类器,我们将使用NLTK中的movie_reviews语料库。此语料库有两个类别的文本,即:pos和neg。这些类别使在它们上面训练的分类器成为二元分类器。语料库中的每个文件都由两个组成,一个是正面影评,另一个是负面影评。在我们的示例中,我们将使用每个文件作为训练和测试分类器的单个实例。
示例
为了训练分类器,我们需要一个带标签的特征集列表,它将采用[(featureset, label)]的形式。这里的featureset变量是一个dict,标签是featureset的已知类别标签。我们将创建一个名为label_corpus()的函数,它将获取一个名为movie_reviews的语料库,以及一个名为feature_detector的函数,默认为词袋。它将构建并返回一个{label: [featureset]}形式的映射。之后,我们将使用此映射来创建带标签的训练实例和测试实例列表。
import collections
def label_corpus(corp, feature_detector=bow): label_feats = collections.defaultdict(list) for label in corp.categories(): for fileid in corp.fileids(categories=[label]): feats = feature_detector(corp.words(fileids=[fileid])) label_feats[label].append(feats) return label_feats
借助上述函数,我们将获得一个{label:fetaureset}映射。现在,我们将定义另一个名为split的函数,它将获取label_corpus()函数返回的映射,并将每个特征集列表拆分为带标签的训练实例和测试实例。
def split(lfeats, split=0.75): train_feats = [] test_feats = [] for label, feats in lfeats.items(): cutoff = int(len(feats) * split) train_feats.extend([(feat, label) for feat in feats[:cutoff]]) test_feats.extend([(feat, label) for feat in feats[cutoff:]]) return train_feats, test_feats
现在,让我们在我们的语料库(即movie_reviews)上使用这些函数 -
from nltk.corpus import movie_reviews from featx import label_feats_from_corpus, split_label_feats movie_reviews.categories()
输出
['neg', 'pos']
示例
lfeats = label_feats_from_corpus(movie_reviews) lfeats.keys()
输出
dict_keys(['neg', 'pos'])
示例
train_feats, test_feats = split_label_feats(lfeats, split = 0.75) len(train_feats)
输出
1500
示例
len(test_feats)
输出
500
我们已经看到,在movie_reviews语料库中,有1000个pos文件和1000个neg文件。我们最终也得到了1500个带标签的训练实例和500个带标签的测试实例。
现在让我们使用其train()类方法训练NaïveBayesClassifier -
from nltk.classify import NaiveBayesClassifier NBC = NaiveBayesClassifier.train(train_feats) NBC.labels()
输出
['neg', 'pos']
决策树分类器
另一个重要的分类器是决策树分类器。在这里,为了训练它,DecisionTreeClassifier类将创建一个树结构。在此树结构中,每个节点对应一个特征名称,分支对应特征值。向下沿着分支,我们将到达树的叶子,即分类标签。
为了训练决策树分类器,我们将使用相同的训练和测试特征,即train_feats和test_feats变量,这些变量是我们从movie_reviews语料库中创建的。
示例
为了训练此分类器,我们将调用DecisionTreeClassifier.train()类方法,如下所示 -
from nltk.classify import DecisionTreeClassifier decisiont_classifier = DecisionTreeClassifier.train( train_feats, binary = True, entropy_cutoff = 0.8, depth_cutoff = 5, support_cutoff = 30 ) accuracy(decisiont_classifier, test_feats)
输出
0.725
最大熵分类器
另一个重要的分类器是MaxentClassifier,它也称为条件指数分类器或逻辑回归分类器。在这里,为了训练它,MaxentClassifier类将使用编码将带标签的特征集转换为向量。
为了训练决策树分类器,我们将使用相同的训练和测试特征,即train_feats和test_feats变量,这些变量是我们从movie_reviews语料库中创建的。
示例
为了训练此分类器,我们将调用MaxentClassifier.train()类方法,如下所示 -
from nltk.classify import MaxentClassifier maxent_classifier = MaxentClassifier .train(train_feats,algorithm = 'gis', trace = 0, max_iter = 10, min_lldelta = 0.5) accuracy(maxent_classifier, test_feats)
输出
0.786
Scikit-learn分类器
Scikit-learn是最好的机器学习 (ML) 库之一。它实际上包含各种用途的各种ML算法,但它们都具有以下相同的拟合设计模式 -
- 将模型拟合到数据
- 并使用该模型进行预测
这里,我们不会直接访问scikit-learn模型,而是将使用NLTK的SklearnClassifier类。此类是scikit-learn模型的包装类,使其符合NLTK的Classifier接口。
我们将按照以下步骤训练SklearnClassifier类 -
步骤1 - 首先,我们将像在以前的配方中一样创建训练特征。
步骤2 - 现在,选择并导入Scikit-learn算法。
步骤3 - 接下来,我们需要使用所选算法构建SklearnClassifier类。
步骤4 - 最后,我们将使用我们的训练特征训练SklearnClassifier类。
让我们在下面的Python配方中实现这些步骤 -
from nltk.classify.scikitlearn import SklearnClassifier from sklearn.naive_bayes import MultinomialNB sklearn_classifier = SklearnClassifier(MultinomialNB()) sklearn_classifier.train(train_feats) <SklearnClassifier(MultinomialNB(alpha = 1.0,class_prior = None,fit_prior = True))> accuracy(sk_classifier, test_feats)
输出
0.885
测量精确率和召回率
在训练各种分类器时,我们也测量了它们的准确率。但是除了准确率之外,还有许多其他指标用于评估分类器。这两个指标是精确率和召回率。
示例
在此示例中,我们将计算之前训练的NaiveBayesClassifier类的精确率和召回率。为了实现这一点,我们将创建一个名为metrics_PR()的函数,它将有两个参数,一个是训练好的分类器,另一个是带标签的测试特征。这两个参数与我们在计算分类器准确率时传递的参数相同 -
import collections from nltk import metrics def metrics_PR(classifier, testfeats): refsets = collections.defaultdict(set) testsets = collections.defaultdict(set) for i, (feats, label) in enumerate(testfeats): refsets[label].add(i) observed = classifier.classify(feats) testsets[observed].add(i) precisions = {} recalls = {} for label in classifier.labels(): precisions[label] = metrics.precision(refsets[label],testsets[label]) recalls[label] = metrics.recall(refsets[label], testsets[label]) return precisions, recalls
让我们调用此函数以查找精确率和召回率 -
from metrics_classification import metrics_PR nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats) nb_precisions['pos']
输出
0.6713532466435213
示例
nb_precisions['neg']
输出
0.9676271186440678
示例
nb_recalls['pos']
输出
0.96
示例
nb_recalls['neg']
输出
0.478
分类器组合和投票
组合分类器是提高分类性能的最佳方法之一。投票是组合多个分类器的最佳方法之一。对于投票,我们需要有奇数个分类器。在下面的Python配方中,我们将组合三个分类器,即NaiveBayesClassifier类、DecisionTreeClassifier类和MaxentClassifier类。
为了实现这一点,我们将定义一个名为voting_classifiers()的函数,如下所示。
import itertools from nltk.classify import ClassifierI from nltk.probability import FreqDist class Voting_classifiers(ClassifierI): def __init__(self, *classifiers): self._classifiers = classifiers self._labels = sorted(set(itertools.chain(*[c.labels() for c in classifiers]))) def labels(self): return self._labels def classify(self, feats): counts = FreqDist() for classifier in self._classifiers: counts[classifier.classify(feats)] += 1 return counts.max()
让我们调用此函数以组合三个分类器并找到准确率 -
from vote_classification import Voting_classifiers combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier) combined_classifier.labels()
输出
['neg', 'pos']
示例
accuracy(combined_classifier, test_feats)
输出
0.948
从上面的输出中,我们可以看到组合分类器的准确率高于单个分类器。