如何将文档拆分为训练集和测试集?
How to split documents into training set and test set?
我正在尝试构建分类模型。我在本地文件夹中有 1000 个文本文档。我想将它们分成训练集和测试集,分割比例为 70:30(70 -> Training and 30 -> Test) 这样做的更好方法是什么?我正在使用 python.
我想要一种以编程方式拆分训练集和测试集的方法。首先读取本地目录中的文件。其次,构建这些文件的列表并将它们打乱。第三,将它们分成训练集和测试集。
我尝试了几种使用内置 python 关键字和函数的方法,但都失败了。最后我有了接近它的想法。交叉验证也是构建通用分类模型的一个不错的选择。
只需使用 os.listdir()
列出文件名。使用 collections.shuffle()
打乱列表,然后 training_files = filenames[:700]
和 testing_files = filenames[700:]
如果你使用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']
不确定确切地你想要什么,所以我会尽量全面。会有几个步骤:
- 获取文件列表
- 随机化文件
- 将文件拆分为训练集和测试集
- 做事
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 中相当于 glob /ml/data/*.data
).
2。随机化文件
我们不希望采样是可预测的,因为这被认为是训练 ML 分类器的糟糕方法。
from random import shuffle
def randomize_files(file_list):
shuffle(file_list)
请注意,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
4。做事
这是您打开每个文件并进行训练和测试的步骤。这个就交给你了!
交叉验证
出于好奇,您是否考虑过使用 cross-validation?这是一种拆分数据的方法,以便您使用每个文档进行训练和测试。您可以自定义每个 "fold" 中用于训练的文档数量。如果你愿意,我可以更深入地讨论这个问题,但如果你不想这样做,我不会。
编辑:好的,既然你要求我再解释一下。
所以我们有一个包含 1000 个文档的数据集。交叉验证的想法是,您可以使用 all 进行训练和测试——只是不能同时使用。我们将数据集拆分为我们所说的 "folds"。折叠的数量决定了任何给定时间点的训练集和测试集的大小。
假设我们想要一个 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)
同样,实现机器学习系统的实际功能取决于您。
声明一下,我不是专家,哈哈。但是,如果您对我在这里写的任何内容有任何疑问,请告诉我!
你可以使用sklearn提供的train_test_split方法。请参阅此处的文档:
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
我正在尝试构建分类模型。我在本地文件夹中有 1000 个文本文档。我想将它们分成训练集和测试集,分割比例为 70:30(70 -> Training and 30 -> Test) 这样做的更好方法是什么?我正在使用 python.
我想要一种以编程方式拆分训练集和测试集的方法。首先读取本地目录中的文件。其次,构建这些文件的列表并将它们打乱。第三,将它们分成训练集和测试集。
我尝试了几种使用内置 python 关键字和函数的方法,但都失败了。最后我有了接近它的想法。交叉验证也是构建通用分类模型的一个不错的选择。
只需使用 os.listdir()
列出文件名。使用 collections.shuffle()
打乱列表,然后 training_files = filenames[:700]
和 testing_files = filenames[700:]
如果你使用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']
不确定确切地你想要什么,所以我会尽量全面。会有几个步骤:
- 获取文件列表
- 随机化文件
- 将文件拆分为训练集和测试集
- 做事
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 中相当于 glob /ml/data/*.data
).
2。随机化文件
我们不希望采样是可预测的,因为这被认为是训练 ML 分类器的糟糕方法。
from random import shuffle
def randomize_files(file_list):
shuffle(file_list)
请注意,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
4。做事
这是您打开每个文件并进行训练和测试的步骤。这个就交给你了!
交叉验证
出于好奇,您是否考虑过使用 cross-validation?这是一种拆分数据的方法,以便您使用每个文档进行训练和测试。您可以自定义每个 "fold" 中用于训练的文档数量。如果你愿意,我可以更深入地讨论这个问题,但如果你不想这样做,我不会。
编辑:好的,既然你要求我再解释一下。
所以我们有一个包含 1000 个文档的数据集。交叉验证的想法是,您可以使用 all 进行训练和测试——只是不能同时使用。我们将数据集拆分为我们所说的 "folds"。折叠的数量决定了任何给定时间点的训练集和测试集的大小。
假设我们想要一个 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)
同样,实现机器学习系统的实际功能取决于您。
声明一下,我不是专家,哈哈。但是,如果您对我在这里写的任何内容有任何疑问,请告诉我!
你可以使用sklearn提供的train_test_split方法。请参阅此处的文档:
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html