我正在尝试理解decision_function和predict之间的关系,它们是SVC的实例方法(http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)。到目前为止,我已经收集到决策函数返回类之间的成对分数。我的印象是预测选择最大化其成对分数的类,但我测试了它并得到了不同的结果。这是我用来尝试理解两者之间关系的代码。首先我生成了成对分数矩阵,然后我打印出了具有最大配对分数的类,该分数与clf.predict预测的类不同。
result = clf.decision_function(vector)[0]
counter = 0
num_classes = len(clf.classes_)
pairwise_scores = np.zeros((num_classes, num_classes))
for r in xrange(num_classes):
for j in xrange(r + 1, num_classes):
pairwise_scores[r][j] = result[counter]
pairwise_scores[j][r] = -result[counter]
counter += 1
index = np.argmax(pairwise_scores)
class = index_star / num_classes
print class
print clf.predict(vector)[0]
有谁知道这些预测与决策功能之间的关系?
答案 0 :(得分:26)
我不完全理解您的代码,但让我们通过您引用的文档页面的示例:
import numpy as np
X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])
from sklearn.svm import SVC
clf = SVC()
clf.fit(X, y)
现在让我们将决策函数和预测应用于样本:
clf.decision_function(X)
clf.predict(X)
我们获得的输出是:
array([[-1.00052254],
[-1.00006594],
[ 1.00029424],
[ 1.00029424]])
array([1, 1, 2, 2])
这很容易理解:desion函数告诉我们分类器生成的超平面的哪一侧(以及我们离它多远)。根据该信息,估算器然后用相应的标签标记示例。
答案 1 :(得分:14)
当您调用decision_function()
时,您将获得每个成对分类器的输出(总共n *(n-1)/ 2个数字)。请参阅pages 127 and 128 of "Support Vector Machines for Pattern Classification"。
每个分类器对正确答案是什么进行投票(基于该分类器输出的符号); predict()
返回投票最多的班级。
答案 2 :(得分:13)
对于那些感兴趣的人,我将发布一个从C ++(here)翻译成predict
函数的快速示例到python:
# I've only implemented the linear and rbf kernels
def kernel(params, sv, X):
if params.kernel == 'linear':
return [np.dot(vi, X) for vi in sv]
elif params.kernel == 'rbf':
return [math.exp(-params.gamma * np.dot(vi - X, vi - X)) for vi in sv]
# This replicates clf.decision_function(X)
def decision_function(params, sv, nv, a, b, X):
# calculate the kernels
k = kernel(params, sv, X)
# define the start and end index for support vectors for each class
start = [sum(nv[:i]) for i in range(len(nv))]
end = [start[i] + nv[i] for i in range(len(nv))]
# calculate: sum(a_p * k(x_p, x)) between every 2 classes
c = [ sum(a[ i ][p] * k[p] for p in range(start[j], end[j])) +
sum(a[j-1][p] * k[p] for p in range(start[i], end[i]))
for i in range(len(nv)) for j in range(i+1,len(nv))]
# add the intercept
return [sum(x) for x in zip(c, b)]
# This replicates clf.predict(X)
def predict(params, sv, nv, a, b, cs, X):
''' params = model parameters
sv = support vectors
nv = # of support vectors per class
a = dual coefficients
b = intercepts
cs = list of class names
X = feature to predict
'''
decision = decision_function(params, sv, nv, a, b, X)
votes = [(i if decision[p] > 0 else j) for p,(i,j) in enumerate((i,j)
for i in range(len(cs))
for j in range(i+1,len(cs)))]
return cs[max(set(votes), key=votes.count)]
predict
和decision_function
有很多输入参数,但请注意,在调用predict(X)
时,模型内部都会使用这些参数。实际上,在拟合之后,模型内的所有参数都可以访问:
# Create model
clf = svm.SVC(gamma=0.001, C=100.)
# Fit model using features, X, and labels, Y.
clf.fit(X, y)
# Get parameters from model
params = clf.get_params()
sv = clf.support_vectors
nv = clf.n_support_
a = clf.dual_coef_
b = clf._intercept_
cs = clf.classes_
# Use the functions to predict
print(predict(params, sv, nv, a, b, cs, X))
# Compare with the builtin predict
print(clf.predict(X))
答案 3 :(得分:11)
datascience.sx上的多级一对一场景有一个really nice Q&A:
我有一个多类SVM分类器,标签为'A','B','C','D'。
这是我正在运行的代码:
>>>print clf.predict([predict_this]) ['A'] >>>print clf.decision_function([predict_this]) [[ 185.23220833 43.62763596 180.83305074 -93.58628288 62.51448055 173.43335293]]
如何使用决策函数的输出来预测类 (A / B / C / D)概率最高,如果可能,它的价值是多少?一世 已经访问了https://stackoverflow.com/a/20114601/7760998,但确实如此 对于二元分类器而言,找不到一个好的资源 解释了多类分类器的decision_function输出 形状卵(一对一)。
修改强>
以上示例适用于“A”类。对于另一个输入分类器 预测'C'并在decision_function中给出以下结果
[[ 96.42193513 -11.13296606 111.47424538 -88.5356536 44.29272494 141.0069203 ]]
对于分类器预测为“C”的另一个不同输入 来自decision_function,
的以下结果[[ 290.54180354 -133.93467605 116.37068951 -392.32251314 -130.84421412 284.87653043]]
如果它是ovr(一对一休息),选择它会变得更容易 一个值较高,但在卵内(一对一),结果列表中有
(n * (n - 1)) / 2
个值。如何推断根据决定选择哪个班级 功能
你的链接有足够的资源,所以让我们通过:
当您调用decision_function()时,您将获得每个成对分类器的输出(总共n *(n-1)/ 2个数字)。见第127页和 128“用于模式分类的支持向量机”。
单击“第127和128页”链接(此处未显示,但在 Stackoverflow答案)。你应该看到:
- Python的SVM实现使用one-vs-one。这正是本书所讨论的内容。
- 对于每个成对比较,我们测量决策函数
- 决策函数只是常规二进制SVM决策边界
这与你的问题有什么关系?
- clf.decision_function()会为每个成对比较提供$ D $
- 获得最多选票的班级
例如,
[[96.42193513 -11.13296606 111.47424538 -88.5356536 44.29272494 141.0069203]]
正在比较:
[AB,AC,AD,BC,BD,CD]
我们用符号标记每一个。我们得到:
[A,C,A,C,B,C]
例如,96.42193513是正数,因此A是AB的标签。
现在我们有三个C,C将是你的预测。如果你重复我的 另外两个例子的程序,你会得到Python的 预测。试试吧!
答案 4 :(得分:1)
Predict()遵循成对投票方案,该方案返回所有成对比较中投票数最多的类。当两个类别的分数相同时,将返回索引最低的类别。
在下面的Python示例中,该示例将此投票方案应用于(n *(n-1)/ 2成对得分,由一对一的Decision_function()返回)。
from sklearn import svm
from sklearn import datasets
from numpy import argmax, zeros
from itertools import combinations
# do pairwise comparisons, return class with most +1 votes
def ovo_vote(classes, decision_function):
combos = list(combinations(classes, 2))
votes = zeros(len(classes))
for i in range(len(decision_function[0])):
if decision_function[0][i] > 0:
votes[combos[i][0]] = votes[combos[i][0]] + 1
else:
votes[combos[i][1]] = votes[combos[i][1]] + 1
winner = argmax(votes)
return classes[winner]
# load the digits data set
digits = datasets.load_digits()
X, y = digits.data, digits.target
# set the SVC's decision function shape to "ovo"
estimator = svm.SVC(gamma=0.001, C=100., decision_function_shape='ovo')
# train SVC on all but the last digit
estimator.fit(X.data[:-1], y[:-1])
# print the value of the last digit
print("To be classified digit: ", y[-1:][0])
# print the predicted class
pred = estimator.predict(X[-1:])
print("Perform classification using predict: ", pred[0])
# get decision function
df = estimator.decision_function(X[-1:])
# print the decision function itself
print("Decision function consists of",len(df[0]),"elements:")
print(df)
# get classes, here, numbers 0 to 9
digits = estimator.classes_
# print which class has most votes
vote = ovo_vote(digits, df)
print("Perform classification using decision function: ", vote)
答案 5 :(得分:0)
他们可能有一些复杂的数学关系。但是,如果您在decision_function
分类器中使用LinearSVC
,则这两者之间的关系将更加明确!因为那时decision_function
将为每个类标签(与SVC不同)给出分数,并且预测将为该类提供最佳分数。