文章目录

概要

成果

完整代码

整体架构流程

数据预处理

决策树类实现

训练和测试(基础)

训练和测试(进阶)

技术细节(没有按顺序)

一、设置随机种子

确保结果可复现

便于调试

科学实验的可重复性

真伪随机数对比(代码)

二、 减少数据冗余

代码解释

三、如何判断数据是否为连续特征

1.数据类型:

2.唯一值的数量

3.数据分布:

四、使用等区间离散化

1.减少特征的连续性

2.提高模型的解释性

3.简化模型输入

4.处理异常值

五、熵(Entropy)和基尼不纯度(Gini Impurity)的作用

1.熵(Entropy):

2. 基尼不纯度(Gini Impurity):

五、 决策树初始化

1. 终止条件

2. 初始化 best_gain 为 -1,best_feature_index 和 best_split_value 为 None

六、 网格搜索

概要

我们将以一个以英雄联盟对局胜负预测任务为基础为例

构建一个决策树模型,从数据预处理到模型训练和评估,再到参数优化(不同max_depth下的准确率,不同min_samples_split下的准确率,不同impurity_t下的准确率)和结果可视化

成果

通过网格搜索找到了最优的决策树参数配置,并在测试集上取得了较高的准确率。通过绘制不同参数组合下的准确率图,直观地展示了参数对模型性能的影响

完整代码

from collections import Counter

import pandas as pd

import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score

import seaborn as sns

import matplotlib.pyplot as plt

# 固定随机种子

RANDOM_SEED = 2020

# 数据路径

csv_data = r'C:\Users\16397\Desktop\tree\tree\data/high_diamond_ranked_10min.csv'

data_df = pd.read_csv(csv_data, sep=',') # 读入csv文件为pandas的DataFrame

data_df = data_df.drop(columns='gameId') # 舍去对局标号列

print(data_df.iloc[0]) # 输出第一行数据

data_df.describe() # 每列特征的简单统计信息

# 需要舍去的特征列

drop_features = ['blueGoldDiff', 'redGoldDiff',

'blueExperienceDiff', 'redExperienceDiff',

'blueCSPerMin', 'redCSPerMin',

'blueGoldPerMin', 'redGoldPerMin']

df = data_df.drop(columns=drop_features) # 舍去特征列

# 取出要作差值的特征名字(除去red前缀)

info_names = [c[3:] for c in df.columns if c.startswith('red')]

for info in info_names: # 对于每个特征名字

df['br' + info] = df['blue' + info] - df['red' + info] # 构造一个新的特征,由蓝色特征减去红色特征,前缀为br

# 原有的FirstBlood可删除

df = df.drop(columns=['blueFirstBlood', 'redFirstBlood'])

# 离散化每一列特征

discrete_df = df.copy() # 先复制一份数据

for c in df.columns[1:]: # 遍历每一列特征,跳过标签列

unique_values = df[c].nunique()

if unique_values <= 10: # 如果特征取值少于等于10个,直接跳过

continue

# 使用等区间离散化

discrete_df[c] = pd.cut(df[c], bins=10, labels=False)

# 准备数据

all_y = discrete_df['blueWins'].values # 所有标签数据

feature_names = discrete_df.columns[1:] # 所有特征的名称

all_x = discrete_df[feature_names].values # 所有原始特征值,pandas的DataFrame.values取出为numpy的array矩阵

# 划分训练集和测试集

x_train, x_test, y_train, y_test = train_test_split(all_x, all_y, test_size=0.2, random_state=RANDOM_SEED)

all_y.shape, all_x.shape, x_train.shape, x_test.shape, y_train.shape, y_test.shape # 输出数据行列信息

# 定义决策树类

class DecisionTree(object):

def __init__(self, classes, features, max_depth=10, min_samples_split=10, impurity_t='entropy'):

self.classes = classes

self.features = features

self.max_depth = max_depth

self.min_samples_split = min_samples_split

self.impurity_t = impurity_t

self.root = None # 定义根节点,未训练时为空

def impurity(self, labels):

if self.impurity_t == 'entropy':

counter = Counter(labels)

probabilities = [count / len(labels) for count in counter.values()]

entropy = -sum(p * np.log2(p) for p in probabilities)

return entropy

elif self.impurity_t == 'gini':

counter = Counter(labels)

probabilities = [count / len(labels) for count in counter.values()]

gini = 1 - sum(p ** 2 for p in probabilities)

return gini

else:

raise ValueError("Unsupported impurity type")

def gain(self, feature, labels):

total_impurity = self.impurity(labels)

values = np.unique(feature)

weighted_impurity = 0

for value in values:

subset_labels = labels[feature


足球标志图案的象征意义
女排世锦赛:法国无缘4强!赛后对巴西,中国女排点评一针见血