我正在尝试使用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(向量长度)。
我是scikit-learn和机器学习的新手。我无法弄清楚这里的问题。有什么问题,我该怎么做才能解决它?
感谢。
答案 0 :(得分:14)
这里有两个问题:
1)缺少标签警告
2)你得到预测的全部0
警告意味着训练数据中缺少某些课程。这是一个常见问题。如果您有400个类,那么其中一些类只能很少出现,并且在数据的任何拆分中,某些类可能会从拆分的一侧丢失。可能还有一些课程根本不会出现在您的数据中。您可以尝试Y.sum(axis=0).all()
,如果这是假的,那么即使在Y中也不会发生某些类。这听起来很糟糕,但实际上,您无法正确预测出现0的类,无论如何,或者任何非常少的次数,因此预测0可能是你可以做的最好的。
对于全0预测,我指出,对于400个课程,可能所有课程的发生时间都不到一半。您可以检查Y.mean(axis=0).max()
以获得最高的标签频率。有400个课程,可能只有几个百分点。如果是这样,必须对每个类进行0-1预测的二进制分类器可能会为所有实例上的所有类选择0。这不是一个真正的错误,只是因为所有的班级频率都很低。
如果您知道每个实例都有一个正面标签(至少一个),您可以获得决策值(clf.decision_function
)并为每个实例选择一个具有最高值的类。但是,您必须编写一些代码来执行此操作。
我曾经在与此类似的Kaggle比赛中获得前10名。这是一个有大约200个类的多标签问题,即使频率为10%也没有发生,我们需要0-1个预测。在那种情况下,我得到了决策值并取得了最高值,加上任何高于阈值的值。我选择了在保持集合上效果最好的阈值。该条目的代码在Github上:Kaggle Greek Media code。你可以看看它。
如果你做到这一点,感谢阅读。希望有所帮助。