根据python中训练和测试集中的时间戳为每个用户拆分数据集

Posted

技术标签:

【中文标题】根据python中训练和测试集中的时间戳为每个用户拆分数据集【英文标题】:Split dataset per user according to timestamp in training and test set in python 【发布时间】:2017-07-12 17:23:44 【问题描述】:

我正在使用 movielens 数据集(ratings.dat)和 pandas 数据框来读取和处理数据。我必须将这些数据分成测试集和训练集。通过使用 pandas dataframe.sample 函数,可以将数据随机分割。例如:

train = df.sample(frac=0.8,random_state=200)

test = df.drop(train.index)

现在我正在尝试对 user_id 和时间戳上的数据进行排序,我需要在训练集和测试集中分别将数据划分为每个用户 80%-20%。

因此,例如,如果 user1 评价了 10 部电影,则该用户的条目应根据时间戳从最旧到最新排序

ratings = pd.read_csv('filename', sep='\t', engine='python', header=0)

sorted_df = rating.sort(['user_id', 'timestamp'], ascending=[True, True])

并且拆分的方式应该是,时间戳最旧的前 8 个条目将在训练集中,而最新的 2 个条目将在测试集中。

我不知道我该怎么做。有什么建议吗?

谢谢

数据:

           user_id   item_id   rating   Timestamp 
15              1      539        5  838984068
16              1      586        5  838984068
5               1      355        5  838984474
9               1      370        5  838984596
12              1      466        5  838984679
14              1      520        5  838984679
19              1      594        5  838984679
7               1      362        5  838984885
20              1      616        5  838984941
23              2      260        5  868244562
29              2      733        3  868244562
32              2      786        3  868244562
36              2     1073        3  868244562
33              2      802        2  868244603
38              2     1356        3  868244603
30              2      736        3  868244698
31              2      780        3  868244698
27              2      648        2  868244699

【问题讨论】:

【参考方案1】:

它需要多个步骤,但可以实现如下。

直觉是根据时间戳生成一个rank,并将其限制在0到1之间。那么低于0.8的所有东西都将是你的train集,否则你的测试设置。

我们如何做到这一点?创建排名就这么简单

df.groupby('user_id')['Timestamp'].rank(method='first')
Out[51]: 
0     1.0
1     2.0
2     3.0
3     4.0
4     5.0
5     6.0
6     7.0
7     8.0
8     9.0
9     1.0
10    2.0
11    3.0
12    4.0
13    5.0
14    6.0
15    7.0
16    8.0
17    9.0
Name: Timestamp, dtype: float64

然后您需要创建每个组中有多少值的映射。您可以在此处找到更多信息:Inplace transformation pandas with groupby。

df['user_id'].map(df.groupby('user_id')['Timestamp'].apply(len))
Out[52]: 
0     9
1     9
2     9
3     9
4     9
5     9
6     9
7     9
8     9
9     9
10    9
11    9
12    9
13    9
14    9
15    9
16    9
17    9
Name: user_id, dtype: int64

现在你可以把所有东西放在一起

ranks = df.groupby('user_id')['Timestamp'].rank(method='first')
counts = df['user_id'].map(df.groupby('user_id')['Timestamp'].apply(len))
(ranks / counts) > 0.8
Out[55]: 
0     False
1     False
2     False
3     False
4     False
5     False
6     False
7      True
8      True
9     False
10    False
11    False
12    False
13    False
14    False
15    False
16     True
17     True
dtype: bool

【讨论】:

以上是关于根据python中训练和测试集中的时间戳为每个用户拆分数据集的主要内容,如果未能解决你的问题,请参考以下文章

训练和测试集中不同数量的特征 - 随机森林 sklearn Python

在测试和训练数据集中使用基于时间的拆分来拆分数据

将训练集和测试集的数据除以训练集中的所有主题

如何使用 sklearn 中的 train_test_split 确保用户和项目同时出现在训练和测试数据集中?

SVM 分类器和测试图像

CIFAR-10和python读取