2012-10-02 1 views
1

J'essaye de reproduire l'exemple de StratifiedShuffleSplit avec X n'étant pas un tableau mais une matrice éparse. Dans l'exemple ci-dessous, cette matrice a été créée par un ajustement de DictVectorizer à un tableau de caractéristiques nominales et numériques mixtes.Utilisation de StratifiedShuffleSplit avec une matrice clairsemée

from sklearn.feature_extraction import DictVectorizer 
from sklearn.preprocessing import LabelEncoder 
from sklearn.cross_validation import StratifiedShuffleSplit 

X = [{"a":1, "b":"xx"}, {"a":2, "b":"yx"}, {"a":2, "b":"yx"}, {"a":1, "b":"xx"}] 
y = ["A", "B", "B", "A"] 

X = DictVectorizer().fit_transform(X) 
y = LabelEncoder().fit_transform(y) 

sss = StratifiedShuffleSplit(y, 3, test_size=0.5, random_state=0) 

for train_index, test_index in sss: 
    X_train, X_test = X[train_index], X[test_index] 
    y_train, y_test = y[train_index], y[test_index] 

Quand je lance le script, l'erreur suivante est générée:

Traceback (most recent call last): 
    File ".../test.py", line 22, in <module> 
    X_train, X_test = X[train_index], X[test_index] 
TypeError: only integer arrays with one element can be converted to an index 

Ceci est parce que X est pas un tableau, mais une matrice creuse. Donc la question est, comment puis-je diviser les données en utilisant cette méthode lorsque X n'est pas un tableau mais une matrice? Peut-être que le problème n'est pas scikit-learn spécifiquement, mais numpy? Dois-je "transformer" train_index et test_index avant de les "appliquer" à X? Ou peut-être que je dois "transformer" X à la place?

Selon la documentation de StratifiedShuffleSplit, pour que cela fonctionne avec des matrices, je passerais vrai au paramètre indices, mais il ne permet pas.

Toute suggestion que vous pourriez me donner serait plus que bienvenue.

Répondre

5

Le problème est causé par le fait que dans votre version de scikit-learn DictVectorizer rendement matrice COO qui n'est pas indexable par ligne (le message d'erreur scipy n'est malheureusement pas très explicite). Pour résoudre le problème de convertir le ouput vectorisé au format RSE en remplaçant la ligne:

X = DictVectorizer().fit_transform(X) 

par

X = DictVectorizer().fit_transform(X).tocsr() 
+1

Notez également: sur le maître scikit-learn, DictVectorizer renvoie maintenant un CSR par défaut. – ogrisel

0

Je peux vous dire comment diviser et mélanger une matrice creuse en python, mybe qui aide:

def splitSparseMatrix(matrix): 
    trainingSet = matrix[:trainingSetSize,:] 
    testSet = matrix[-testSetSize:,:] 
    return trainingSet, testSet 

def shuffleSparseMatrix(smatrix): 
    indexList = np.arange(np.shape(matrix)[0]) 
    np.random.shuffle(indexList) 
    return matrix[indexList, :] 
1

Vous devez passer à indices=TrueStratifiedShuffleSplit comme spécifié in the docs.

Questions connexes