Как заменить ядро ​​svm.SVR 'rbf' в sklearn, используя мою собственную функцию RBF? - PullRequest
0 голосов
/ 20 апреля 2019

Я разработал код ниже для запуска проекта для метода SVM:

import numpy as np
import pandas as pd

from sklearn import svm
from sklearn.datasets import load_boston
from sklearn.metrics import mean_absolute_error

housing = load_boston()
df = pd.DataFrame(np.c_[housing['data'], housing['target']],
              columns= np.append(housing['feature_names'], ['target']))

features = df.columns.tolist()
label = features[-1]
features = features[:-1]

x_train = df[features].iloc[:400]
y_train = df[label].iloc[:400]

x_test = df[features].iloc[400:]
y_test = df[label].iloc[400:]

svr = svm.SVR(kernel='rbf')
svr.fit(x_train, y_train)
y_pred = svr.predict(x_test)

print(mean_absolute_error(y_pred, y_test))

Теперь я хочу использовать мое настроенное ядро ​​rbf:

def my_rbf(feat, lbl):
#feat = feat.values
    #lbl = lbl.values
    ans = np.array([])
    gamma = 0.000005
    for i in range(len(feat)):
        ans = np.append(ans, np.exp(-gamma * np.dot(feat[i]-lbl[i], feat[i]-lbl[i])))

    return ans

Затем я изменил svm.SVR(kernel=my_rbf) Но я получаю множество ошибок, когда модифицирую его любым способом. Я также попытался использовать простую функцию, такую ​​как np.dot(feat-lbl,feat-lbl), которая прекрасно работала в методе SVR.fit, но в svr.predict произошла ошибка, которая говорила, что форма входной матрицы должна быть похожа на [n_samples_test, n_samples_train].

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

Ответы [ 2 ]

1 голос
/ 20 апреля 2019

Пользовательский метод ядра my_rbf, который вы кодировали, использует и X (функции), и y (метки).Вы не можете оценить эту функцию во время прогнозов, поскольку у вас нет доступа к меткам.Кастомное ядро, если оно некорректно*enter image description here

, где x и x' - два векторных признака (X).

Пусть H(X) - это функция с преобразованием вектора X в другое измерение (обычно в очень очень высокое измерение).SVM необходимо рассчитать скалярное произведение между всеми комбинациями векторов признаков (т. Е. Всеми H(X)).Так что если H(X1) . H(X2) = K(X1, X2), то K называется функцией ядра или кернализацией H.Таким образом, вместо преобразования точек X1 и X2 в очень высокие измерения и вычисления точечного произведения там, K вычисляет их непосредственно из X1 и X2.

Заключение my_rbf не является допустимой функцией ядра просто потому, что использует метки (Y s).Это должно быть только на характерных векторах.

0 голосов
/ 22 апреля 2019

Согласно этому источнику , функция RBF, которую я искал (принимает тренировочные навыки как X и тестирует функции как X 'как входные данные) и выводит [n_training_samples, n_testing_samples], как более подробно объяснено в docs , это что-то вроде этого:

def my_kernel(X,Y):
    K = np.zeros((X.shape[0],Y.shape[0]))
    for i,x in enumerate(X):
        for j,y in enumerate(Y):
            K[i,j] = np.exp(-1*np.linalg.norm(x-y)**2)
    return K

clf=SVR(kernel=my_kernel)

, что в точности равно:

clf=SVR(kernel="rbf",gamma=1)

С точки зрения скорости ему не хватает производительности, столь же эффективной, как у svm-библиотеки по умолчанию rbf.,Было бы полезно использовать статическую типизацию библиотеки cython для индексов, а также использовать memory-views для массивов с пустым фрагментом, чтобы немного его ускорить.

...