Ошибка типа: строковые индексы должны быть целыми числами с версией sklearn 0.24.2

#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 и MAE scoring .
 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%