如何获取特征的权重

时间:2014-01-21 14:19:47

标签: python machine-learning svm scikit-learn libsvm

我正在处理高度不平衡的数据集,我的想法是从我的 libSVM 模型中获取要素权重值。至于现在,我可以使用线性内核,在那里我可以获得特征权重,但是当我使用rbfpoly时,我无法实现我的目标。

这里我使用sklearn作为我的模型,使用.coef_很容易获得线性内核的特征权重。任何人都可以帮助我为rbfpoly做同样的事吗?我到目前为止尝试做的事情如下:

svr = SVC(C=10, cache_size=200, class_weight='auto', coef0=0.0, degree=3.0, gamma=0.12,kernel='rbf', max_iter=-1, probability=True, random_state=0,shrinking=True, tol=0.001, verbose=False)
clf = svr.fit(data_train,target_train)
print clf.coef_

2 个答案:

答案 0 :(得分:13)

这不仅是不可能的,如documentation

中所述
  

符合特征的权重(原始问题中的系数)。这仅适用于线性内核。

但也没有意义。在线性SVM中,生成的分离平面与输入要素位于同一空间中。因此,其系数可视为输入“维度”的权重。

在其他内核中,分离平面存在于另一个空间中 - 原始空间的内核转换的结果。其系数与输入空间没有直接关系。事实上,对于rbf内核,变换后的空间是无限维的(当然,你可以在这个on Wikipedia得到一个起点)。

答案 1 :(得分:1)

我遇到了类似的问题,但原因不同。 我的目标是不使用内置的 SVC.predict 来计算推理。 假设:

import numpy as np
from sklearn.svm import SVC

X = np.array([[3, 4], [1, 4], [2, 3], [6, -1], [7, -1], [5, -3]])
y = np.array([-1, -1, -1, 1, 1, 1])

clf = SVC(C=1e5, kernel='linear')
clf.fit(X, y)

我想仅使用代数计算训练模型的预测。 现在线性推理的公式很简单:

enter image description here

其中 \alpha_jy_jx_j 统称为权重。让事情变得超级简单的是 clf.coef_ 为您提供权重。 所以:

w = clf.coef_
b = clf.intercept_

assert np.sign(w.dot(X[0]) + b)[0] == clf.predict(X[0].reshape((1, 2)))

旁注:乘法之和正是 dot 对两个向量所做的,并且输入向量需要 reshape 以符合预期的 predict 输入形状。

当然,对于其他内核来说,比这更复杂,从这个公式enter image description here 和之前的答案我们无法预先计算权重,因为 \alpha_jy_jK(x,x_j) 都联系在一起。

现在,在我从朋友那里得到一些帮助之前,我一直陷入困境。 谁发现了这个documentation page。它说 \alpha_jy_j 在 scikit learn 术语中是 clf.dual_coef_。 一旦你知道这个等式也变得简单了。

我们现在知道 \alpha_jy_j 的值。剩下要做的一件事是计算核函数,这取决于核的类型,对于 3 阶多项式核(这是 scikit 中 poly SVM 的默认次数)K(x,x_j) 大致转换为 {{1} }. **

现在让我们将所学的所有内容结合到此代码片段中:

np.power(clf.support_vectors_.dot(X), clf.degree)

如果你运行它,你会看到断言正在通过,哇哦!我们现在可以在不使用 import numpy as np from sklearn.svm import SVC X = np.array([[3, 4], [1, 4], [2, 3], [6, -1], [7, -1], [5, -3]]) y = np.array([-1, -1, -1, 1, 1, 1]) clf = SVC(kernel='poly', gamma=1) clf.fit(X, y) print('b = ', clf.intercept_) print('Indices of support vectors = ', clf.support_) print('Support vectors = ', clf.support_vectors_) print('Number of support vectors for each class = ', clf.n_support_) print('Coefficients of the support vector in the decision function = ', np.abs(clf.dual_coef_)) negative_prediction = clf.dual_coef_.dot(np.power(clf.gamma * clf.support_vectors_.dot(X[0]), clf.degree)) + clf.intercept_ positive_prediction = clf.dual_coef_.dot(np.power(clf.gamma * clf.support_vectors_.dot(X[4]), clf.degree)) + clf.intercept_ print('Compare both results') print(negative_prediction, clf.decision_function(X[0].reshape((1, 2)))) print(positive_prediction, clf.decision_function(X[4].reshape((1, 2)))) assert np.sign(negative_prediction) == clf.predict(X[0].reshape((1, 2))) assert np.sign(positive_prediction) == clf.predict(X[4].reshape((1, 2))) 的情况下预测结果,我希望它可以帮助解决所提出的问题。从现在开始,您可以像调整权重一样调整双系数。

** 但是请注意,如果您不使用伽马,请将其从“手动计算”中删除,否则它会崩溃。此外,它是多项式内核推理的一个例子,对于其他内核,推理函数应相应调整。 See documentation

  • Source 用于公式快照以及有关 SVM 的更多信息。
  • Relevant scikit learn documentation
  • 代码片段基于我在 stackoverflow 上看到的内容,但我丢失了源链接。所以我要感谢并感谢原作者(一旦我找到他)。