【问题标题】:How to split documents into training set and test set?如何将文档拆分为训练集和测试集?
【发布时间】:2017-07-17 05:30:15
【问题描述】:

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


我想要一种以编程方式分割训练集和测试集的方法。首先读取本地目录中的文件。其次,构建这些文件的列表并打乱它们。第三,将它们分成训练集和测试集。

我尝试了几种使用内置 python 关键字和函数的方法,但都失败了。最后我有了接近它的想法。此外,在构建通用分类模型时,交叉验证也是一个不错的选择。

【问题讨论】:

  • Scikit learn 有许多可用的功能,可以通过示例来做你想做的事。如果您发现应用有任何困难,请搜索网络并在此处发布
  • 这个问题有什么问题?为什么成员不赞成这个问题?
  • Stackoverflow 不是用来发表意见的。是用来编程的。你只是在问,没有表现出任何努力。
  • @VivekKumar 我已经为这些文件准备了 tf-idf。我问的问题是我在这个小项目上迈出的一步。我了解它的编程,我已经完成了。我在其他问题上看到了类似下面答案的描述。我只是想知道拆分文档时的最佳实践。仅供参考,我在提问之前已经编写了代码。
  • 下面的答案帮助我优化了它。我很感激它。 :)

标签: machine-learning scikit-learn text-classification


【解决方案1】:

不确定究竟你在追求什么,所以我会尽量全面。会有几个步骤:

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

1。获取文件列表

假设您的文件都具有扩展名.data,并且它们都在文件夹/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

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

2。随机化文件

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

from random import shuffle

def randomize_files(file_list):
    shuffle(file_list)

请注意,random.shuffle 执行 in-place 洗牌,因此它会修改现有列表。 (当然这个函数有点傻,因为你可以调用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

4。做事

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


交叉验证

出于好奇,您是否考虑过使用cross-validation?这是一种拆分数据的方法,以便您使用每个文档进行训练和测试。您可以自定义每个“折叠”中用于训练的文档数量。如果您愿意,我可以对此进行更深入的介绍,但如果您不想这样做,我不会这样做。

编辑:好的,既然你要求我会再解释一下。

所以我们有一个包含 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) 会有所不同。我们可以将函数转换为generator,而不是只分成两组(一组用于训练,一组用于测试)——我们可以像列表一样遍历该函数。

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

最后的 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)

同样,实现 ML 系统的实际功能取决于您。

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

【讨论】:

  • 我想将 1000 个文本文档 (.txt) 拆分为训练和测试集以实现 tf-idf 并应用算法以构建分类模型。根据我的目标将文档分为两个单独的类。
  • 是的,我考虑过交叉验证。但作为一个初学者,我想不去尝试它。我也请你解释一下。请。
  • FWIW,在您的 get_file_list_from_dir 函数中使用 dir 作为参数不是好的做法,因为 dir 是 Python 内置函数。也许试试directory之类的东西。
  • @not_a_robot 你是对的!我通常对此要好得多,但早些时候很着急,哈哈。现已更新;谢谢! :)
  • k-fold 交叉验证其实是倒序解释的。每次将 k 个子集中的一个作为测试集,将其他 k-1 个子集放在一起形成一个训练集。
【解决方案2】:

如果你使用 numpy 就很简单了,首先加载文档并将它们变成一个 numpy 数组,然后:

import numpy as np

docs = np.array([
    'one', 'two', 'three', 'four', 'five',
    'six', 'seven', 'eight', 'nine', 'ten',
    ])

idx = np.hstack((np.ones(7), np.zeros(3))) # generate indices
np.random.shuffle(idx) # shuffle to make training data and test data random

train = docs[idx == 1]
test = docs[idx == 0]

print(train)
print(test)

结果:

['one' 'two' 'three' 'six' 'eight' 'nine' 'ten']
['four' 'five' 'seven']

【讨论】:

    【解决方案3】:

    只需使用os.listdir() 列出文件名即可。使用collections.shuffle() 打乱列表,然后使用training_files = filenames[:700]testing_files = filenames[700:]

    【讨论】:

      【解决方案4】:

      您可以使用 sklearn 提供的 train_test_split 方法。在此处查看文档:

      http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-01
        • 1970-01-01
        • 2017-06-11
        • 2019-05-01
        • 2020-01-11
        • 1970-01-01
        • 2023-01-24
        • 2017-08-30
        相关资源
        最近更新 更多