Scikit Узнать SVC decision_function и предсказать
Я пытаюсь понять взаимосвязь между decision_function и прогнозом, которые являются методами экземпляра 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]
Кто-нибудь знает отношения между этими предсказывающими и решающими функциями?
Ответы
Ответ 1
Я не совсем понимаю ваш код, но отпустил пример страницы с документацией, на которую вы ссылались:
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 говорит нам, на какой стороне гиперплоскости, порожденной классификатором мы (и насколько далеко мы от него). На основе этой информации оценщик затем маркирует примеры соответствующей меткой.
Ответ 2
Когда вы вызываете decision_function()
, вы получаете результат от каждого из парных классификаторов (общее число n * (n-1)/2). См. страницы 127 и 128 "Поддержка векторных машин для классификации шаблонов" .
Каждый классификатор ставит вопрос о правильном ответе (на основе знака выхода этого классификатора); predict()
возвращает класс с наибольшим количеством голосов.
Ответ 3
Для тех, кто заинтересован, я отправлю быстрый пример функции 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))
Ответ 4
Там действительно приятный Q & A для многоклассового сценария one-vs-one на datascience.sx:
Вопрос
У меня есть многоклассовый классификатор 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) с наивысшей вероятностью и, если возможно, значения? Я посетил fooobar.com/questions/156210/... но он предназначен для двоичных классификаторов и не смог найти хороший ресурс, который объясняет вывод решения_функции для многоклассовых классификаторов с формой ovo (one-vs-one).
Редактировать:
Вышеприведенный пример относится к классу "А". Для другого ввода классификатор предсказал "C" и дал следующий результат в решении_функции
[[ 96.42193513 -11.13296606 111.47424538 -88.5356536 44.29272494 141.0069203 ]]
Для другого другого ввода, который классификатор, предсказанный как "C", дал следующий результат от функции принятия решения,
[[ 290.54180354 -133.93467605 116.37068951 -392.32251314 -130.84421412 284.87653043]]
Если бы это было ovr (one-vs-rest), стало бы легче выбрать вариант с более высоким значением, но в ovo (one-vs-one) есть (n * (n - 1))/2
значения в итоговый список.
Как определить, какой класс будет выбран на основе функции принятия решения?
Ответ
У вашей ссылки достаточно ресурсов, поэтому отпустите:
Когда вы вызываете решение_функции(), вы получаете результат от каждого из парных классификаторов (общее число n * (n-1)/2). См. Стр. 127 и 128 "Машины поддержки векторов для классификации шаблонов".
Нажмите ссылку "страница 127 и 128" (здесь не показано, но в ответе на Stackoverflow). Тебе следует увидеть:
![enter image description here]()
- Реализация Python SVM использует один-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. Попробуй!
Ответ 5
Вероятно, они имеют немного сложное математическое отношение. Но если вы используете классификатор decision_function
in LinearSVC
, связь между этими двумя будет более понятной! Потому что тогда decision_function
даст вам оценки для каждого ярлыка класса (не так же, как SVC), и предсказание даст класс с лучшим результатом.