使用train_testrongplit()时如何获得数据的原始索引?
我有以下内容
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)
但这并没有给出原始数据的索引。一种解决方法是将索引添加到数据(例如data = [(i, d) for i, d in enumerate(data)]
),然后将它们传递到train_test_split
中,然后再次展开。有没有更清洁的解决方案?
你可以像Julien说的那样使用pandas dataframes或series,但如果你想限制自己使用numpy,你可以传递一个额外的索引数组:
from sklearn.model_selection 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)
(
data_train,
data_test,
labels_train,
labels_test,
indices_train,
indices_test,
) = train_test_split(data, labels, indices, test_size=0.2)
Scikit learn和Pandas玩得很好,所以我建议你使用它。下面是一个例子:
In [1]:
import pandas as pd
import numpy as np
from sklearn.model_selection 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]: # Giving columns in X a name
X = pd.DataFrame(data, columns=['Column_1', 'Column_2'])
y = pd.Series(labels)
In [3]:
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2,
random_state=0)
In [4]: X_test
Out[4]:
Column_1 Column_2
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
你可以直接调用DataFrame/Series上的任何scikit函数,它将会工作。
让我们假设你想做一个逻辑回归,这里是你如何以一种很好的方式检索系数:
In [6]:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model = model.fit(X_train, y_train)
# Retrieve coefficients: index is the feature name (['Column_1', 'Column_2'] here)
df_coefs = pd.DataFrame(model.coef_[0], index=X.columns, columns = ['Coefficient'])
df_coefs
Out[6]:
Coefficient
Column_1 0.076987
Column_2 -0.352463
这是最简单的解决方案(Jibwa在另一个答案中使它看起来很复杂),无需自己生成索引—只需使用ShuffleSplit对象生成1个分割。
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]
文档中提到train_testrongplit只是在shuffle split之上的一个方便函数。
我只是重新安排了他们的一些代码,使我自己的例子。注意,实际的解决方案是中间的代码块。剩下的是导入,以及可运行示例的设置。
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)
现在我有了实际的索引:train_is, test_is
如果使用的是pandas,则可以通过调用想要模拟的任何数组的.index来访问索引。train_testrongplit将pandas索引传递到新的数据帧。
在您的代码中,您只需使用x1.index
返回的数组是与x中原始位置相关的索引。