我正在尝试用SVM进行多标签分类。我有近8k个特征,也有近400个长度的y向量。我已经对Y向量进行了二值化,所以我并没有使用MultiLabelBinarizer()
,但当我将其与Y数据的原始形式一起使用时,它仍然会给出相同的结果。
我正在运行这个代码:
X = np.genfromtxt('data_X', delimiter=";")
Y = np.genfromtxt('data_y', delimiter=";")
training_X = X[:2600,:]
training_y = Y[:2600,:]
test_sample = X[2600:2601,:]
test_result = Y[2600:2601,:]
classif = OneVsRestClassifier(SVC(kernel='rbf'))
classif.fit(training_X, training_y)
print(classif.predict(test_sample))
print(test_result)
在所有的拟合过程之后,当涉及到预测部分时,它说Label not x is present in all training examples
(x是我的y向量长度400范围内的几个不同的数字)。然后,它给出了预测的y向量,该向量总是长度为400的零向量(y向量长度)。我是scikit学习和机器学习的新手。我想不通这里的问题。问题出在哪里?我该怎么办?谢谢
这里有两个问题:
1) 缺少标签警告
2) 你得到了所有0的预测
该警告意味着您的某些类在培训数据中丢失。这是一个常见的问题。如果您有400个类,那么其中一些类必须很少出现,并且在任何数据分割中,某些类可能会从分割的一侧丢失。可能还有一些类根本不会出现在您的数据中。你可以尝试Y.sum(axis=0).all()
,如果它是False,那么有些类甚至不会出现在Y中。这听起来很可怕,但实际上,你无论如何都无法正确预测出现0、1或任何非常小次数的类,所以预测0可能是你能做的最好的事情。
至于全0预测,我要指出的是,对于400个类,可能你所有的类出现的时间都不到一半。您可以检查Y.mean(axis=0).max()
以获得最高标签频率。如果有400个班,可能只有百分之几。如果是这样的话,必须对每个类进行0-1预测的二进制分类器可能会为所有实例上的所有类选择0。这并不是一个真正的错误,只是因为所有的类频率都很低。
如果您知道每个实例都有一个正标签(至少一个),那么您可以获得决策值(clf.decision_function
),并为每个实例选择具有最高标签的类。不过,您必须编写一些代码才能做到这一点。
我曾经在一场类似的Kaggle比赛中取得过前十名的成绩。这是一个多标签问题,大约有200个类别,甚至没有一个类别的频率为10%,我们需要0-1个预测。在这种情况下,我得到了决策值,并取了最高的一个,加上任何超过阈值的值。我选择了在坚持比赛中效果最好的门槛。该条目的代码在Github上:Kaggle希腊媒体代码。你可以看看。
如果你能走到这一步,谢谢你的阅读。希望能有所帮助。