一、实验目的及要求
1)实验目的
- 了解决策树的工作机制;
- 掌握决策树模型及模型改进流程;
- 熟悉并建立随机森林分类模型。
2)实验要求
- 根据实验题目编写好源程序;
- 对上机操作过程中可能出现的问题预先分析,确定调试步骤和测试方法;
- 输入一定数量的测试数据,对运行结果进行分析;
- 上机实验后, 认真写出实验报告,对上机中出现的问题进行分析、总结。
二、实验环境(工具、配置等)
- 硬件要求:计算机一台;
- 软件要求:Mac操作系统,本实验在jupyter notebook上进行开发。
三、实验内容(实验方案、实验步骤、设计思路等)
1)实验方案
- 学习并跟随着蓝桥云课完成此次试验;
- 在实验中构建Adult数据集决策树,加载数据后对数据进行处理,经过数据处理,创建一个决策树分类器;
- 对决策树参数进行调整,并且明白这些参数的意义,通过多次建模,训练提高精确度;
- 建立随机森林分类模型,利用scikit-learn提供的随机森林算法建立相应的分类预测模型。
2)实验步骤
-
模型定义:
- 打开蓝桥实验楼的实验环境;
- 导入实验所需要的模块。
-
数据处理和加载:
- 加载数据集;
- 根据实验要求创建一个示例数据集并划分训练数据和测试数据;
- 使用scikit-learn提供的方法绘制一棵决策树;
- 对数据进行必要的清洗,将目标数值转换为0,1二元数值,将Age修复为整数类型;
- 对数据进行一些预处理,区分数据集中的类别和连续特征,并对缺失数据进行填充,对类别特征进行独热编码;
- 创建零值特征进行补齐测试数据。
-
训练模型:
- 根据实验内容实现香农熵计算函数entrop();
- 实现信息增益的计算函数information_gain(root,left,right);
- 实现基于信息增益划分函数best_feature_to_split;
- 通过递归调用划分函数实现一个简单的树构建决策,并输出每一步的熵变化;
- 构建Adult数据集决策树,加载并读取该数据集;
- 使用训练数据创建一个决策树分类器;
- 使用GridSearchCV网格搜索对决策树进行调参并返回最佳参数,输出精确度;
- 建立随机森立分类模型,构建RandomForestClassifier随机森林分类器。
-
训练过程可视化;
-
测试,并多次修改。
3)设计思路:
-
首先,对于第一个示例来了解简单决策树的工作机制,需要自己创建示例数据集,指定一些训练和测试数据,然后根据训练数据集理解基于信息熵的决策树,利用scikit-learn提供的方法绘制决策树。
-
接下来,在计算熵和信息增益的时候,需要实现香农熵函数、信息增益的计算函数和基于信息增益划分函数,再实现一个简单的树构建策略,并输出每一步的熵变化,这对了解决策树的生成也很有帮助。
-
接下来,构建Adult数据决策树。这是一个比较完整的例子,在加载数据集后需要对数据进行一系列的处理,将目标值转换为0,1二元数值,将浮点类型处理为整型,对缺失数据进行填充等等预处理操作。
-
将数据处理完后使用训练数据创建一个决策树分类器,再对决策树模型进行参数的调整,查看在测试集上的准确度。
-
最后建立随机森林分类模型,利用scikit-learn提供的随机森林算法建立相应的分类预测模型,并输出在测试集上的分类预测模型。
四、实验结果
简单示例练习
- 创建示例数据集
# 创建示例数据集,并对数据类别进行独热编码
def create_df(dic, feature_list):
out = pd.DataFrame(dic)
out = pd.concat([out, pd.get_dummies(out[feature_list])], axis=1)
out.drop(feature_list, axis=1, inplace=True)
return out
# 保证独热编码后的特征在训练和测试数据中同时存在
def intersect_features(train, test):
common_feat = list(set(train.keys()) & set(test.keys()))
return train[common_feat], test[common_feat]
- 定义特征
features = ['Looks', 'Alcoholic_beverage', 'Eloquence', 'Money_spent']
- 训练数据
df_train = {}
df_train['Looks'] = ['handsome', 'handsome', 'handsome', 'repulsive',
'repulsive', 'repulsive', 'handsome']
df_train['Alcoholic_beverage'] = [
'yes', 'yes', 'no', 'no', 'yes', 'yes', 'yes']
df_train['Eloquence'] = ['high', 'low', 'average', 'average', 'low',
'high', 'average']
df_train['Money_spent'] = ['lots', 'little', 'lots', 'little', 'lots',
'lots', 'lots']
df_train['Will_go'] = LabelEncoder().fit_transform(
['+', '-', '+', '-', '-', '+', '+'])
df_train = create_df(df_train, features)
df_train
图一 训练数据的结果图
- 测试数据
df_test = {}
df_test['Looks'] = ['handsome', 'handsome', 'repulsive']
df_test['Alcoholic_beverage'] = ['no', 'yes', 'yes']
df_test['Eloquence'] = ['average', 'high', 'average']
df_test['Money_spent'] = ['lots', 'little', 'lots']
df_test = create_df(df_test, features)
df_test
# 保证独热编码后的特征在训练和测试数据中同时存在
y = df_train['Will_go']
df_train, df_test = intersect_features(train=df_train, test=df_test)
图二 测试集
- 绘制一颗基于信息熵的决策树。
dt = DecisionTreeClassifier(criterion='entropy', random_state=17)
dt.fit(df_train, y)
tree_str = export_graphviz(
dt, feature_names=df_train.columns, out_file=None, filled=True)
graph = pydotplus.graph_from_dot_data(tree_str)
SVG(graph.create_svg())
- 实现香农熵计算函数
entropy()
from math import log
def entropy(a_list):
lst = list(a_list)
size = len(lst) * 1.0
entropy = 0
set_elements = len(set(lst))
if set_elements in [0, 1]:
return 0
for i in set(lst):
occ = lst.count(i)
entropy -= occ/size * log(occ/size, 2)
return entropy
图七 列表 ball_left 给出状态的熵
- 实现信息增益的计算函数
information_gain(root, left, right)
def information_gain(root, left, right):
return entropy(root) - 1.0 * len(left) / len(root) * entropy(left) \
- 1.0 * len(right) / len(root) * entropy(right)
- 实现基于信息增益划分函数
best_feature_to_split
def best_feature_to_split(X, y):
'''信息增益用于特征分割'''
out = []
for i in X.columns:
out.append(information_gain(y, y[X[i] == 0], y[X[i] == 1]))
return out
- 通过递归调用 best_feature_to_split 实现一个简单的树构建策略,并输出每一步的熵变化
def btree(X, y):
clf = best_feature_to_split(X, y)
param = clf.index(max(clf))
ly = y[X.iloc[:, param] == 0]
ry = y[X.iloc[:, param] == 1]
print('Column_' + str(param) + ' N/Y?')
print('Entropy: ', entropy(ly), entropy(ry))
print('N count:', ly.count(), '/', 'Y count:', ry.count())
if entropy(ly) != 0:
left = X[X.iloc[:, param] == 0]
btree(left, ly)
if entropy(ry) != 0:
right = X[X.iloc[:, param] == 1]
btree(right, ry)
构建Adult 数据集决策树
- 加载人口收入普查数据集
data_train = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult_train.csv', sep=';')
data_test = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult_test.csv', sep=';')
- 人口收入普查数据集中的特征
- Age – 连续数值特征
- Workclass – 连续数值特征
- fnlwgt – 连续数值特征
- Education – 类别特征
- Education_Num – 连续数值特征
- Martial_Status – 类别特征
- Occupation – 类别特征
- Relationship – 类别特征
- Race – 类别特征
- Sex – 类别特征
- Capital_Gain – 连续数值特征
- Capital_Loss – 连续数值特征
- Hours_per_week – 连续数值特征
- Country – 类别特征
- Target – 收入水平,二元分类目标值
- 对数据集进行一些必要的清洗。同时,将目标值转换为 0,1 二元数值:
# 移除测试集中的错误数据
data_test = data_test[(data_test['Target'] == ' >50K.')
| (data_test['Target'] == ' <=50K.')]
# 将目标编码为 0 和 1
data_train.loc[data_train['Target'] == ' <=50K', 'Target'] = 0
data_train.loc[data_train['Target'] == ' >50K', 'Target'] = 1
data_test.loc[data_test['Target'] == ' <=50K.', 'Target'] = 0
data_test.loc[data_test['Target'] == ' >50K.', 'Target'] = 1
- 绘制各项特征的关联分布图像:
fig = plt.figure(figsize=(25, 15))
cols = 5
rows = np.ceil(float(data_train.shape[1]) / cols)
for i, column in enumerate(data_train.columns):
ax = fig.add_subplot(rows, cols, i + 1)
ax.set_title(column)
if data_train.dtypes[column] == np.object:
data_train[column].value_counts().plot(kind="bar", axes=ax)
else:
data_train[column].hist(axes=ax)
plt.xticks(rotation="vertical")
plt.subplots_adjust(hspace=0.7, wspace=0.2)
- 将Age特征类型由object变为整形
data_test['Age'] = data_test['Age'].astype(int)
- 将测试数据中浮点类型特征全部处理成整数类型,以便与训练数据对应:
data_test['fnlwgt'] = data_test['fnlwgt'].astype(int)
data_test['Education_Num'] = data_test['Education_Num'].astype(int)
data_test['Capital_Gain'] = data_test['Capital_Gain'].astype(int)
data_test['Capital_Loss'] = data_test['Capital_Loss'].astype(int)
data_test['Hours_per_week'] = data_test['Hours_per_week'].astype(int)
- 从数据集中选择类别和连续特征变量:
categorical_columns = [c for c in data_train.columns
if data_train[c].dtype.name == 'object']
numerical_columns = [c for c in data_train.columns
if data_train[c].dtype.name != 'object']
print('categorical_columns:', categorical_columns)
print('numerical_columns:', numerical_columns)
- 对连续特征使用中位数对缺失数据进行填充,而类别特征则使用众数进行填充:
for c in categorical_columns:
data_train[c].fillna(data_train[c].mode(), inplace=True)
data_test[c].fillna(data_train[c].mode(), inplace=True)
for c in numerical_columns:
data_train[c].fillna(data_train[c].median(), inplace=True)
data_test[c].fillna(data_train[c].median(), inplace=True)
- 对类别特征进行独热编码,以保证数据集特征全部为数值类型方便后续传入模型:
data_train = pd.concat([data_train[numerical_columns],
pd.get_dummies(data_train[categorical_columns])], axis=1)
data_test = pd.concat([data_test[numerical_columns],
pd.get_dummies(data_test[categorical_columns])], axis=1)
set(data_train.columns) - set(data_test.columns)
data_train.shape, data_test.shape
'''
独热编码之后发现测试数据中没有 Holland,为了与训练数据对应,这里需要创建零值特征进行补齐。
'''
data_test['Country_ Holand-Netherlands'] = 0
set(data_train.columns) - set(data_test.columns)
- 去除target特性
X_train = data_train.drop(['Target'], axis=1)
y_train = data_train['Target']
X_test = data_test.drop(['Target'], axis=1)
y_test = data_test['Target']
寻找决策树参数模型
- 使用默认参数,
max_depth=3,random_state=17:
tree = DecisionTreeClassifier(max_depth=3, random_state=17)
tree.fit(X_train, y_train)
tree_predictions = tree.predict(X_test)
accuracy_score(y_test, tree_predictions)
一些重要重要参数
- criterion Criterion这个参数正是用来决定不纯度的计算方法的。
sklearn提供了两种选择:
1)输入“entropy”, 使用信息熵(Entropy)
2)输入“gini”,使用基尼系数(Gini Impurity)
注意, 当使用信息熵时, sklearn实际计算的是基于信息熵的信息增益(Information Gain), 即父节点的信息熵和子节点的信息熵之差. 比起基尼系数, 信息熵对不纯度更加敏感, 对不纯度的惩罚最强. 但是在实际使用中,信息熵和基尼系数的效果基本相同. 信息熵的计算比基尼系数缓慢一些, 因为基尼系数的计算不涉及对数. 另外, 因为信息熵对不纯度更加敏感, 所以信息熵作为指标时, 决策树的生长会更加“精细”, 因此对于高维数据或者噪音很多的数据, 信息熵很容易过拟合, 基尼系数在这种情况下效果往往比较好. 当模型拟合程度不足的时候, 即当模型在训练集和测试集上都表 现不太好的时候, 使用信息熵. 当然, 这些不是绝对的。
- random_state & splitter
random_state用来设置分枝中的随机模式的参数, 默认None, 在高维度时随机性会表现更明显,低维度的数据 (比如鸢尾花数据集), 随机性几乎不会显现. 输入任意整数, 会一直长出同一棵树, 让模型稳定下来. splitter也是用来控制决策树中的随机选项的, 有两种输入值, 输入”best", 决策树在分枝时虽然随机, 但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看), 输入“random”, 决策树在 分枝时会更加随机, 树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合. 这也是防止过拟合的一种方式. 当你预测到你的模型会过拟合, 用这两个参数来帮助你降低树建成之后过拟合的可能性. 当然, 树一旦建成,我们依然是使用剪枝参数来防止过拟合.
剪枝参数
不加限制的情况下, 一棵决策树会生长到衡量不纯度的指标最优, 或者没有更多的特征可用为止. 这样的决策树往往会过拟合, 这就是说, 它会在训练集上表现很好, 在测试集上却表现糟糕. 我们收集的样本数据不可能和整体的状况完全一致, 因此当一棵决策树对训练数据有了过于优秀的解释性, 它找出的规则必然包含了训练样本中的噪声, 并使它对未知数据的拟合程度不足。
为了让决策树有更好的泛化性, 我们要对决策树进行剪枝. 剪枝策略对决策树的影响巨大, 正确的剪枝策略是优化决策树算法的核心. sklearn为我们提供了不同的剪枝策略:
- max_depth: 限制树的最大深度, 超过设定深度的树枝全部剪掉. 这是用得最广泛的剪枝参数, 在高维度低样本量时非常有效. 决策树多生长一层, 对样本量的需求会增加一倍, 所以限制树深度能够有效地限制过拟合. 在集成算法中也非常实用. 实际使用时, 建议从=3开始尝试, 看看拟合的效果再决定是否增加设定深度。
- min_samples_leaf & min_samples_split
min_samples_leaf限定, 一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本, 否则分枝就不会发生; 或者, 分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生.
一般搭配max_depth使用, 在回归树中有神奇的效果, 可以让模型变得更加平滑. 这个参数的数量设置得太小会引 起过拟合, 设置得太大就会阻止模型学习数据. 一般来说, 建议从=5开始使用. 如果叶节点中含有的样本量变化很大, 建议输入浮点数作为样本量的百分比来使用. 同时, 这个参数可以保证每个叶子的最小尺寸, 可以在回归问题 中避免低方差, 过拟合的叶子节点出现. 对于类别不多的分类问题, =1通常就是最佳选择. min_samples_split限定, 一个节点必须要包含至少min_samples_split个训练样本, 这个节点才允许被分枝, 否则分枝就不会发生.
- max_features & min_impurity_decrease
max_features限制分枝时考虑的特征个数, 超过限制个数的特征都会被舍弃. 和max_depth异曲同工, max_features是用来限制高维度数据的过拟合的剪枝参数, 但其方法比较暴力, 是直接限制可以使用的特征数量而强行使决策树停下的参数, 在不知道决策树中的各个特征的重要性的情况下, 强行设定这个参数可能会导致模型学习不足. 如果希望通过降维的方式防止过拟合, 建议使用PCA, ICA或者特征选择模块中的降维算法.
- 使用 GridSearchCV 网格搜索对决策树进行调参并返回最佳参数:
tree_params = {'max_depth': range(8, 11)}
locally_best_tree = GridSearchCV(DecisionTreeClassifier(random_state=17),
tree_params, cv=5)
locally_best_tree.fit(X_train, y_train)
print("Best params:", locally_best_tree.best_params_)
print("Best cross validaton score", locally_best_tree.best_score_)
- 使用上面找到的最佳参数,再次测试:
tuned_tree = DecisionTreeClassifier(max_depth=9, random_state=17)
tuned_tree.fit(X_train, y_train)
tuned_tree_predictions = tuned_tree.predict(X_test)
accuracy_score(y_test, tuned_tree_predictions)
建立随机森林分类模型
- 建立随机森林分类模型并预测:
rf = RandomForestClassifier(n_estimators=100, random_state=17)
rf.fit(X_train, y_train)
forest_predictions = rf.predict(X_test)
accuracy_score(y_test,forest_predictions)
遇到的问题及解决的方法
-
问题:对于决策树算法的内核不够了解,并且对于决策树中能够使用的各种参数也不了解。
-
解决方案:通过网络自学并且总结知识点。我了解到决策树是一种自上而下,对样本数据进行树形分类的过程,由节点和有向边组成。节点分为内部节点和叶节点,每个内部节点表示一个特征或属性,叶节点表示类别,边代表划分的条件。从顶部节点开始,所有样本聚在一起,经过根节点的划分,样本被分到不同的子节点中,再根据子节点的特征进一步划分,直至所有样本都被归到某个类别。构建决策树就是一个递归的选择内部节点,计算划分条件的边,最后到达叶子节点的过程。并且对sklearn库中的决策树中的模型进行了一定的了解,并在本次试验中多次改变参数值完成了本次试验。
五、附源程序
import warnings
import pydotplus
from io import StringIO
from IPython.display import SVG
from sklearn.metrics import accuracy_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn import preprocessing
from sklearn.model_selection import GridSearchCV, cross_val_score
import collections
from sklearn.preprocessing import LabelEncoder
import pandas as pd
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 8)
warnings.filterwarnings('ignore')
def create_df(dic, feature_list):
out = pd.DataFrame(dic)
out = pd.concat([out, pd.get_dummies(out[feature_list])], axis=1)
out.drop(feature_list, axis=1, inplace=True)
return out
def intersect_features(train, test):
common_feat = list(set(train.keys()) & set(test.keys()))
return train[common_feat], test[common_feat]
features = ['Looks', 'Alcoholic_beverage', 'Eloquence', 'Money_spent']
df_train = {}
df_train['Looks'] = ['handsome', 'handsome', 'handsome', 'repulsive', 'repulsive', 'repulsive', 'handsome']
df_train['Alcoholic_beverage'] = [ 'yes', 'yes', 'no', 'no', 'yes', 'yes', 'yes']
df_train['Eloquence'] = ['high', 'low', 'average', 'average', 'low', 'high', 'average']
df_train['Money_spent'] = ['lots', 'little', 'lots', 'little', 'lots', 'lots', 'lots']
df_train['Will_go'] = LabelEncoder().fit_transform(
['+', '-', '+', '-', '-', '+', '+'])
df_train = create_df(df_train, features)
df_train
df_test = {}
df_test['Looks'] = ['handsome', 'handsome', 'repulsive']
df_test['Alcoholic_beverage'] = ['no', 'yes', 'yes']
df_test['Eloquence'] = ['average', 'high', 'average']
df_test['Money_spent'] = ['lots', 'little', 'lots']
df_test = create_df(df_test, features)
df_test
y = df_train['Will_go']
df_train, df_test = intersect_features(train=df_train, test=df_test)
df_train
df_test
dt = DecisionTreeClassifier(criterion='entropy', random_state=17)
dt.fit(df_train, y)
tree_str = export_graphviz(
dt, feature_names=df_train.columns, out_file=None, filled=True)
graph = pydotplus.graph_from_dot_data(tree_str)
SVG(graph.create_svg())
balls = [1 for i in range(9)] + [0 for i in range(11)]
balls_left = [1 for i in range(8)] + [0 for i in range(5)]
balls_right = [1 for i in range(1)] + [0 for i in range(6)]
from math import log
def entropy(a_list):
lst = list(a_list)
size = len(lst) * 1.0
entropy = 0
set_elements = len(set(lst))
if set_elements in [0, 1]:
return 0
for i in set(lst):
occ = lst.count(i)
entropy -= occ/size * log(occ/size, 2)
return entropy
entropy(balls_left)
entropy([1, 2, 3, 4, 5, 6])
def information_gain(root, left, right):
''' root - 初始数据, left and right - 分组数据'''
return entropy(root) - 1.0 * len(left) / len(root) * entropy(left) \
- 1.0 * len(right) / len(root) * entropy(right)
information_gain(balls, balls_left, balls_right)
def best_feature_to_split(X, y):
'''信息增益用于特征分割'''
out = []
for i in X.columns:
out.append(information_gain(y, y[X[i] == 0], y[X[i] == 1]))
return out
def btree(X, y):
clf = best_feature_to_split(X, y)
param = clf.index(max(clf))
ly = y[X.iloc[:, param] == 0]
ry = y[X.iloc[:, param] == 1]
print('Column_' + str(param) + ' N/Y?')
print('Entropy: ', entropy(ly), entropy(ry))
print('N count:', ly.count(), '/', 'Y count:', ry.count())
if entropy(ly) != 0:
left = X[X.iloc[:, param] == 0]
btree(left, ly)
if entropy(ry) != 0:
right = X[X.iloc[:, param] == 1]
btree(right, ry)
best_feature_to_split(df_train, y)
btree(df_train, y)
### 构建 Adult 数据集决策树
data_train = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult_train.csv', sep=';')
data_train.tail()
data_test = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult_test.csv', sep=';')
data_test.tail()
# 移除测试集中的错误数据
data_test = data_test[(data_test['Target'] == ' >50K.')
| (data_test['Target'] == ' <=50K.')]
# 将目标编码为 0 和 1
data_train.loc[data_train['Target'] == ' <=50K', 'Target'] = 0
data_train.loc[data_train['Target'] == ' >50K', 'Target'] = 1
data_test.loc[data_test['Target'] == ' <=50K.', 'Target'] = 0
data_test.loc[data_test['Target'] == ' >50K.', 'Target'] = 1
data_test.describe(include='all').T
data_train['Target'].value_counts()
fig = plt.figure(figsize=(25, 15))
cols = 5
rows = np.ceil(float(data_train.shape[1]) / cols)
for i, column in enumerate(data_train.columns):
ax = fig.add_subplot(rows, cols, i + 1)
ax.set_title(column)
if data_train.dtypes[column] == np.object:
data_train[column].value_counts().plot(kind="bar", axes=ax)
else:
data_train[column].hist(axes=ax)
plt.xticks(rotation="vertical")
plt.subplots_adjust(hspace=0.7, wspace=0.2)
data_train.dtypes
data_test.dtypes
data_test['Age'] = data_test['Age'].astype(int)
data_test['fnlwgt'] = data_test['fnlwgt'].astype(int)
data_test['Education_Num'] = data_test['Education_Num'].astype(int)
data_test['Capital_Gain'] = data_test['Capital_Gain'].astype(int)
data_test['Capital_Loss'] = data_test['Capital_Loss'].astype(int)
data_test['Hours_per_week'] = data_test['Hours_per_week'].astype(int)
categorical_columns = [c for c in data_train.columns
if data_train[c].dtype.name == 'object']
numerical_columns = [c for c in data_train.columns
if data_train[c].dtype.name != 'object']
print('categorical_columns:', categorical_columns)
print('numerical_columns:', numerical_columns)
for c in categorical_columns:
data_train[c].fillna(data_train[c].mode(), inplace=True)
data_test[c].fillna(data_train[c].mode(), inplace=True)
for c in numerical_columns:
data_train[c].fillna(data_train[c].median(), inplace=True)
data_test[c].fillna(data_train[c].median(), inplace=True)
data_train = pd.concat([data_train[numerical_columns],
pd.get_dummies(data_train[categorical_columns])], axis=1)
data_test = pd.concat([data_test[numerical_columns],
pd.get_dummies(data_test[categorical_columns])], axis=1)
set(data_train.columns) - set(data_test.columns)
data_train.shape, data_test.shape
data_test['Country_ Holand-Netherlands'] = 0
set(data_train.columns) - set(data_test.columns)
data_train.head(2)
data_test.head(2)
X_train = data_train.drop(['Target'], axis=1)
y_train = data_train['Target']
X_test = data_test.drop(['Target'], axis=1)
y_test = data_test['Target']
tree = DecisionTreeClassifier(max_depth=3, random_state=17)
tree.fit(X_train, y_train)
tree_predictions = tree.predict(X_test)
accuracy_score(y_test, tree_predictions)
tree_params = {'max_depth': range(8, 11)}
locally_best_tree = GridSearchCV(DecisionTreeClassifier(random_state=17),
tree_params, cv=5)
locally_best_tree.fit(X_train, y_train)
print("Best params:", locally_best_tree.best_params_)
print("Best cross validaton score", locally_best_tree.best_score_)
tuned_tree = DecisionTreeClassifier(max_depth=9, random_state=17)
tuned_tree.fit(X_train, y_train)
tuned_tree_predictions = tuned_tree.predict(X_test)
accuracy_score(y_test, tuned_tree_predictions)
rf = RandomForestClassifier(n_estimators=100, random_state=17)
rf.fit(X_train, y_train)
forest_predictions = rf.predict(X_test)
accuracy_score(y_test,forest_predictions)