GridSearchCV - доступ к прогнозируемым значениям по всем тестам?

Есть ли способ получить доступ к прогнозируемым значениям, вычисленным в процессе GridSearchCV?

Я хотел бы иметь возможность построить прогнозируемые значения у против их фактических значений (из набора испытаний / проверки).

Когда поиск по сетке завершен, я могу сопоставить его с некоторыми другими данными, используя

 ypred = grid.predict(xv)

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

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV, KFold, 
cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.svm import SVR

scaler = StandardScaler()
svr_rbf = SVR(kernel='rbf')
pipe = Pipeline(steps=[('scaler', scaler), ('svr_rbf', svr_rbf)])
grid = GridSearchCV(pipe, param_grid=parameters, cv=splits, refit=True, verbose=3, scoring=msescorer, n_jobs=4)
grid.fit(xt, yt)

2 ответа

Решение

Одним из решений является создание собственного счетчика и сохранение полученного аргумента в глобальной переменной:

from sklearn.grid_search import GridSearchCV
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error,make_scorer

X, y = np.random.rand(2,200)
clf = SVR()

ys = []

def MSE(y_true,y_pred):
    global ys
    ys.append(y_pred)
    mse = mean_squared_error(y_true, y_pred)
    return mse

def scorer():
    return make_scorer(MSE, greater_is_better=False)

n_splits = 3 
cv = GridSearchCV(clf, {'degree':[1,2,3]}, scoring=scorer(), cv=n_splits)
cv.fit(X.reshape(-1, 1), y)

Затем нам нужно собрать каждое разбиение в полный массив:

idxs = range(0, len(ys)+1, n_splits)
#e.g. [0, 3, 6, 9]
#collect every n_split elements into a single list
new = [ys[j[0]+1:j[1]] for j in zip(idxs,idxs[1:])]
#summing every such list
ys = [reduce(lambda x,y:np.concatenate((x,y), axis=0), i) for i in new]

Решение для использования более одного процессора и хранения y_pred_proba вместо y_pred.

Для начала нам нужно запустить многопроцессорный менеджер:

      import multiprocessing
manager = multiprocessing.Manager()

Перед созданием экземпляра нам нужно создать фиктивный счетчик, который будет фиксировать и сохранять значения вероятностей. В моем случае я использовал ROC_AUC, но подойдет любая метрика:

      scorers = {}
def roc_auc_dummy(y_true, y_pred_proba):
    global ys # This will make sure `ys` is in the global, not local, scope
    ys.append(y_pred_proba)
    roc_auc = roc_auc_score(y_true, y_pred_proba)
    return roc_auc
scorers['roc_auc'] = make_scorer(roc_auc_dummy, needs_proba = True)

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

      ys = manager.list()
clf = GridSearchCV(model, params, scoring = scorers)
clf.fit(X, y)

Вероятности можно получить, переведя ys к списку:

      y_pred_probas = list(ys)

y_pred_probas будет списком списков, в котором каждый внутренний список будет в том же порядке, что и в clf.cv_results_['params'].

Другие вопросы по тегам