我尝试使用 scikit-learn 中的 Pipeline\onevsrest 分类器实现多标签分类。代码如下,但首先让我提一下,我从 pandas 数据帧构建了多标签示例。
代码如下:
df = pd.read_csv(fileIn, header = 0, encoding='utf-8-sig')
rows = random.sample(df.index, int(len(df) * 0.9))
work = df.ix[rows]
work_test = df.drop(rows)
X_train = []
y_train = []
X_test = []
y_test = []
for i in work[[i for i in list(work.columns.values) if i.startswith('Change')]].values:
X_train.append(','.join(i.T.tolist()))
X_train = np.array(X_train)
for i in work[[i for i in list(work.columns.values) if i.startswith('Corax')]].values:
y_train.append(list(i))
for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Change')]].values:
X_test.append(','.join(i.T.tolist()))
X_test = np.array(X_test)
for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Corax')]].values:
y_test.append(list(i))
lb = preprocessing.MultiLabelBinarizer()
Y = lb.fit_transform(y_train)
classifier = Pipeline([('vectorizer', CountVectorizer()),('tfidf', TfidfTransformer()),('clf', OneVsRestClassifier(SVC(kernel='rbf')))])
classifier.fit(X_train, Y)
predicted = classifier.predict(X_test)
但问题是,当您使用这组转换时:CountVectorizer -> TfidfTransformer
您会得到一个稀疏矩阵。问题是,当您尝试使用 OneVsRest 分类器预测标签时,它会查找 decision_function
或 predict_proba
方法。除非您指定 probability=True
,否则 predict_proba
在 svm.SVC
上不可用。另一方面,正如我在代码中看到的,决策函数并未针对稀疏矩阵实现。因此我的代码失败了,因为这两个必需的方法都不可用。但也许我做错了什么?是否有可能以某种方式使用 svm.SVC 实现多标签分类而不指定 probability=True?(这样做会给分类器训练增加一些显着的开销),也许通过某种方式强制 TfidfTransformer输出密集矩阵而不是稀疏矩阵?
最佳答案
这是一个well-known issue到目前为止,还不存在简单的解决方案。
您可以使用Pipeline “致密”稀疏数据(通过调用 .toarray
),但这可能会增加内存消耗。你可以做TruncatedSVD (据我所知,这是唯一适用于稀疏数据的降维方法),但它可能会扰乱您的数据,从而导致 SVM 的性能下降。
关于python - scikit-learn - 使用 svm.svc 分类器进行多标签分类,是否可以在没有probability=True的情况下进行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27389019/