如何使用基于时间的拆分将数据拆分为Train和Test。
我知道train_test_split会随机拆分它如何根据时间拆分它。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
# this splits the data randomly as 67% test and 33% train
如何根据时间将相同的数据集拆分为67%的列车和33%的测试?
数据集有一列TimeStamp。
我尝试搜索类似的问题但不确定这种方法。
有人可以简要解释
答案 0 :(得分:1)
在时间序列数据集上,数据拆分以不同的方式进行。 See this link了解更多信息。或者,您可以尝试使用scikit-learn包中的TimeSeriesSplit。所以主要的想法就是这个,假设根据时间戳你有10个数据点。现在拆分将是这样的:
Split 1 :
Train_indices : 1
Test_indices : 2
Split 2 :
Train_indices : 1, 2
Test_indices : 3
Split 3 :
Train_indices : 1, 2, 3
Test_indices : 4
Split 4 :
Train_indices : 1, 2, 3, 4
Test_indices : 5
等等。您可以查看上面链接中显示的示例,以更好地了解TimeSEriesSPlit如何在sklearn中工作
<强>更新强> 如果你有一个单独的时间列,你可以简单地根据该列对数据进行排序,并如上所述应用timeSeriesSplit来获得分割。
为了确保最终拆分中67%的培训和33%的测试数据,请指定拆分数量如下:
no_of_split = int((len(data)-3)/3)
示例
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4],[1, 2], [3, 4],[3, 4],[1, 2], [3, 4],[3, 4],[1, 2], [3, 4] ])
y = np.array([1, 2, 3, 4, 5, 6,7,8,9,10,11,12])
tscv = TimeSeriesSplit(n_splits=int((len(y)-3)/3))
for train_index, test_index in tscv.split(X):
print("TRAIN:", train_index, "TEST:", test_index)
#To get the indices
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
输出:
('TRAIN:', array([0, 1, 2]), 'TEST:', array([3, 4, 5]))
('TRAIN:', array([0, 1, 2, 3, 4, 5]), 'TEST:', array([6, 7, 8]))
('TRAIN:', array([0, 1, 2, 3, 4, 5, 6, 7, 8]), 'TEST:', array([ 9, 10, 11]))
答案 1 :(得分:0)
如果您有一个简单的数据集,其中每一行都是一个观察值(例如,用于分类问题的非时间序列数据集),并且您希望将其拆分为训练和测试,则此功能将基于训练和测试在日期列上:
import pandas as pd
import numpy as np
from math import ceil
def train_test_split_sorted(X, y, test_size, dates):
"""Splits X and y into train and test sets, with test set separated by most recent dates.
Example:
--------
>>> from sklearn import datasets
# Fake dataset:
>>> gen_data = datasets.make_classification(n_samples=10000, n_features=5)
>>> dates = np.array(pd.date_range('2016-01-01', periods=10000, freq='5min'))
>>> np.random.shuffle(dates)
>>> df = pd.DataFrame(gen_data[0])
>>> df['date'] = dates
>>> df['target'] = gen_data[1]
# Separate:
>>> X_train, X_test, y_train, y_test = train_test_split_sorted(df.drop('target', axis=1), df['target'], 0.33, df['date'])
>>> print('Length train set: {}'.format(len(y_train)))
Length train set: 8000
>>> print('Length test set: {}'.format(len(y_test)))
Length test set: 2000
>>> print('Last date in train set: {}'.format(X_train['date'].max()))
Last date in train set: 2016-01-28 18:35:00
>>> print('First date in test set: {}'.format(X_test['date'].min()))
First date in test set: 2016-01-28 18:40:00
"""
n_test = ceil(test_size * len(X))
sorted_index = [x for _, x in sorted(zip(np.array(dates), np.arange(0, len(dates))), key=lambda pair: pair[0])]
train_idx = sorted_index[:-n_test]
test_idx = sorted_index[-n_test:]
if isinstance(X, (pd.Series, pd.DataFrame)):
X_train = X.iloc[train_idx]
X_test = X.iloc[test_idx]
else:
X_train = X[train_idx]
X_test = X[test_idx]
if isinstance(y, (pd.Series, pd.DataFrame)):
y_train = y.iloc[train_idx]
y_test = y.iloc[test_idx]
else:
y_train = y[train_idx]
y_test = y[test_idx]
return X_train, X_test, y_train, y_test
dates
参数实际上可以是您要用来对数据进行排序的任何类型的数组或Series。
在这种情况下,您应该调用:X_train, X_test, y_train, y_test = train_test_split_sorted(X, y, 0.333, TimeStamp)
,其中TimeStamp
是包含有关每个观察的时间戳记信息的数组或列。
答案 2 :(得分:0)
一种简单的方法。
首先:按时间对数据进行排序
第二:
import numpy as np
train_set, test_set= np.split(data, [int(.67 *len(data))])
这会使trainset的数据占前67%,而test_set的数据占其余33%。
答案 3 :(得分:0)
如果您的数据已经基于时间进行了排序,则只需使用shuffle=False
例如:
train, test = train_test_split(newdf, test_size=0.3, shuffle=False)