注意 所有函数仅针对西瓜数据集 如果需要对其他数据集进行分类 只需找到数据集中目标值 西瓜数据集中目标值为是否是好瓜的 是 和 否 所在的列(西瓜数据集中其在最后一列) 然后将需要按照目标值进行运行的代码替换即可
留出法实现实现思路 根据留出法的原理 需要将数据集分为互斥的两个集合 一个作为训练集 另一个作为测试集 在数据划分过程中需要分层采样 为了生成多组数据 需要每次随机划分。
首先统计一下数据集中的正例的个数:
# 计算数据集中的正例数 for data in data_set: if data[-1] 是 : positive_size 1
然后计算一下需要的训练集的大小:
# 计算训练集大小 train_set_size int(percent / 100 * len(data_set) 0.5)
其中 percent是训练集占数据集的百分比 需要人为输入。
再然后计算一下训练集中需要的正例个数:
# 计算训练集中需要的正例大小 positive_train_data_size int( train_set_size / len(data_set) * positive_size 0.5)
为了每次划分都随机且训练集和测试集互斥 使用sample生成随机数作为即将采集训练的下标:
# 每组训练集和数据集保证随机划分 index_list random.sample(range(0, len(data_set)), len(data_set))
使用for循环分层训练集和测试集
# 划分训练集、数据集 for j in index_list: if data_set[j][-1] 是 : if positive_count positive_train_data_size: train_set.append(data_set[j]) positive_count 1 else: test_set.append(data_set[j]) else: if negative_count train_set_size - positive_train_data_size: train_set.append(data_set[j]) negative_count 1 else: test_set.append(data_set[j])
每生成完一组训练集和测试集就将其存起来
k_train_set.append(train_set) k_test_set.append(test_set)
总的程序如下
def setAside(data_set): 使用留出法生成数据集 positive_size 0 # 计算数据集中的正例数 for data in data_set: if data[-1] 是 or data[-1] 1 : positive_size 1 percent int(input( 训练集占总数据集百分比(1~99) )) # 计算训练集大小 train_set_size int(percent / 100 * len(data_set) 0.5) # 计算训练集中需要的正例大小 positive_train_data_size int( train_set_size / len(data_set) * positive_size 0.5) group_num int(input( 需要多少组 )) k_train_set, k_test_set [], [] # 生成训练集、测试集 for i in range(group_num): # 每组训练集和数据集保证随机划分 index_list random.sample(range(0, len(data_set)), len(data_set)) # 存放一组数据集和训练集 train_set, test_set [], [] # 训练集中正反例计数 为了确定正反例已存够 positive_count, negative_count 0, 0 # 划分训练集、数据集 for j in index_list: if data_set[j][-1] 是 or data[-1] 1 : if positive_count positive_train_data_size: train_set.append(data_set[j]) positive_count 1 else: test_set.append(data_set[j]) else: if negative_count train_set_size - positive_train_data_size: train_set.append(data_set[j]) negative_count 1 else: test_set.append(data_set[j]) k_train_set.append(train_set) k_test_set.append(test_set) # 返回训练集、数据集组 组数 return k_train_set, k_test_set, group_numk折交叉验证法实现
实现思路 K折交叉验证法是将数据集划分为k个互斥子集 取出一个作为测试集 其余作为训练集 且要分层采样 如果像留出法那样计算各个子集需要的各种数据 会导致程序太复杂 所以采用另外一种思路 就是将其按照是否是好瓜进行排序 然后依次存入各个列表。
首先 将数据集排序
# 按照表中最后一个元素来排序 便于分层 data_set.sort(key lambda k: k[-1])
然后将排好序的数据集依次存入大小为k的list
# 分层划分数据集为k份 for i in range(len(data_set)): k_list[i % k].append(data_set[i])
这样 数据就被分层分为了互斥的k份
然后将k份数据中的一份作为测试集 其他作为训练集来分类 每划分一次就将其结果存下来
# 生成k个数据集和k个训练集 for i in range(k): temp_set [] for j in range(k): if j ! i: temp_set.extend(k_list[j]) else: k_test_set.append(k_list[j]) k_train_set.append(temp_set)
总的程序如下
def crossValidate(data_set): 使用k折交叉验证法生成数据集 # 按照表中最后一个元素来排序 便于分层 data_set.sort(key lambda k: k[-1]) k int(input( 输入折数k(k 1) )) # 生成k个列表放在一个列表中 k_list list([] for i in range(k)) k_train_set list([]) k_test_set list([]) # 分层划分数据集为k份 for i in range(len(data_set)): k_list[i % k].append(data_set[i]) # 生成k个数据集和k个训练集 for i in range(k): temp_set [] for j in range(k): if j ! i: temp_set.extend(k_list[j]) else: k_test_set.append(k_list[j]) k_train_set.append(temp_set) # 返回训练集、数据集组 组数 return k_train_set, k_test_set, k自助法实现
实现思路 自助法就是从大小的m数据集中随机采样 本随机采样类似于放回抽样 m次数据 作为训练集 其余的作为测试集。
首先得到m的大小
m len(data_set)
为了可以生成多组训练集和测试集 所以生成需要的组数组随机数 每组随机数的范围为0~m-1 因为数据集的下标范围是从0开始到m-1结束
# 生成group组随机数 每组有m个 随机数的范围为0~m-1 ran_lis list([[random.randint(0, m-1)for i in range(m)] for j in range(group)])
然后分出训练集和测试集
# 生成训练集 测试集 for i in range(group): train_set [] test_set [] # 随机采样m个数据放在训练集中 for j in ran_lis[i]: train_set.append(data_set[j]) # 余下的数据放在测试集中 for data in data_set: if data not in train_set: test_set.append(data) k_train_set.append(train_set) k_test_set.append(test_set) 总的程序如下 def bootstrap(data_set): m len(data_set) group int(input( 需要多少组 )) # 生成group组随机数 每组有m个 随机数的范围为0~m-1 ran_lis list([[random.randint(0, m-1) for i in range(m)] for j in range(group)]) k_train_set [] k_test_set [] # 生成训练集 测试集 for i in range(group): train_set [] test_set [] # 随机采样m个数据放在训练集中 for j in ran_lis[i]: train_set.append(data_set[j]) # 余下的数据放在测试集中 for data in data_set: if data not in train_set: test_set.append(data) k_train_set.append(train_set) k_test_set.append(test_set) # 返回训练集、数据集组 组数 return k_train_set, k_test_set, group
其它读取数据集文件 保存生成的训练集和测试集到文件中以及调用这三个函数的程序等其他辅助程序不在此赘述 可点击此链接下载全部的文件。



