使用 SVM 进行分类

Posted

技术标签:

【中文标题】使用 SVM 进行分类【英文标题】:Classification using SVM 【发布时间】:2016-12-01 08:59:48 【问题描述】:

为了对文本进行分类,我想使用 SVM。 我想将测试数据分类到标签之一(健康/成人) 训练和测试数据是文本文件

我正在使用 python 的 scikit 库。 当我将文本保存到 txt 文件时,我将其编码为 utf-8 这就是我在sn-p中解码它们的原因。 这是我尝试的代码

String = String.decode('utf-8')
String2 = String2.decode('utf-8')
bigram_vectorizer = CountVectorizer(ngram_range=(1, 2),
                                     token_pattern=r'\b\w+\b', min_df=1)

X_2 = bigram_vectorizer.fit_transform(String2).toarray()
X_1 = bigram_vectorizer.fit_transform(String).toarray()
X_train = np.array([X_1,X_2])
print type(X_train)
y = np.array([1, 2])
clf = SVC()
clf.fit(X_train, y)

#prepare test data
print(clf.predict(X))

这是我遇到的错误

  File "/Users/guru/python_projects/implement_LDA/lda/apply.py", line 107, in <module>
    clf.fit(X_train, y)
  File "/Users/guru/python_projects/implement_LDA/lda/lib/python2.7/site-packages/sklearn/svm/base.py", line 150, in fit
    X = check_array(X, accept_sparse='csr', dtype=np.float64, order='C')
  File "/Users/guru/python_projects/implement_LDA/lda/lib/python2.7/site-packages/sklearn/utils/validation.py", line 373, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: setting an array element with a sequence.

当我搜索错误时,我发现了一些结果,但它们甚至没有帮助。我认为我在应用 SVM 模型时在逻辑上是错误的。有人可以给我一个提示吗?

参考:[1][2]

【问题讨论】:

【参考方案1】:

您必须组合您的样本,将它们矢量化,然后拟合分类器。像这样:

String = String.decode('utf-8')
String2 = String2.decode('utf-8')
bigram_vectorizer = CountVectorizer(ngram_range=(1, 2),
                                     token_pattern=r'\b\w+\b', min_df=1)

X_train = bigram_vectorizer.fit_transform(np.array([String, String2]))
print type(X_train)
y = np.array([1, 2])
clf = SVC()
clf.fit(X_train, y)

#prepare test data
print(clf.predict(bigram_vectorizer.transform(np.array([X1, X2, ...]))))

但是 2 个样本是非常少量的数据,因此您的预测可能不准确。

已编辑:

您还可以使用 Pipeline 一步将转换和分类结合起来。

from sklearn.pipeline import Pipeline

print type(X_train) # Should be a list of texts length 100 in your case
y_train = ... # Should be also a list of length 100
clf = Pipeline([
    ('transformer', CountVectorizer(...)),
    ('estimator', SVC()),
])
clf.fit(X_train, y_train)

X_test = np.array(["sometext"]) # array of test texts length = 1
print(clf.predict(X_test))

【讨论】:

好的,非常感谢 但是我有两个疑问如果我在代码的最后一行(在 clf.predict() 中)只通过 1 个测试字符串,例如 clf.predict(bigram_vectorizer.transform(corpus ))) 那么我得到的输出为 [1,1,1....1,1,1] 为什么? 这是因为vectorizer接受序列并且字符串也是序列。你必须像这样重塑你的输入:...transform(np.array([corpus])) 我的预测非常错误,您能建议一些改进的技术吗?除了收集更多我可以在同一个 SVM 模型中即兴创作的数据之外?自定义停用词列表应该有帮助吗? 而且你说的是训练集或测试集的数据量很少? @Guru 首先,根据两个样本拟合的模型进行任何预测是不够的。您需要更多数据进行训练。预测实际上不会训练您的模型,而只会进行拟合。也许如果你解释一下你的任务,我可以给你任何建议。

以上是关于使用 SVM 进行分类的主要内容,如果未能解决你的问题,请参考以下文章

使用 SVM 进行分类

在 CNN 提取特征之上使用 SVM - 如何进行多类分类?

如何使用卡方值使用 SVM 进行文本分类?

Matlab:使用 SVM 对多类分类问题进行预测

使用 SVM 对多维输出类进行分类时出现值错误

使用预制字典进行文本分类的SVM特征向量表示