Подтвердить что ты не робот

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]

Кто-нибудь знает отношения между этими предсказывающими и решающими функциями?

4b9b3361

Ответ 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), и предсказание даст класс с лучшим результатом.