webentwicklung-frage-antwort-db.com.de

Scikit-learn train_test_split mit Indizes

Wie erhalte ich die ursprünglichen Indizes der Daten, wenn Sie train_test_split () verwenden?

Was ich habe, ist folgendes

from sklearn.cross_validation import train_test_split
import numpy as np
data = np.reshape(np.randn(20),(10,2)) # 10 training examples
labels = np.random.randint(2, size=10) # 10 labels
x1, x2, y1, y2 = train_test_split(data, labels, size=0.2)

Dies gibt jedoch nicht die Indizes der Originaldaten an. Eine Problemumgehung besteht darin, die Indizes den Daten hinzuzufügen (z. B. data = [(i, d) for i, d in enumerate(data)]), diese dann in train_test_split zu übergeben und dann erneut zu erweitern. Gibt es sauberere Lösungen?

31
CentAu

Scikit learn spielt mit Pandas sehr gut, daher schlage ich vor, es zu benutzen. Hier ist ein Beispiel:

In [1]: 
import pandas as pd
import numpy as np
from sklearn.cross_validation import train_test_split
data = np.reshape(np.random.randn(20),(10,2)) # 10 training examples
labels = np.random.randint(2, size=10) # 10 labels

In [2]: 
X = pd.DataFrame(data)
y = pd.Series(labels)

In [3]:
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=test_size, 
                                                    random_state=0)

In [4]: X_test
Out[4]:

     0       1
2   -1.39   -1.86
8    0.48   -0.81
4   -0.10   -1.83

In [5]: y_test
Out[5]:

2    1
8    1
4    1
dtype: int32

Sie können beliebige Scikit-Funktionen von DataFrame/Series direkt aufrufen und funktionieren.

Angenommen, Sie wollten eine LogisticRegression durchführen. So können Sie die Koeffizienten auf nette Weise abrufen:

In [6]: 
from sklearn.linear_model import LogisticRegression

model = linear_model.LogisticRegression()
model = model.fit(X_train, y_train)

# Retrieve coefficients: index is the feature name ([0,1] here)
df_coefs = pd.DataFrame(model.coef_[0], index=X.columns, columns = ['Coefficient'])
df_coefs
Out[6]:
    Coefficient
0   0.076987
1   -0.352463
26
Julien Marrec

Sie können Pandas-Datenrahmen oder -serien verwenden, wie Julien gesagt hat. Wenn Sie sich jedoch auf Numpy beschränken möchten, können Sie ein zusätzliches Array von Indizes übergeben:

from sklearn.cross_validation import train_test_split
import numpy as np
n_samples, n_features, n_classes = 10, 2, 2
data = np.random.randn(n_samples, n_features)  # 10 training examples
labels = np.random.randint(n_classes, size=n_samples)  # 10 labels
indices = np.arange(n_samples)
x1, x2, y1, y2, idx1, idx2 = train_test_split(
    data, labels, indices, test_size=0.2)
58
ogrisel

Das docs erwähnen train_test_split ist nur eine Komfortfunktion neben dem Shuffle Split.

Ich habe gerade einen Teil ihres Codes umgestellt, um mein eigenes Beispiel zu machen. Beachten Sie, dass die eigentliche Lösung der mittlere Codeblock ist. Der Rest ist Importe und Setup für ein lauffähiges Beispiel.

from sklearn.model_selection import ShuffleSplit
from sklearn.utils import safe_indexing, indexable
from itertools import chain
import numpy as np
X = np.reshape(np.random.randn(20),(10,2)) # 10 training examples
y = np.random.randint(2, size=10) # 10 labels
seed = 1

cv = ShuffleSplit(random_state=seed, test_size=0.25)
arrays = indexable(X, y)
train, test = next(cv.split(X=X))
iterator = list(chain.from_iterable((
    safe_indexing(a, train),
    safe_indexing(a, test),
    train,
    test
    ) for a in arrays)
)
X_train, X_test, train_is, test_is, y_train, y_test, _, _  = iterator

print(X)
print(train_is)
print(X_train)

Jetzt habe ich die aktuellen Indizes: train_is, test_is

1
Jibwa

Hier ist die einfachste Lösung (nicht sicher, warum Jibwa es in einer anderen Antwort als kompliziert empfunden hat), ohne dass Sie Indizes selbst generieren müssen.

import numpy as np 
from sklearn.model_selection import ShuffleSplit # or StratifiedShuffleSplit
sss = ShuffleSplit(n_splits=1, test_size=0.1)

data_size = 100
X = np.reshape(np.random.Rand(data_size*2),(data_size,2))
y = np.random.randint(2, size=data_size)

sss.get_n_splits(X, y)
train_index, test_index = next(sss.split(X, y)) 

X_train, X_test = X[train_index], X[test_index] 
y_train, y_test = y[train_index], y[test_index]
0
m3h0w