SVCのインスタンスメソッドであるdecision_functionとpredictの関係を理解しようとしています( http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html )。これまでのところ、決定関数がクラス間のペアワイズスコアを返すことを収集しました。私は、predictはペアワイズスコアを最大化するクラスを選択するという印象を受けていましたが、これをテストしてさまざまな結果を得ました。以下は、2つの関係を理解するために使用していたコードです。まず、ペアワイズスコアマトリックスを生成し、次に、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]
誰もこれらの予測と決定関数の関係を知っていますか?
私はあなたのコードを完全には理解していませんが、あなたが参照したドキュメントページの例を見てみましょう。
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関数は、分類器によって生成された超平面のどちら側にいるか(および、そこからどれだけ離れているか)を示します。その情報に基づいて、推定器は対応するラベルで例をラベル付けします。
decision_function()
を呼び出すと、ペアワイズ分類器のそれぞれから出力が得られます(n *(n-1)/ 2個の合計数)。 「パターン分類のサポートベクターマシン」の127ページと128ページ を参照してください。
各分類子は、(その分類子の出力の符号に基づいて)正解が何であるかについて投票を行います。 predict()
は、投票数が最も多いクラスを返します。
興味がある人のために、C++( here )からpythonに変換されたpredict
関数の簡単な例を投稿します。
_# 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))
_
Datascience.sxのマルチクラスone-vs-oneシナリオには 本当に素晴らしいQ&A があります:
ラベル「A」、「B」、「C」、「D」のマルチクラスSVM分類器があります。
これは私が実行しているコードです:
>>>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 を訪れましたが、それはバイナリ分類器用であり、形状ovo(1つ-vs-one)。
編集:
上記の例はクラス「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(one-vs-rest)であれば、より高い値を選択することで簡単になりますが、ovo(one-vs-one)には
(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のラベルです。
これで3つのCがあります。Cはあなたの予測です。他の2つの例に対して私の手順を繰り返すと、Pythonの予測が得られます。それを試してみてください!
それらはおそらく少し複雑な数学的関係を持っています。ただし、decision_function
LinearSVC
分類子では、これら2つの間の関係がより明確になります。なぜならdecision_function
は各クラスラベル(SVCとは異なります)のスコアを提供し、predictはクラスに最高のスコアを提供します。