"TypeError: Singleton array...cannot be considered a valid collection" и "ValueError: Found input ...inconsistent num...samples" в train_test_split

Не могу понять что является причиной ошибки на второй итерации в функции ниже:

# create empty pandas DF:
model_q = pd.DataFrame(columns=['model', 'set', 'threshold','set_size','tn','fp','fn','tp'])

# get seed
cv_seed = random.sample(range(1, 1000), 10) 

def bootstraping_estimator(clf, model_name, X, y, cv_seed=cv_seed):

for i in cv_seed:
    print(i)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, shuffle=True, random_state=i, stratify=y)

    # StandartScaler
    scaler.fit(X_train.values)
    X_train = scaler.transform(X_train)
    X_test = scaler.transform(X_test)

    # compute TEST   ############################################################ 
    y_pred_test = clf.predict_proba(X_test)[:, 1]
    fpr, tpr, ths = roc_curve(y_test, y_pred_test)
    roc_auc = auc(fpr, tpr) 
    optimal_ths_idx = np.argmax(tpr - fpr)
    optimal_ths = ths[optimal_ths_idx]

    # round predicts    ##########################################################
    for y in y_pred_test:
        y_pred_test_round = [1 if y >= 0.5 else 0 for y in y_pred_test]
        y_pred_test_round_ths = [1 if y >= optimal_ths else 0 for y in y_pred_test]

    # cm with default ths = 0.5 ##################################################
    cm = confusion_matrix(y_test, y_pred_test_round)  
    cm_norm = cm.astype('float') / cm.sum()     # normalize cm  
    tn, fp, fn, tp = cm.ravel() # compute estimetor answers

    # cm with ths = optimal_ths
    cm_ths = confusion_matrix(y_test, y_pred_test_round_ths)
    cm_norm_ths = cm_ths.astype('float') / cm_ths.sum()     # normalize cm  
    tn_ths, fp_ths, fn_ths, tp_ths = cm_ths.ravel()
    fpr_ths, tpr_ths, _ = roc_curve(y_test, y_pred_test_round_ths) # ... for test with optimal_threshold
    roc_auc_ths = auc(fpr_ths, tpr_ths) 


    # get global var and appned metrics
    global model_q
    model_q = model_q.append({'model': f'{model_name}_{i}',
                          'threshold': 0.5,
                          'set_size': len(y_test),
                          'tn': tn,'fp': fp, 'fn': fn, 'tp': tp,
                          'roc_auc': roc_auc},
                          ignore_index=True)

    model_q = model_q.append({'model': f'{model_name}_{i}',
                          'threshold': optimal_ths,
                          'set_size': len(y_test),
                          'tn': tn_ths,'fp': fp_ths, 'fn': fn_ths, 'tp': tp_ths,
                          'roc_auc': roc_auc_ths},
                          ignore_index=True)

    model_q['sensitivity'] = model_q.tp/(model_q.tp+model_q.fn)
    model_q['specificity'] = model_q.tn/(model_q.tn+model_q.fp)
    model_q['accuracy'] = (model_q.tp+model_q.tn)/(model_q.tp+model_q.tn+model_q.fn+model_q.fp)

    model_q.iloc[:,1:] = model_q.iloc[:,1:].apply(pd.to_numeric)

    model_q = model_q.round({'roc_auc':3,
                         'threshold':3,
                         'sensitivity':3,
                         'specificity':3,
                         'accuracy':3})


return (model_q.sort_values(by='accuracy', ascending=False)[:10].style.hide_index()\
        .bar(color='#FFA07A', vmin=500, subset=['fp', 'fn'], align='zero')\
        .bar(color='lightgreen', vmin=500, subset=['tp', 'tn'], align='zero')
        .set_caption('Top-10 accuracy'))

Есть сохранение данных в переменную, второй train_test_split падает:

введите сюда описание изображения

    TypeError                                 Traceback (most recent call last)
<ipython-input-22-bb1482942a86> in <module>
----> 1 bootstraping_estimator(clf_NB, 'NBGaussian', X, y)

<ipython-input-16-836a8d7da60e> in bootstraping_estimator(clf, model_name, X, y, cv_seed)
      6     for i in cv_seed:
      7         print(i)
----> 8         X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, shuffle=True, random_state=i, stratify=y)
      9 
     10         # StandartScaler

~\Anaconda3\lib\site-packages\sklearn\model_selection\_split.py in train_test_split(*arrays, **options)
   2182         test_size = 0.25
   2183 
-> 2184     arrays = indexable(*arrays)
   2185 
   2186     if shuffle is False:

~\Anaconda3\lib\site-packages\sklearn\utils\validation.py in indexable(*iterables)
    258         else:
    259             result.append(np.array(X))
--> 260     check_consistent_length(*result)
    261     return result
    262 

~\Anaconda3\lib\site-packages\sklearn\utils\validation.py in check_consistent_length(*arrays)
    229     """
    230 
--> 231     lengths = [_num_samples(X) for X in arrays if X is not None]
    232     uniques = np.unique(lengths)
    233     if len(uniques) > 1:

~\Anaconda3\lib\site-packages\sklearn\utils\validation.py in <listcomp>(.0)
    229     """
    230 
--> 231     lengths = [_num_samples(X) for X in arrays if X is not None]
    232     uniques = np.unique(lengths)
    233     if len(uniques) > 1:

~\Anaconda3\lib\site-packages\sklearn\utils\validation.py in _num_samples(x)
    140         if len(x.shape) == 0:
    141             raise TypeError("Singleton array %r cannot be considered"
--> 142                             " a valid collection." % x)
    143         # Check that shape is returning an integer or default to len
    144         # Dask dataframes may not return numeric shape[0] value

TypeError: Singleton array 6.80836481004117e-07 cannot be considered a valid collection.

Ответы (1 шт):

Автор решения: CrazyElf

А, всё, я понял. Вы используете y как переменную цикла for y in y_pred_test:. А потом на второй итерации тот же y используете в train_test_split(X, y, ...). Типичная ошибка начинающего питониста - использовать одни и те же названия переменных для разных целей.

Ну и до кучи вы где-то потеряли clf.fit(X_train, y_train). Если б вы не использовали scaler я бы подумал, что так и задумано, но если вы скейлите X_test каждый раз заново, вам придётся заново обучать модель на X_train, иначе это вообще не пойми что будет в результате.

→ Ссылка