文本分类:多标签与命令行训练探索
多标签分类器的构建与评估
在文本分类任务中,我们通常会遇到需要对文本进行多标签分类的情况。传统的二元分类器只能对文本进行二选一的分类,而多标签分类器则可以为文本分配多个标签。下面我们将详细介绍如何使用路透社语料库构建和评估多标签分类器。
准备工作
路透社语料库包含了多标签文本,我们可以利用这些文本进行训练和评估。首先,我们需要计算路透社语料库中的高信息词,这可以通过
featx.py
文件中的
reuters_high_info_words()
函数来实现:
from nltk.corpus import reuters
def reuters_high_info_words(score_fn=BigramAssocMeasures.chi_sq):
labeled_words = []
for label in reuters.categories():
labeled_words.append((label, reuters.words(categories=[label])))
return high_information_words(labeled_words, score_fn=score_fn)
接下来,我们需要根据这些高信息词获取训练和测试特征集。这可以通过
featx.py
文件中的
reuters_train_test_feats()
函数来实现:
def reuters_train_test_feats(feature_detector=bag_of_words):
train_feats = []
test_feats = []
for fileid in reuters.fileids():
if fileid.startswith('training'):
featlist = train_feats
else: # fileid.startswith('test')
featlist = test_feats
feats = feature_detector(reuters.words(fileid))
labels = reuters.categories(fileid)
featlist.append((feats, labels))
return train_feats, test_feats
我们可以使用这两个函数来获取多标签训练和测试特征集的列表:
from featx import reuters_high_info_words, reuters_train_test_feats
rwords = reuters_high_info_words()
featdet = lambda words: bag_of_words_in_set(words, rwords)
multi_train_feats, multi_test_feats = reuters_train_test_feats(featdet)
训练多个二元分类器
得到多标签训练特征集后,我们可以使用
classification.py
文件中的
train_binary_classifiers()
函数为每个标签训练一个二元分类器:
def train_binary_classifiers(trainf, labelled_feats, labelset):
pos_feats = collections.defaultdict(list)
neg_feats = collections.defaultdict(list)
classifiers = {}
for feat, labels in labelled_feats:
for label in labels:
pos_feats[label].append(feat)
for label in labelset - set(labels):
neg_feats[label].append(feat)
for label in labelset:
postrain = [(feat, label) for feat in pos_feats[label]]
negtrain = [(feat, '!%s' % label) for feat in neg_feats[label]]
classifiers[label] = trainf(postrain + negtrain)
return classifiers
为了使用这个函数,我们需要提供一个训练函数,该函数接受一个参数,即训练数据。这里我们使用一个简单的
lambda
包装器来包装
sklearn
逻辑回归
SklearnClassifier
类:
from classification import train_binary_classifiers
trainf = lambda train_feats: SklearnClassifier(LogisticRegression()).train(train_feats)
labelset = set(reuters.categories())
classifiers = train_binary_classifiers(trainf, multi_train_feats, labelset)
构建多标签分类器
在训练完多个二元分类器后,我们可以使用
classification.py
文件中的
MultiBinaryClassifier
类来构建一个多标签分类器:
from nltk.classify import MultiClassifierI
class MultiBinaryClassifier(MultiClassifierI):
def __init__(self, *label_classifiers):
self._label_classifiers = dict(label_classifiers)
self._labels = sorted(self._label_classifiers.keys())
def labels(self):
return self._labels
def classify(self, feats):
lbls = set()
for label, classifier in self._label_classifiers.items():
if classifier.classify(feats) == label:
lbls.add(label)
return lbls
我们可以使用刚刚创建的二元分类器来构建这个类:
from classification import MultiBinaryClassifier
multi_classifier = MultiBinaryClassifier(*classifiers.items())
评估多标签分类器
为了评估多标签分类器,我们可以使用精确率和召回率,但不能使用准确率。因为准确率函数假设的是单值,没有考虑部分匹配的情况。因此,我们使用
masi
距离来评估分类器,
masi
距离可以衡量两个集合之间的部分重叠程度。
classification.py
文件中的
multi_metrics()
函数可以计算每个标签的精确率和召回率,以及平均
masi
距离:
import collections
from nltk import metrics
def multi_metrics(multi_classifier, test_feats):
mds = []
refsets = collections.defaultdict(set)
testsets = collections.defaultdict(set)
for i, (feat, labels) in enumerate(test_feats):
for label in labels:
refsets[label].add(i)
guessed = multi_classifier.classify(feat)
for label in guessed:
testsets[label].add(i)
mds.append(metrics.masi_distance(set(labels), guessed))
avg_md = sum(mds) / float(len(mds))
precisions = {}
recalls = {}
for label in multi_classifier.labels():
precisions[label] = metrics.precision(refsets[label], testsets[label])
recalls[label] = metrics.recall(refsets[label], testsets[label])
return precisions, recalls, avg_md
使用这个函数来评估我们刚刚创建的多标签分类器:
from classification import multi_metrics
multi_precisions, multi_recalls, avg_md = multi_metrics(multi_classifier, multi_test_feats)
下面是多标签分类器构建和评估的流程图:
graph TD;
A[计算高信息词] --> B[获取训练和测试特征集];
B --> C[训练多个二元分类器];
C --> D[构建多标签分类器];
D --> E[评估多标签分类器];
NLTK-Trainer训练分类器
除了上述的多标签分类器构建方法,我们还可以使用
NLTK-Trainer
中的
train_classifier.py
脚本来从命令行训练
NLTK
分类器。
基本使用
train_classifier.py
脚本的唯一必需参数是语料库的名称,语料库必须有
categories()
方法。以下是在
movie_reviews
语料库上运行
train_classifier.py
的示例:
$ python train_classifier.py movie_reviews
这个命令将加载
movie_reviews
语料库,使用词袋特征提取方法,训练一个
NaiveBayes
分类器,并输出准确率、精确率、召回率和F值等评估指标。
我们还可以使用
--no-pickle
参数跳过保存分类器,使用
--fraction
参数限制训练集的大小,并对分类器进行测试:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75
选择不同的分类器
可以使用
--classifier
参数选择不同的分类器,例如
DecisionTreeClassifier
:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier DecisionTree --trace 0 --entropy_cutoff 0.8 --depth_cutoff 5 --support_cutoff 30 --binary
其他功能
-
保存分类器
:可以使用
--filename参数指定分类器的保存文件名:
$ python train_classifier.py movie_reviews --filename path/to/classifier.pickle
-
使用不同的训练实例
:默认情况下,
train_classifier.py使用单个文件作为训练实例,但我们可以使用--instances参数指定使用段落或句子作为训练实例:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --instances sents
-
查看最具信息性的特征
:可以使用
--show-most-informative参数查看最具信息性的特征:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --show-most-informative 5
-
使用不同的分类算法
:可以使用
--classifier参数选择不同的分类算法,例如Maxent、LogisticRegression、SVM等:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier GIS --max_iter 10 --min_lldelta 0.5
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier sklearn.LogisticRegression
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier sklearn.LinearSVC
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier sklearn.NuSVC
-
组合分类器
:可以使用
--classifier参数指定多个分类器,train_classifier.py会将这些分类器组合起来:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier sklearn.LogisticRegression sklearn.MultinomialNB sklearn.NuSVC
-
使用高信息词和二元组
:可以使用
--min_score和--ngrams参数指定使用高信息词和二元组作为特征:
$ python train_classifier.py movie_reviews --no-pickle --fraction 0.75 --classifier NaiveBayes --min_score 5 --ngrams 1 2
-
交叉验证
:可以使用
--cross-fold参数进行交叉验证:
$ python train_classifier.py movie_reviews --classifier sklearn.LogisticRegression --cross-fold 10
下面是
train_classifier.py
脚本的使用流程表格:
| 功能 | 参数 | 示例 |
| ---- | ---- | ---- |
| 基本使用 | 语料库名称 |
python train_classifier.py movie_reviews
|
| 跳过保存分类器 |
--no-pickle
|
python train_classifier.py movie_reviews --no-pickle
|
| 限制训练集大小 |
--fraction
|
python train_classifier.py movie_reviews --fraction 0.75
|
| 选择分类器 |
--classifier
|
python train_classifier.py movie_reviews --classifier DecisionTree
|
| 保存分类器 |
--filename
|
python train_classifier.py movie_reviews --filename path/to/classifier.pickle
|
文本分类:多标签与命令行训练探索
分析分类器
除了训练分类器,我们还可以使用
NLTK-Trainer
中的
analyze_classifier_coverage.py
脚本来分析分类器对给定语料库的分类情况。该脚本需要语料库的名称和一个已保存的分类器的路径作为输入。如果语料库是有分类标注的,还可以使用
--metrics
参数来获取准确率、精确率和召回率等评估指标。此外,使用
--speed
参数可以查看分类器的分类速度。
以下是一个使用
analyze_classifier_coverage.py
脚本来分析一个保存的
NaiveBayesClassifier
对
movie_reviews
语料库的分类情况的示例:
$ python analyze_classifier_coverage.py movie_reviews --classifier classifiers/movie_reviews_NaiveBayes.pickle --metrics --speed
这个命令会输出加载时间、准确率、精确率、召回率、F值、每个分类的数量以及平均每个特征的分类时间。
下面是分析分类器的操作步骤列表:
1. 准备好语料库和已保存的分类器。
2. 运行
analyze_classifier_coverage.py
脚本,并传入语料库名称和分类器路径。
3. 根据需要添加
--metrics
参数获取评估指标,添加
--speed
参数查看分类速度。
总结与注意事项
在构建和评估多标签分类器以及使用
NLTK-Trainer
训练和分析分类器的过程中,有以下几点需要注意:
多标签分类器
- 类不平衡问题 :路透社语料库存在类不平衡问题,即某些标签的特征集很少,而其他标签的特征集很多。这会导致二元分类器对负标签有很强的偏向性,难以得到正结果。虽然这种偏向反映了数据的实际情况,但可能会影响分类器的性能。可以参考相关技术来解决这个问题。
-
评估指标
:对于多标签分类器,不能使用准确率来评估,而应使用精确率、召回率和
masi距离等指标,因为准确率函数假设的是单值,没有考虑部分匹配的情况。
NLTK-Trainer
-
参数使用
:
train_classifier.py和analyze_classifier_coverage.py脚本支持很多参数,可以根据需要灵活使用这些参数来实现不同的功能,如选择不同的分类器、保存分类器、使用不同的训练实例等。 -
结果稳定性
:由于
PYTHONHASHSEED环境变量的影响,运行train_classifier.py时,准确率、精确率和召回率等结果可能会有所不同。如果需要得到一致的结果,可以设置PYTHONHASHSEED环境变量,例如:
$ PYTHONHASHSEED=0 python train_classifier.py movie_reviews
下面是多标签分类和
NLTK-Trainer
使用的整体流程图:
graph LR;
A[多标签分类器构建] --> B[计算高信息词];
B --> C[获取训练和测试特征集];
C --> D[训练多个二元分类器];
D --> E[构建多标签分类器];
E --> F[评估多标签分类器];
G[NLTK-Trainer使用] --> H[train_classifier.py训练];
H --> I[选择不同参数和分类器];
J --> K[analyze_classifier_coverage.py分析];
K --> L[获取评估指标和速度];
A -.-> G;
通过以上介绍,我们详细了解了如何构建和评估多标签分类器,以及如何使用
NLTK-Trainer
从命令行训练和分析分类器。这些方法和工具可以帮助我们更高效地进行文本分类任务。
超级会员免费看
8666

被折叠的 条评论
为什么被折叠?



