【问题标题】:How do I divide a dataset into training and test sets using Weka?如何使用 Weka 将数据集划分为训练集和测试集?
【发布时间】:2015-03-23 07:42:53
【问题描述】:

我想将 CSV 格式的百万记录数据集划分为 80% 用于训练和 20% 用于测试。如何使用 Java 或 Weka 库对此进行编码?

【问题讨论】:

  • 你为什么不使用标准随机数生成器随机做呢?
  • 正如 JS Meier 所说:逐行读取文件并决定是否要将此类行放入 TEST.csv 文件或 TRAIN.csv 文件。网络上有数百个如何处理文本文件的示例。
  • 你说的我能理解。但是朋友们,如果我要更改和更新数据集,我需要手动处理每个数据集。实际上我想用这个来进行机器学习,所以需要适当的随机数据集处理,你的想法会增加处理成本。如果你能理解我在说什么,那么你再给我一个想法。

标签: java csv weka


【解决方案1】:

您可以在 Java 中使用名为 StratifiedRemoveFolds 的过滤器在 Weka 库中执行此操作

// Load data  
DataSource source = new DataSource("/some/where/data.csv");
Instances data = source.getDataSet();

// Set class to last attribute
if (data.classIndex() == -1)
    data.setClassIndex(data.numAttributes() - 1);

// use StratifiedRemoveFolds to randomly split the data  
StratifiedRemoveFolds filter = new StratifiedRemoveFolds();

// set options for creating the subset of data
String[] options = new String[6];

options[0] = "-N";                 // indicate we want to set the number of folds                        
options[1] = Integer.toString(5);  // split the data into five random folds
options[2] = "-F";                 // indicate we want to select a specific fold
options[3] = Integer.toString(1);  // select the first fold
options[4] = "-S";                 // indicate we want to set the random seed
options[5] = Integer.toString(1);  // set the random seed to 1

filter.setOptions(options);        // set the filter options
filter.setInputFormat(data);       // prepare the filter for the data format    
filter.setInvertSelection(false);  // do not invert the selection

// apply filter for test data here
Instances test = Filter.useFilter(data, filter);

//  prepare and apply filter for training data here
filter.setInvertSelection(true);     // invert the selection to get other data 
Instances train = Filter.useFilter(data, filter);

【讨论】:

    【解决方案2】:

    你可以使用Instances提供的方法先随机化你的数据

    Random rand = new Random(seed);   // create seeded number generator
    randData = new Instances(data);   // create copy of original data
    randData.randomize(rand);         // randomize data with number generator
    

    如果您的数据具有名义类别并且您想要执行分层交叉验证:

    randData.stratify(folds);
    

    现在,通常您需要进行交叉验证并执行以下操作:

    for (int n = 0; n < folds; n++) {
        Instances train = randData.trainCV(folds, n);
        Instances test = randData.testCV(folds, n);
    
        // further processing, classification, etc.
        ...
    }
    

    (源码其实提到“上面的代码是被weka.filters.supervised.instance.StratifiedRemoveFolds过滤器使用的”)

    但如果您只想要一组 80/20 个实例,那么只需执行一次:

    Instances train = randData.trainCV(folds, 0);
    Instances test = randData.testCV(folds, 0);
    

    Source

    【讨论】:

    • @Sentry 您的 for 循环如何划分训练集和测试集?例如,如果我想要 %90 的数据是训练集,而 %10 是测试集,如何创建它?
    • 我做的方式(使用Weka的方法),数据总是被划分,所以(k-1)/k是训练集,1/k是测试集。如果要除以 90/10,则必须选择 k=10。如果不想有 10 个不同的拆分,请使用上述方法,不要使用 for 循环。
    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 2016-04-04
    • 2015-12-21
    • 1970-01-01
    • 2019-05-01
    • 2019-12-06
    • 2012-12-04
    • 2019-10-15
    相关资源
    最近更新 更多