使用 NLTK、scikit-learn 和 OneVsRestClassifier 打开多标签分类
Turning on multi-label classification with NLTK, scikit-learn and OneVsRestClassifier
免责声明:我对 AI、Python、NLTK 和 scikit-learn 还很陌生。
我正在尝试训练 classifier 以 class将一组文档验证为一组标签。
我正在使用 NLTK 包装器与 scikit-learn 的 OneVsRestClassifier 对话。
training_set = [
[{"car": True, ...}, "Label 1"],
[{"car": False, ...}, "Label 2"],
...
[{"car": False, ...}, "Label 1"],
]
ovr = SklearnClassifier(OneVsRestClassifier(MultinomialNB()))
ovr.train(training_set)
这与 Multi-class classification 一起工作很好,其中 classifier 试图将文档 classify 仅到一个标签。准确性很好,但我希望 classifier 为文档分配 0、1 或更多标签。我怎样才能做到这一点?
遗憾的是我不能只初始化 classifier 告诉它是一个多标签 classifier,documentation 说:
这个策略也可以用于多标签学习,其中一个 classifier
用于预测多个标签,例如,通过拟合二维矩阵
如果样本 i 具有标签 j,则单元格 [i, j] 为 1,否则为 0。
我不太清楚,因为我不熟悉这种语言。我有一种感觉,我必须以 classifier 理解我希望它对我的数据进行多标签 class 验证的方式来塑造我的训练集?如果是,如何?
我尝试在数组中提供标签,如下所示:
training_set = [
[{"car": True, ...}, ["Label 1"]],
[{"car": False, ...}, ["Label 2"]],
...
[{"car": False, ...}, ["Label 1"]],
]
这没有按预期工作并引发:
DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
y = column_or_1d(y, warn=True)
One-vs-rest accuracy percent: 0.0
文档试图说明的是,使用二维矩阵作为目标。所以基本上,你的训练集可以是,
training_set = [
[{"car": True, ...}, [is_label_1, is_label_2, is_label_3]],
[{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
...
[{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
]
对于特定样本,使用多个标签对其进行训练,
例如对于第一个样本,如果存在标签 1 和标签 3,则将其作为 [1, 0, 1].
传递
希望,答案对你来说很清楚。
我通过摆脱 NLTK 到 scikit-learn 适配器并导入一个 NLTK 模块来帮助我将我的数据结构转换为可提供给 scikit-learn OneVsRestClassifier 的东西来解决这个问题。
from nltk import compat
from sklearn.feature_extraction import DictVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.multiclass import OneVsRestClassifier
_vectorizer = DictVectorizer(dtype=float, sparse=True)
def prepare_scikit_x_and_y(labeled_featuresets):
X, y = list(compat.izip(*labeled_featuresets))
X = _vectorizer.fit_transform(X)
set_of_labels = []
for label in y:
set_of_labels.append(set(label))
y = self.mlb.fit_transform(set_of_labels)
return X, y
def train_classifier(labeled_featuresets):
X, y = prepare_scikit_x_and_y(labeled_featuresets)
classifier.fit(X, y)
training_set = [
[{"car": True, ...}, ["Label 1"]],
[{"car": False, ...}, ["Label 2"]],
...
[{"car": False, ...}, ["Label 1"]],
]
ovr = OneVsRestClassifier(MultinomialNB())
ovr.train(training_set)
快乐豆
免责声明:我对 AI、Python、NLTK 和 scikit-learn 还很陌生。
我正在尝试训练 classifier 以 class将一组文档验证为一组标签。
我正在使用 NLTK 包装器与 scikit-learn 的 OneVsRestClassifier 对话。
training_set = [
[{"car": True, ...}, "Label 1"],
[{"car": False, ...}, "Label 2"],
...
[{"car": False, ...}, "Label 1"],
]
ovr = SklearnClassifier(OneVsRestClassifier(MultinomialNB()))
ovr.train(training_set)
这与 Multi-class classification 一起工作很好,其中 classifier 试图将文档 classify 仅到一个标签。准确性很好,但我希望 classifier 为文档分配 0、1 或更多标签。我怎样才能做到这一点?
遗憾的是我不能只初始化 classifier 告诉它是一个多标签 classifier,documentation 说:
这个策略也可以用于多标签学习,其中一个 classifier 用于预测多个标签,例如,通过拟合二维矩阵 如果样本 i 具有标签 j,则单元格 [i, j] 为 1,否则为 0。
我不太清楚,因为我不熟悉这种语言。我有一种感觉,我必须以 classifier 理解我希望它对我的数据进行多标签 class 验证的方式来塑造我的训练集?如果是,如何?
我尝试在数组中提供标签,如下所示:
training_set = [
[{"car": True, ...}, ["Label 1"]],
[{"car": False, ...}, ["Label 2"]],
...
[{"car": False, ...}, ["Label 1"]],
]
这没有按预期工作并引发:
DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
y = column_or_1d(y, warn=True)
One-vs-rest accuracy percent: 0.0
文档试图说明的是,使用二维矩阵作为目标。所以基本上,你的训练集可以是,
training_set = [
[{"car": True, ...}, [is_label_1, is_label_2, is_label_3]],
[{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
...
[{"car": False, ...}, [is_label_1, is_label_2, is_label_3]],
]
对于特定样本,使用多个标签对其进行训练, 例如对于第一个样本,如果存在标签 1 和标签 3,则将其作为 [1, 0, 1].
传递希望,答案对你来说很清楚。
我通过摆脱 NLTK 到 scikit-learn 适配器并导入一个 NLTK 模块来帮助我将我的数据结构转换为可提供给 scikit-learn OneVsRestClassifier 的东西来解决这个问题。
from nltk import compat
from sklearn.feature_extraction import DictVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.multiclass import OneVsRestClassifier
_vectorizer = DictVectorizer(dtype=float, sparse=True)
def prepare_scikit_x_and_y(labeled_featuresets):
X, y = list(compat.izip(*labeled_featuresets))
X = _vectorizer.fit_transform(X)
set_of_labels = []
for label in y:
set_of_labels.append(set(label))
y = self.mlb.fit_transform(set_of_labels)
return X, y
def train_classifier(labeled_featuresets):
X, y = prepare_scikit_x_and_y(labeled_featuresets)
classifier.fit(X, y)
training_set = [
[{"car": True, ...}, ["Label 1"]],
[{"car": False, ...}, ["Label 2"]],
...
[{"car": False, ...}, ["Label 1"]],
]
ovr = OneVsRestClassifier(MultinomialNB())
ovr.train(training_set)
快乐豆