4

在 Python 中创建训练、测试和交叉验证示例时,我将默认方法视为 -:

1. 跳过标题后读取数据集 2. 创建训练、测试和交叉验证样本

 import csv
 with open('C:/Users/Train/Trainl.csv', 'r') as f1:
     next(f1)
     reader = csv.reader(f1, delimiter=',')
     input_set = []   
     for row in reader:
         input_set.append(row)

import numpy as np 
from numpy import genfromtxt
from sklearn import cross_validation
train, intermediate_set = cross_validation.train_test_split(input_set, train_size=0.6, test_size=0.4)
cv, test = cross_validation.train_test_split(intermediate_set, train_size=0.5, test_size=0.5)

我的问题是,我在读取到 numpy 数组的 csv 文件中有一个字段说“A”,并且所有采样都应该尊重这个字段。也就是说,“A”值相似的所有条目都应该放在一个样本中。

Line #|A | B | C | D 
1     |1 | 
2     |1 |
3     |1 |
4     |1 |
5     |2 |
6     |2 |
7     |2 |

必需:第 1、2、3、4 行应放入“一”样本中,第 5、6、7 行应放入“一”样本中。 A列的值是一个唯一的id,对应一个实体(可以看作是一个SINGLE用户上的横截面数据点,所以它必须放在一个唯一的train、test或cv样本中),并且有很多此类实体,因此需要按实体 ID 进行分组。

B、C、D 列可以有任何值,但不需要对它们进行分组保存。(奖励:我可以对多个字段的采样进行分组吗?)

我尝试了什么:

A.查找 A 的所有唯一值- 将其表示为我的样本我现在将样本分布在 -st train、intermediate & cv & test -> 然后将“A”值的其余行放在每个文件中. 也就是说,如果 train 有“3”的条目,“2”的测试和“1”的 cv,那么所有值为 A 为 3 的行都进入 train,所有的 2 进入测试,所有的 1 进入 cv。

  1. 当然,这种方法是不可扩展的。
  2. 而且我怀疑,它可能在数据集中引入了偏差,因为 A 列中 1 的数量、2 的数量等不相等,这意味着这种方法行不通!

B. 我还按照此处的线程尝试了 numpy.random.shuffle 或 numpy.random.permutation - Numpy: How to split/partition a dataset (array) into training and test datasets for, eg, cross validation? ,但它不符合我的要求。

C. 第三种选择当然是编写一个自定义函数来进行这种分组,然后根据每组中数据点的数量平衡训练、测试和 cv 数据集。但只是想知道,是否已经有一种有效的方法来实现这一点?

请注意,我的数据集很大,因此理想情况下,我希望有一种确定性的方式来划分我的数据集,而无需进行多次眼球扫描来确保分区正确。

编辑第 2 部分:

由于我没有找到任何符合我的抽样标准的东西 - 我实际上编写了一个模块来使用分组约束进行抽样。这是它的github代码。该代码不是为非常大的数据编写的,因此效率不高。如果您分叉此代码 - 请指出我如何改善运行时。 https://github.com/ekta1007/Sampling-techniques/blob/master/sample_expedia.py

4

2 回答 2

3

通过强制此类约束,您将向您的程序引入偏见。因此,基于“用户”数据的分区然后收集他们各自的“测量”的方法似乎并不坏。它会很好地扩展,这就是O(n)方法,不扩展的唯一原因是糟糕的实现,而不是糟糕的方法。

现有方法(如 sklearn 库)中没有此类功能的原因是因为它看起来非常人工,并且与机器学习模型的想法相反。如果这些在某种程度上是一个实体,那么它们不应被视为单独的数据点。如果您需要这种单独的表示,那么需要这种划分,即特定实体不能部分处于测试测试中而部分处于训练中,这肯定会使整个模型产生偏差。

总而言之——你应该从机器学习的角度真正深入分析你的方法是否合理。如果你确定的话,我认为唯一的可能就是自己编写分段,因为即使过去使用了许多 ML 库,我也从未见过这样的功能。

事实上,我不确定,如果将包含 N 个数字(实体大小)的集合分割成 K(=3)个给定总和比例的子集,被视为随机过程时,这个问题是否本身不是 NP 问题. 如果您不能保证均匀分布,那么您的数据集就不能用作训练/测试/验证模型的统计正确方法。即使它有一个合理的多项式解决方案,它仍然可以严重扩展(比线性方法差得多)。如果您的约束是“严格的”,那么这个疑问适用,如果它们是“弱”的,您总是可以采用“生成并拒绝”的方法,这应该具有摊销的线性复杂性。

于 2013-09-18T05:57:07.720 回答
0

我也面临着类似的问题,虽然我的编码不太好,但我想出了下面给出的解决方案:

  1. 创建了一个仅包含 df 的唯一 ID 并删除重复项的新数据框。
new = df[["Unique_Id "]].copy()
New_DF = new.drop_duplicates()
  1. 基于New_DF创建训练和测试集
train, test = train_test_split(New_DF, test_size=0.2)
  1. 然后将这些训练和测试集与原始 df 合并。
df_Test = pd.merge(df, test, how='inner', on = “Unique_Id”)
df_Train = pd.merge(df, train, how='inner', on = “Unique_Id”)

同样,我们也可以为验证部分创建样本。

干杯。

于 2019-11-11T05:59:23.280 回答