Python 3 и Sklearn: Сложность использования модели NOT-sklearn в качестве модели sklearn - PullRequest
0 голосов
/ 16 февраля 2020

Код ниже работает. У меня есть только процедура для запуска схемы перекрестной проверки с использованием линейной модели, ранее определенной в sklearn. У меня нет проблем с этим. Моя проблема в том, что: если я заменю код model=linear_model.LinearRegression() на model=RBF('multiquadric') (см. Строки 14 и 15 в __main__, он больше не работает. Так что моя проблема на самом деле в классе RBF, где я пытаюсь mimi c модель sklearn.

Если я заменю код, описанный выше, я получаю следующую ошибку:

  FitFailedWarning)
/home/daniel/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_validation.py:536: FitFailedWarning: Estimator fit failed. The score on this train-test partition for these parameters will be set to nan. Details: 
ValueError: All arrays must be equal length.

  FitFailedWarning)

1) Должен ли я определить функцию оценки в классе RBF?

2) Как это сделать? Я потерян. Так как я унаследовал BaseEstimator и RegressorMixin, я ожидал, что это будет внутренне решено.

3) Чего-то еще не хватает?

from sklearn import datasets
import numpy as np
import pandas as pd
from sklearn import linear_model
from sklearn import model_selection
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from scipy.interpolate import Rbf
np.random.seed(0)
from sklearn.base import BaseEstimator, RegressorMixin



class RBF(BaseEstimator, RegressorMixin):
    def __init__(self,function):
        self.function=function
    def fit(self,x,y):
        self.rbf = Rbf(x, y,function=self.function)
    def predict(self,x):   
        return self.rbf(x)    


if __name__ == "__main__":
    # Load Data
    targetName='HousePrice'
    data=datasets.load_boston()
    featuresNames=list(data.feature_names)
    featuresData=data.data
    targetData = data.target
    df=pd.DataFrame(featuresData,columns=featuresNames)
    df[targetName]=targetData
    independent_variable_list=featuresNames
    dependent_variable=targetName
    X=df[independent_variable_list].values
    y=np.squeeze(df[[dependent_variable]].values)    
    # Model Definition    
    model=linear_model.LinearRegression()
    #model=RBF('multiquadric')    
    # Cross validation routine
    number_splits=5
    score_list=['neg_mean_squared_error','neg_mean_absolute_error','r2']
    kfold = model_selection.KFold(n_splits=number_splits,shuffle=True, random_state=0)
    scalar = StandardScaler()
    pipeline = Pipeline([('transformer', scalar), ('estimator', model)])
    results = model_selection.cross_validate(pipeline, X, y, cv=kfold, scoring=score_list,return_train_score=True)
    for score in score_list:
        print(score+':')
        print('Train: '+'Mean',np.mean(results['train_'+score]),'Standard Error',np.std(results['train_'+score]))
        print('Test: '+'Mean',np.mean(results['test_'+score]),'Standard Error',np.std(results['test_'+score]))

1 Ответ

1 голос
/ 18 февраля 2020

Давайте посмотрим на документацию здесь

* args: массивы

x, y, z,…, d, где x, y, z , ... - это координаты узлов, а d - это массив значений в узлах

Так что он принимает аргумент переменной длины, последним аргументом является значение, равное y в вашем случае. Аргумент k - это k -ые координаты всей точки данных (то же самое для всех остальных аргументов z, y, z, ….

. В соответствии с документацией ваш код должен быть

from sklearn import datasets
import numpy as np
import pandas as pd
from sklearn import linear_model
from sklearn import model_selection
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from scipy.interpolate import Rbf
np.random.seed(0)
from sklearn.base import BaseEstimator, RegressorMixin

class RBF(BaseEstimator, RegressorMixin):
    def __init__(self,function):
        self.function=function
    def fit(self,X,y):        
        self.rbf = Rbf(*X.T, y,function=self.function)

    def predict(self,X):   
        return self.rbf(*X.T)


# Load Data
data=datasets.load_boston()

X = data.data
y = data.target


number_splits=5
score_list=['neg_mean_squared_error','neg_mean_absolute_error','r2']

kfold = model_selection.KFold(n_splits=number_splits,shuffle=True, random_state=0)
scalar = StandardScaler()

model = RBF(function='multiquadric')

pipeline = Pipeline([('transformer', scalar), ('estimator', model)])

results = model_selection.cross_validate(pipeline, X, y, cv=kfold, scoring=score_list,return_train_score=True)

for score in score_list:
        print(score+':')
        print('Train: '+'Mean',np.mean(results['train_'+score]),'Standard Error',np.std(results['train_'+score]))
        print('Test: '+'Mean',np.mean(results['test_'+score]),'Standard Error',np.std(results['test_'+score]))

Output

neg_mean_squared_error:
Train: Mean -1.552450953914355e-20 Standard Error 7.932530906290208e-21
Test: Mean -23.007377210596463 Standard Error 4.254629143836107
neg_mean_absolute_error:
Train: Mean -9.398502208736061e-11 Standard Error 2.4673749061941226e-11
Test: Mean -3.1319779583728673 Standard Error 0.2162343985534446
r2:
Train: Mean 1.0 Standard Error 0.0
Test: Mean 0.7144217179633185 Standard Error 0.08526294242760363

Почему *X.T: Как мы видели, каждый аргумент соответствует оси всех точек данных, поэтому мы транспонируем их и затем используем оператор * для расширения и передать каждый из подмассива в качестве аргумента функции переменной длины.

Похоже, что в последней реализации есть параметр mode, где мы можем напрямую передать массив N-D.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...