如何将文档分为训练集和测试集?

Wat*_*236 -1 machine-learning scikit-learn text-classification

我正在尝试建立分类模型。我在本地文件夹中有1000个文本文档。我想将它们分为训练集和测试集,拆分比例为70:30(70->训练和30->测试),有什么更好的方法呢?我正在使用python。

注意:-为了更好的理解,请提供为什么应遵循该方法的解释。

谢谢

更新:-在对这个问题进行了几次投票之后。尽管我得到了接近完美的答案,但我还是想简单地介绍一下问题。

我希望以编程方式将训练集和测试集分开。首先读取本地目录中的文件。其次,构建这些文件的列表并对其进行随机排序。第三,将它们分为训练集和测试集。

作为python的初学者和新手,我尝试了几种使用内置python关键字和函数的方法,但都失败了。最后,我有了接近它的想法。同样,交叉验证是构建建筑物一般分类模型时要考虑的一个很好的选择。感谢您的回答。

Pie*_*agh 8

不确定您要追求的什么,因此我将尝试全面。将有几个步骤:

  1. 获取文件列表
  2. 随机化文件
  3. 将文件分为训练和测试集
  4. 做事情

1.获取文件列表

假设您的文件都具有扩展名,.data并且都位于folder中/ml/data/。我们要做的是获取所有这些文件的列表。只需使用os模块即可完成。我假设您没有子目录;如果有的话,这会改变。

import os

def get_file_list_from_dir(datadir):
    all_files = os.listdir(os.path.abspath(datadir))
    data_files = list(filter(lambda file: file.endswith('.data'), all_files))
    return data_files
Run Code Online (Sandbox Code Playgroud)

因此,如果要调用get_file_list_from_dir('/ml/data'),我们将返回该目录中所有.data文件的列表(在shell中等效于glob /ml/data/*.data)。

2.将文件随机化

我们不希望采样是可预测的,因为这被认为是训练ML分类器的不良方法。

from random import shuffle

def randomize_files(file_list):
    shuffle(file_list)
Run Code Online (Sandbox Code Playgroud)

请注意,它random.shuffle执行就地改组,因此会修改现有列表。(当然,此函数很愚蠢,因为您可以调用shuffle而不是randomize_files;您可以将此函数写入另一个函数以使其更有意义。)

3.将文件分为训练和测试集

我将假定70:30的比例,而不是任何特定数量的文档。所以:

from math import floor

def get_training_and_testing_sets(file_list):
    split = 0.7
    split_index = floor(len(file_list) * split)
    training = file_list[:split_index]
    testing = file_list[split_index:]
    return training, testing
Run Code Online (Sandbox Code Playgroud)

4.做事情

这是打开每个文件并进行培训和测试的步骤。我留给你!


交叉验证

出于好奇,您是否考虑过使用交叉验证?这是一种拆分数据的方法,因此您可以使用每个文档进行培训和测试。您可以自定义每个“折页”中用于培训的文档数量。如果您愿意,我可以对此做更深入的了解,但是如果您不想这样做,我不会。

编辑:好的,自您请求以来,我将对此进行解释。

因此,我们有1000个文档的数据集。交叉验证的想法是,您可以同时使用所有验证和培训,而不能一次使用。我们将数据集划分为所谓的“折叠”。折叠次数决定了在任何给定时间点的训练和测试集的大小。

假设我们想要一个10倍的交叉验证系统。这意味着训练和测试算法将运行十次。第一次将训练文件1-100,并测试101-1000。第二折将在101-200上训练,并在1-100和201-1000上测试。

例如,如果我们采用40折CV系统,则第一折将在文档1-25上进行训练并在26-1000上进行测试,第二折将在26-40上进行训练并在1-25和51-1000上进行测试,等等。

为了实现这样的系统,我们仍然需要从上面开始执行步骤(1)和(2),但是步骤(3)会有所不同。我们可以将函数变成生成器,而不是仅分成两组(一组用于训练,一组用于测试),而该函数可以像列表一样进行迭代。

def cross_validate(data_files, folds):
    if len(data_files) % folds != 0:
        raise ValueError(
            "invalid number of folds ({}) for the number of "
            "documents ({})".format(folds, len(data_files))
        )
    fold_size = len(data_files) // folds
    for split_index in range(0, len(data_files), fold_size):
        training = data_files[split_index:split_index + fold_size]
        testing = data_files[:split_index] + data_files[split_index + fold_size:]
        yield training, testing
Run Code Online (Sandbox Code Playgroud)

yield在最后的关键字是什么使这个发电机。要使用它,您将像这样使用它:

def ml_function(datadir, num_folds):
    data_files = get_file_list_from_dir(datadir)
    randomize_files(data_files)
    for train_set, test_set in cross_validate(data_files, num_folds):
        do_ml_training(train_set)
        do_ml_testing(test_set)
Run Code Online (Sandbox Code Playgroud)

同样,由您来实现ML系统的实际功能。

作为免责声明,我绝不是专家,哈哈。但是,如果您对我在这里写的任何内容有任何疑问,请告诉我!

  • FWIW,在你的 `get_file_list_from_dir` 函数中使用 `dir` 作为参数不是一个好习惯,因为 `dir` 是一个 Python 内置函数。也许尝试类似`directory`之类的东西。 (2认同)