python实现ID3决策树及随机森林

前言

数据集及完整代码:https://download.csdn.net/download/qq_49101550/20464229


一、对数据集进行训练集和测试集划分

  从数据集中无放回地随机抽选80%的样本作为训练集,剩下的20%划分为测试集。将训练集和测试集分别存放到train_data.csv和test_data.csv文件中。
在这里插入图片描述

二、ID3算法实现

 1.实现ID3决策树算法的首要工作是数据的特征选择,需要在特征集合中挑选出能最大化减小数据样本集不确定程度的特征,将之作为节点。而不确定程度可以用信息增益来表示。根据熵和条件熵的概念,可以得知熵与条件熵的差就是样本集不确定程度的减少量,即信息增益。

  这里创建entropy()函数来计算熵:
在这里插入图片描述
  创建计算条件熵的函数entropy_S_A(),核心代码如下:

  创建函数get_root()计算信息增益,并挑选出信息增益最大的特征在特征列表中的下标big_index:
在这里插入图片描述

 2.creat_tree()函数递归构建决策树,返回树模型myTree。

  要先考虑到训练出来的模型应该以什么样的形式来表示,这里使用字典来表示生成的决策树模型。如图:
在这里插入图片描述
  从特征列表中取出信息增益最大的特征作为节点,将剩余的特征存放到copy_list列表里(作为递归时构建当前节点的另一边树枝时特征列表)。如图:

在这里插入图片描述
  筛选出训练集中节点特征的为某一特征值的所有样本。如图:
在这里插入图片描述
  如果筛选后样本数为空,则返回上个分支条件下数据集中占比最大的分类标签。如图:
在这里插入图片描述
  为了防止模型的过拟合可以设置预先剪枝。如图:
在这里插入图片描述
  如果特征列表为空,则返回占比最大的分类标签。如图:
在这里插入图片描述
在这里插入图片描述
  如果筛选后所有样本的分类标签是唯一值,则返回该值。如图:
在这里插入图片描述
  如果筛选后样本的分类标签不唯一,则递归建树。如图:
在这里插入图片描述

 3.对测试集进行分类预测,计算分类准确率。

  构建测试函数test()。如图:
在这里插入图片描述
  对测试集中的样本进行逐个预测。如图:
在这里插入图片描述
  计算准确率。如图:
在这里插入图片描述

三、随机森林

  随机森林是是由多棵相对独立的决策树构成的。在进行分类时,要保证每一棵树都尽可能完整地生长(不剪枝),每棵树都产生一个分类结果,最终的分类结果是由每棵决策树投票产生的(哪一个分类结果占比最大)。

 1.训练集的选取

将一个样本容量为N的样本,有放回的抽取N次,每次抽取1个,最终形成N个样本,此样本作为随机森林中一棵树的训练集。如图:
在这里插入图片描述
  当每个样本有M个属性时,随机从这M个属性中选取出 在这里插入图片描述个属性作为随机森林每棵决策树的属性列表,如图:
在这里插入图片描述
  生成森林,如图:
在这里插入图片描述
  投票选择最终的分类标签,如图:
在这里插入图片描述

代码及数据集:https://download.csdn.net/download/qq_49101550/20464229

python实现朴素贝叶斯:
https://download.csdn.net/download/qq_49101550/20464382

python实现KNN:
https://download.csdn.net/download/qq_49101550/20464377

python实现PageRank:
https://download.csdn.net/download/qq_49101550/20464361

