Предпочитаемые ядра Libsvm

Я использую libsvm с предварительно вычисленными ядрами. Я сгенерировал предварительно вычисленный файл ядра для примера набора данных heart_scale и выполнил svm-train. Он работал должным образом, и поддерживающие векторы были идентифицированы правильно, т.е. Аналогично неперечисленной версии.

Однако, когда я пытаюсь запустить svm-pred, он дал разные результаты для файла с предварительно вычисленной моделью. После копания кода я заметил, что функция svm_predict_values ​​() требует реальных функций векторов поддержки, которые недоступны в предварительно вычисленном режиме. В предвычисленном режиме, у нас есть только коэффициент и индекс каждого вектора поддержки, который ошибочно принимает за его особенности с помощью SVM предсказуемых.

Является ли это ошибкой или проблемой с моим пониманием. Если это ошибка с моей стороны, сообщите мне, как запустить svm-pred в предварительно вычисленном режиме.

Ответ 1

Значения оценки ядра между вектором тестового набора, x и каждым вектором обучающего набора должны использоваться как вектор функций набора тестов.

Вот соответствующие строки из файла libsvm readme:

Новый учебный пример для xi:
  <label> 0: я 1: K (xi, x1)... L: K (xi, xL)

Новый тестовый экземпляр для любого x:
  <label> 0:? 1: K (x, x1)... L: K (x, xL)

В файле libsvm readme говорится, что если у вас есть L обучающих наборов векторов, где xi - вектор набора тренировок с я из [1..L] и вектор набора тестов x, то вектор функции для x должен быть

< метка x > 0: < любое число > 1: K (x ^ {тест}, x1 ^ {поезд}), 2: K (x ^ {тест}, x2 ^ {поезд})... L: K (x ^ {test}, xL ^ {train})

где K (u, v) используется для обозначения вывода функции ядра on с векторами u и v в качестве аргументов.

Я включил некоторый пример кода python ниже.

Результаты первоначального представления вектора признаков и предварительно вычислимого (линейного) ядра не совсем то же самое, но это, вероятно, связано с различиями в алгоритме оптимизации.

from svmutil import *
import numpy as np

#original example
y, x = svm_read_problem('.../heart_scale')
m = svm_train(y[:200], x[:200], '-c 4')
p_label, p_acc, p_val = svm_predict(y[200:], x[200:], m)

##############
#train the SVM using a precomputed linear kernel

#create dense data
max_key=np.max([np.max(v.keys()) for v in x])
arr=np.zeros( (len(x),max_key) )

for row,vec in enumerate(x):
    for k,v in vec.iteritems():
        arr[row][k-1]=v
x=arr

#create a linear kernel matrix with the training data
K_train=np.zeros( (200,201) )
K_train[:,1:]=np.dot(x[:200],x[:200].T)
K_train[:,:1]=np.arange(200)[:,np.newaxis]+1

m = svm_train(y[:200], [list(row) for row in K_train], '-c 4 -t 4')

#create a linear kernel matrix for the test data
K_test=np.zeros( (len(x)-200,201) )
K_test[:,1:]=np.dot(x[200:],x[:200].T)
K_test[:,:1]=np.arange(len(x)-200)[:,np.newaxis]+1

p_label, p_acc, p_val = svm_predict(y[200:],[list(row) for row in K_test], m)