#python #scikit-learn #typeerror
Вопрос:
Я запускал следующий код с помощью sklearn 0.22:
def regress_models(X, y):
scoring = {'r2': 'r2',
'mae': 'neg_mean_absolute_error'}
# define models
models, names, mape, r2, mae = list(), list(), list(), list(), list()
# LR
models.append(LinearRegression())
names.append('LR')
#Lasso
models.append(Lasso())
names.append('LA')
#RF
models.append(RandomForestRegressor(random_state=42))
names.append('RF')
for i in range(len(models)):
# define evaluation procedure
cv=StratifiedKFold(n_splits=4, random_state=None)
pipeline = Pipeline([('model', models[i])])
scores = cross_validate(pipeline, X, y, scoring=scoring,
cv=cv, return_train_score=True, n_jobs=-1)
mape=list(scores["test_mape"])
r2=list(scores['test_r2'])
mae=list(scores['test_mae'])
# summarize and store
print('{} R^2:{}, MAE:{}'.format(names[i], mean(r2), mean(mae)))
Все работает нормально, пока я не обновился до sklearn 0.24, и теперь я получаю следующую ошибку:
--------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-309-cf93f9c077fa> in <module>
----> 1 regress_clamp(X_rcsi, y_rcsi)
<ipython-input-308-67a5841bff3d> in regress_clamp(X, y)
38 pipeline = Pipeline([('model', models[i])])
39 scores = cross_validate(pipeline, X, y, scoring=scoring,
---> 40 cv=cv, return_train_score=True, n_jobs=-1)
41
42 mape=list(scores["test_mape"])
~/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in cross_validate(estimator, X, y, groups, scoring, cv, n_jobs, verbose, fit_params, pre_dispatch, return_train_score, return_estimator, error_score)
239 if callable(scoring):
240 scorers = scoring
--> 241 elif scoring is None or isinstance(scoring, str):
242 scorers = check_scoring(estimator, scoring)
243 else:
~/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in _aggregate_score_dicts(scores)
1503 for n_train_samples, partial_train in partitions:
1504 train_subset = train[:n_train_samples]
-> 1505 X_train, y_train = _safe_split(estimator, X, y, train_subset)
1506 X_partial_train, y_partial_train = _safe_split(estimator, X, y,
1507 partial_train)
~/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in <dictcomp>(.0)
1503 for n_train_samples, partial_train in partitions:
1504 train_subset = train[:n_train_samples]
-> 1505 X_train, y_train = _safe_split(estimator, X, y, train_subset)
1506 X_partial_train, y_partial_train = _safe_split(estimator, X, y,
1507 partial_train)
~/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in <listcomp>(.0)
1502 fit_params = {}
1503 for n_train_samples, partial_train in partitions:
-> 1504 train_subset = train[:n_train_samples]
1505 X_train, y_train = _safe_split(estimator, X, y, train_subset)
1506 X_partial_train, y_partial_train = _safe_split(estimator, X, y,
TypeError: string indices must be integers
Это снова работает после того, как я понизил рейтинг до 0,22, но кто-нибудь знает, что вызывает эту проблему в новой версии? Больше ничего в моем наборе данных или коде не изменилось между двумя версиями модуля.
Ответ №1:
Приведенный ниже код работает на scikit-learn 0.24.1. Ключевыми вопросами были:
- Код использовался
StratifiedKFold
вместоKFold
, что приводит к ошибке, учитывая, что цель непрерывна, так как это задача регрессии. - Код пытался извлечь
'test_mape'
из результатов перекрестной проверки, но в словарь были включены только R2 и MAEscoring
.
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_validate, KFold
from sklearn.pipeline import Pipeline
import numpy as np
import sklearn
print(sklearn.__version__)
# 0.24.1
def regress_models(X, y):
# define metrics
scoring = {'r2': 'r2', 'mae': 'neg_mean_absolute_error', 'mape': 'neg_mean_absolute_percentage_error'}
# define models
models, names, mape, r2, mae = list(), list(), list(), list(), list()
# LR
models.append(LinearRegression())
names.append('LR')
# Lasso
models.append(Lasso())
names.append('LA')
# RF
models.append(RandomForestRegressor(random_state=42))
names.append('RF')
for i in range(len(models)):
# define evaluation procedure
cv = KFold(n_splits=4, random_state=None)
pipeline = Pipeline([('model', models[i])])
scores = cross_validate(pipeline, X, y, scoring=scoring, cv=cv, return_train_score=True, n_jobs=-1)
# calculate performance metrics
mape = list(scores['test_mape'])
r2 = list(scores['test_r2'])
mae = list(scores['test_mae'])
# summarize and store
print('{} R^2: {:%}, MAE: {:f}, MAPE: {:%}'.format(names[i], np.mean(r2), np.mean(mae), np.mean(mape)))
# test the function
X, y = make_regression(n_samples=1000, n_features=5, noise=10, random_state=42)
regress_models(X, y)
# LR R^2: 97.421704%, MAE: -8.260329, MAPE: -75.592451%
# LA R^2: 97.305603%, MAE: -8.371423, MAPE: -70.782377%
# RF R^2: 88.443183%, MAE: -16.847307, MAPE: -135.300698%