1

Il s'agit d'une question à propos de scikit learn (version 0.17.0) en Python 2.7 avec Pandas 0.17. 1. Afin de diviser les données brutes (sans entrées manquantes) en utilisant l'approche détaillée here, j'ai constaté que si les données séparées sont utilisées pour procéder à un .fit() qu'une erreur apparaît.sklearn grid.fit (X, y) - erreur: "indexeurs de position sont hors des limites" pour X_train, y_train

Voici le code repris en grande partie inchangé par rapport à l'autre question de stackoverflow avec renommage des variables. J'ai ensuite instancié une grille et essayé d'ajuster les données séparées dans le but de déterminer les paramètres optimaux du classificateur. L'erreur se produit après la dernière ligne du code ci-dessous:

import pandas as pd 
import numpy as np 
# UCI's wine dataset 
wine = pd.read_csv("https://s3.amazonaws.com/demo-datasets/wine.csv") 

# separate target variable from dataset 
y = wine['quality'] 
X = wine.drop(['quality','color'],axis = 1) 

# Stratified Split of train and test data 
from sklearn.cross_validation import StratifiedShuffleSplit 
sss = StratifiedShuffleSplit(y, n_iter=3, test_size=0.2) 

# Split dataset to obtain indices for train and test set 
for train_index, test_index in sss: 
    xtrain, xtest = X.iloc[train_index], X.iloc[test_index] 
    ytrain, ytest = y[train_index], y[test_index] 

# Pick some classifier here 
from sklearn.tree import DecisionTreeClassifier 
decision_tree = DecisionTreeClassifier() 

from sklearn.grid_search import GridSearchCV 
# Instantiate grid 
grid = GridSearchCV(decision_tree, param_grid={'max_depth':np.arange(1,3)}, cv=sss, scoring='accuracy') 

# this line causes the error message 
grid.fit(xtrain,ytrain) 

Voici le message d'erreur produit par le code ci-dessus:

Traceback (most recent call last): 
    File "C:\Python27\test.py", line 23, in <module> 
    grid.fit(xtrain,ytrain) 
    File "C:\Python27\lib\site-packages\sklearn\grid_search.py", line 804, in fit 
    return self._fit(X, y, ParameterGrid(self.param_grid)) 
    File "C:\Python27\lib\site-packages\sklearn\grid_search.py", line 553, in _fit 
    for parameters in parameter_iterable 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 800, in __call__ 
    while self.dispatch_one_batch(iterator): 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 658, in dispatch_one_batch 
    self._dispatch(tasks) 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 566, in _dispatch 
    job = ImmediateComputeBatch(batch) 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 180, in __init__ 
    self.results = batch() 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 72, in __call__ 
    return [func(*args, **kwargs) for func, args, kwargs in self.items] 
    File "C:\Python27\lib\site-packages\sklearn\cross_validation.py", line 1524, in _fit_and_score 
    X_train, y_train = _safe_split(estimator, X, y, train) 
    File "C:\Python27\lib\site-packages\sklearn\cross_validation.py", line 1591, in _safe_split 
    X_subset = safe_indexing(X, indices) 
    File "C:\Python27\lib\site-packages\sklearn\utils\__init__.py", line 152, in safe_indexing 
    return X.iloc[indices] 
    File "C:\Python27\lib\site-packages\pandas\core\indexing.py", line 1227, in __getitem__ 
    return self._getitem_axis(key, axis=0) 
    File "C:\Python27\lib\site-packages\pandas\core\indexing.py", line 1504, in _getitem_axis 
    self._is_valid_list_like(key, axis) 
    File "C:\Python27\lib\site-packages\pandas\core\indexing.py", line 1443, in _is_valid_list_like 
    raise IndexError("positional indexers are out-of-bounds") 
IndexError: positional indexers are out-of-bounds 

REMARQUE: Il est important pour moi de conservez X et y comme des structures de données Pandas, similaires à la deuxième approche présentée dans l'autre question de stackoverflow ci-dessus. c'est-à-dire que je ne voudrais pas utiliser X.values et y.values.

Question: À l'aide des données brutes en tant que structure de données Pandas (DataFrame pour X et Series pour y), est-il un moyen d'exécuter grid.fit() sans obtenir ce message d'erreur?

+1

Un problème dans ce script est que l'objet CV sss génère des index pour toutes les lignes de y. Lorsque vous appelez grid.fit - vous lui donnez uniquement xtrain, ytrain, qui sont plus courtes que y, donc les indexeurs de position sont hors-limites. Une fois que vous avez créé sss, vous n'avez pas besoin de diviser les données. Transmettez les entiers X et Y dans grid.fit et effectuez la division en fonction des indices de sss. –

+0

C'est vrai, mais je lui donne aussi 'y_test'. La taille de 'X_test' correspond à celle de' y_test'. Cela ne signifie-t-il pas que les indexeurs de position correspondent? –

+1

@WR, non, vous donnez 'y' à' StratifiedShuffleSplit' et 'xtrain, ytrain' à' grid.fit'. C'est la racine du problème. –

Répondre

2

Vous devez passer X et y directement à fit(), comme

grid.fit(X, y) 

et GridSearchCV prendra soin de

xtrain, xtest = X.iloc[train_index], X.iloc[test_index] 
ytrain, ytest = y[train_index], y[test_index] 

L'instance StratifiedShuffleSplit, lorsque itéré, donne paires de trains/test split indices:

>>> list(sss) 
[(array([2531, 4996, 4998, ..., 3205, 2717, 4983]), array([5942, 893, 1702, ..., 6340, 4806, 2537])), 
(array([1888, 2332, 6276, ..., 1674, 775, 3705]), array([3404, 3304, 4741, ..., 4397, 3646, 1410])), 
(array([1517, 3759, 4402, ..., 5098, 4619, 4521]), array([1110, 4076, 1280, ..., 6384, 1294, 1132]))] 

GridSearchCV utilise ces indices pour séparer les échantillons d'apprentissage. Vous n'avez pas besoin de le faire manuellement.

L'erreur se produit parce que vous alimentez xtrain et ytrain (l'un des trains/tests de division) dans le validateur croisé. Le validateur croisé tente d'accéder aux éléments qui existent dans l'ensemble de données complet mais pas dans la division train/test, ce qui génère un IndexError.

+0

Mais alors, comment créer un set d'attente? Sans division, il n'y a aucun moyen d'obtenir 'x_test',' y_test'. Ou existe-t-il une autre méthode pour créer un ensemble de données pour X et Y? –

+0

La validation croisée implique l'itération à travers un certain nombre de divisions train/test (dans votre cas, 3) et la moyenne du score. 'GridSearchCV' le fait automatiquement. Pourquoi avez-vous besoin d'un autre ensemble de blocage? –

+0

Si vous voulez vraiment conserver un morceau de données, vous pouvez utiliser quelque chose comme 'train_test_split', qui produit simplement une seule division des données (plutôt qu'un itérable de splits). A la fin, vous devez vous assurer d'instancier 'StratifiedShuffleSplit' avec le' y' qui vient du tuple 'X, y' que vous passez à' fit (...) '. –