我正在尝试建立一个分类模型。我在本地文件夹中有1000个文本文档。我想将它们分成训练集和测试集,分数比为70:30(70->训练和30->测试)这样做的更好的方法是什么?我正在使用python。
注意: - 为了更好地理解,请解释为什么应该遵循该方法。
谢谢
更新: - 经过几次投票回到这个问题。虽然我得到了近乎完美的答案,但我还想简要回答一下这个问题。
我想以编程方式分割训练集和测试集。首先要读取本地目录中的文件。其次,构建这些文件的列表并对其进行随机播放。第三,将它们分成训练集和测试集。
作为python的初学者和新手,我尝试了一些方法,使用内置的python关键字和函数只会失败。最后我有了接近它的想法。此外,交叉验证是建筑物一般分类模型的一个很好的选择。谢谢你的回答。
答案 0 :(得分:6)
不确定完全你所追求的是什么,所以我会尽量全面。将有几个步骤:
我们假设您的文件都具有扩展名.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中等效于glob /ml/data/*.data
)。
我们不希望采样是可预测的,因为这被认为是训练ML分类器的一种不好的方法。
from random import shuffle
def randomize_files(file_list):
shuffle(file_list)
请注意random.shuffle
执行就地改组,因此会修改现有列表。 (当然这个函数相当愚蠢,因为你只需要调用shuffle
而不是randomize_files
;你可以把它写成另一个函数来使它更有意义。)
我假设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
这是您打开每个文件并进行培训和测试的步骤。我会留给你的!
出于好奇,您是否考虑过使用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系统的实际功能。
作为免责声明,我无论如何都不是专家,哈哈。但是,如果您对我在这里写的任何内容有任何疑问,请与我联系!
答案 1 :(得分:3)
如果你使用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']
答案 2 :(得分:1)
您可以使用sklearn提供的train_test_split方法。请参阅此处的文档:
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
答案 3 :(得分:0)
只需使用os.listdir()
列出文件名。使用collections.shuffle()
随机播放列表,然后training_files = filenames[:700]
和testing_files = filenames[700:]