使用分组约束在sklearn(python 2.7)中创建训练,测试和交叉验证数据集?

时间:2013-09-18 05:48:37

标签: python-2.7 numpy machine-learning data-mining scikit-learn

在创建火车时,测试&在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)

我的问题是我在csv文件中有一个字段说“A”我读入numpy数组,所有采样都应该尊重这个字段。也就是说,“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用户的横截面数据点,所以它必须放在一个独特的列车样本中,测试,或者cv),并且有很多这样的实体,因此需要按实体ID进行分组。

B,C,D列可以包含任何值,但不需要对其进行分组保存。 (额外奖励:我可以对多个领域的抽样进行分组吗?)

我尝试了什么:

一个。 查找A的所有唯一值 - 将此表示为我的样本我现在将样本分发到中间列车,中间和&amp; cv&amp;测试 - &gt;然后在其中每个文件中将其余行放入“A”值。 也就是说,如果火车进入“3”,测试为“2”,cv为“1”,则所有值为A的行都为3列,所有2个进入测试,所有1个进入cv。< / p>

  1. 当然,这种方法不具备可扩展性。
  2. 我怀疑,它可能会在数据集中引入偏差,因为A列中的1的数量,2的等数不等,这意味着这种方法不起作用!
  3. B中。我也尝试了 numpy.random.shuffle,或numpy.random.permutation ,按照这里的主题 - Numpy: How to split/partition a dataset (array) into training and test datasets for, e.g., cross validation?,但它不符合我的要求。

    ℃。第三个选项当然是编写自定义函数来执行此分组,然后根据每个组中的数据点数量平衡训练,测试和简历数据集。但只是想知道,如果已经有一种有效的方法来实现它吗?

    注意我的数据集很大,所以理想情况下我希望有一种确定性的方法来分区我的数据集,而不需要进行多次眼球扫描以确保分区正确。

    编辑第2部分:

    由于我没有找到符合我的采样标准的任何内容 - 我实际上编写了一个模块来对分组约束进行采样。这是 github代码。代码不是为大数据而编写的,因此效率不高。你应该问这个代码 - 请指出我如何改善运行时间。 https://github.com/ekta1007/Sampling-techniques/blob/master/sample_expedia.py

2 个答案:

答案 0 :(得分:2)

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

现有方法(如sklearn库)中没有这种功能的原因是因为它看起来非常人为,而且反制机器学习模型的想法。如果这些是某种实体,则不应将它们视为单独的数据点。如果您需要这种单独的表示,然后需要这样的划分,那么特定实体不能部分地进行测试测试并且部分地在训练中肯定会偏向整个模型。

总结一下 - 从机器学习的角度来看,你应该深入分析你的方法是否合理。如果你确定的话,我认为唯一的可能就是自己编写分段,就像过去使用很多ML库一样,我从未见过这样的功能。

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

答案 1 :(得分: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”)

类似地,我们也可以为验证部分创建示例。

干杯。

相关问题