python实现KMeans:
https://download.csdn.net/download/qq_49101550/20464286

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
ID3算法是一种决策树学习算法,用于分类和预测。下面是实现ID3算法的步骤: 1. 计算每个特征的信息增益,选择信息增益最大的特征作为根节点。 2. 将数据集按照根节点特征值分成不同的子集。 3. 对每个子集递归执行步骤1和2,直到所有的叶子节点都是同一类别。 下面是一个Python实现ID3算法的示例代码: ```python import math def entropy(class_probabilities): """计算熵""" return sum(-p * math.log(p, 2) for p in class_probabilities if p) def class_probabilities(labels): """计算各个类的概率""" total_count = len(labels) return [count / total_count for count in collections.Counter(labels).values()] def data_entropy(labeled_data): """计算数据集的熵""" labels = [label for _, label in labeled_data] probabilities = class_probabilities(labels) return entropy(probabilities) def partition_entropy(subsets): """计算数据集的加权平均熵""" total_count = sum(len(subset) for subset in subsets) return sum(data_entropy(subset) * len(subset) / total_count for subset in subsets) def partition_by(inputs, attribute): """按照某个特征进行分组""" groups = collections.defaultdict(list) for input in inputs: key = input[0][attribute] groups[key].append(input) return groups def partition_entropy_by(inputs, attribute): """计算按照某个特征分组后的数据集的加权平均熵""" partitions = partition_by(inputs, attribute) return partition_entropy(partitions.values()) def build_tree_id3(inputs, split_attributes): """构建ID3决策树""" class_labels = [label for _, label in inputs] if len(set(class_labels)) == 1: # 所有样本属于同一类别,返回叶子节点 return class_labels[0] if not split_attributes: # 没有可用特征,返回该节点样本数最多的类别 return max(set(class_labels), key=class_labels.count) # 选择最优特征 def score(attribute): return partition_entropy_by(inputs, attribute) best_attribute = min(split_attributes, key=score) # 构建子树 partitions = partition_by(inputs, best_attribute) new_attributes = [a for a in split_attributes if a != best_attribute] subtrees = {attribute_value: build_tree_id3(subset, new_attributes) for attribute_value, subset in partitions.items()} subtrees[None] = max(set(class_labels), key=class_labels.count) return (best_attribute, subtrees) def classify(tree, input): """对输入进行分类""" if tree in (True, False): return tree attribute, subtree_dict = tree subtree_key = input.get(attribute) if subtree_key not in subtree_dict: subtree_key = None subtree = subtree_dict[subtree_key] return classify(subtree, input) # 示例 inputs = [ ({'level': 'Senior', 'lang': 'Java', 'tweets': 'no', 'phd': 'no'}, False), ({'level': 'Senior', 'lang': 'Java', 'tweets': 'no', 'phd': 'yes'}, False), ({'level': 'Mid', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'R', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'R', 'tweets': 'yes', 'phd': 'yes'}, False), ({'level': 'Mid', 'lang': 'R', 'tweets': 'yes', 'phd': 'yes'}, True), ({'level': 'Senior', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, False), ({'level': 'Senior', 'lang': 'R', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Senior', 'lang': 'Python', 'tweets': 'yes', 'phd': 'yes'}, True), ({'level': 'Mid', 'lang': 'Python', 'tweets': 'no', 'phd': 'yes'}, True), ({'level': 'Mid', 'lang': 'Java', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'no', 'phd': 'yes'}, False) ] split_attributes = ['level', 'lang', 'tweets', 'phd'] tree = build_tree_id3(inputs, split_attributes) print(classify(tree, {'level': 'Junior', 'lang': 'Java', 'tweets': 'yes', 'phd': 'no'})) # True ``` 随机森林算法是一种基于决策树的集成学习算法,它通过随机选择特征和数据样本来构建多个决策树,并将它们的预测结果进行投票或平均,最终得到最终的预测结果。下面是实现随机森林算法的步骤: 1. 对于每棵决策树,从训练数据集中随机选择一个子集。 2. 对于每棵决策树,从特征集合中随机选择一个子集。 3. 对于每棵决策树,使用ID3算法构建决策树。 4. 对于测试数据,对每个样本进行预测,将所有决策树的预测结果进行投票或平均,得到最终的预测结果。 下面是一个Python实现随机森林算法的示例代码: ```python import random def build_tree_random_forest(inputs, split_attributes): """构建随机森林""" class_labels = [label for _, label in inputs] if len(set(class_labels)) == 1: # 所有样本属于同一类别,返回叶子节点 return class_labels[0] if not split_attributes: # 没有可用特征,返回该节点样本数最多的类别 return max(set(class_labels), key=class_labels.count) # 随机选择特征和数据集 selected_inputs = [random.choice(inputs) for _ in inputs] selected_attributes = random.sample(split_attributes, int(math.sqrt(len(split_attributes)))) # 选择最优特征 def score(attribute): return partition_entropy_by(selected_inputs, attribute) best_attribute = min(selected_attributes, key=score) # 构建子树 partitions = partition_by(selected_inputs, best_attribute) new_attributes = [a for a in split_attributes if a != best_attribute] subtrees = {attribute_value: build_tree_random_forest(subset, new_attributes) for attribute_value, subset in partitions.items()} subtrees[None] = max(set(class_labels), key=class_labels.count) return (best_attribute, subtrees) def classify_random_forest(trees, input): """对输入进行分类""" votes = [classify(tree, input) for tree in trees] return max(set(votes), key=votes.count) # 示例 inputs = [ ({'level': 'Senior', 'lang': 'Java', 'tweets': 'no', 'phd': 'no'}, False), ({'level': 'Senior', 'lang': 'Java', 'tweets': 'no', 'phd': 'yes'}, False), ({'level': 'Mid', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'R', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'R', 'tweets': 'yes', 'phd': 'yes'}, False), ({'level': 'Mid', 'lang': 'R', 'tweets': 'yes', 'phd': 'yes'}, True), ({'level': 'Senior', 'lang': 'Python', 'tweets': 'no', 'phd': 'no'}, False), ({'level': 'Senior', 'lang': 'R', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Senior', 'lang': 'Python', 'tweets': 'yes', 'phd': 'yes'}, True), ({'level': 'Mid', 'lang': 'Python', 'tweets': 'no', 'phd': 'yes'}, True), ({'level': 'Mid', 'lang': 'Java', 'tweets': 'yes', 'phd': 'no'}, True), ({'level': 'Junior', 'lang': 'Python', 'tweets': 'no', 'phd': 'yes'}, False) ] split_attributes = ['level', 'lang', 'tweets', 'phd'] trees = [build_tree_random_forest(inputs, split_attributes) for _ in range(10)] print(classify_random_forest(trees, {'level': 'Junior', 'lang': 'Java', 'tweets': 'yes', 'phd': 'no'})) # True ``` 注意,在实际应用中,为了防止过拟合,需要对随机森林进行一些优化,例如设置每棵决策树的最大深度、设置叶子节点的最小样本数等。此外,还可以使用交叉验证来选择最优的超参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开朗小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值