【Python机器学习】实验08 决策树

文章目录

  • 决策树
      • 1 创建数据
      • 2 定义香农信息熵
      • 3 条件熵
      • 4 信息增益
      • 5 计算所有特征的信息增益,选择最优最大信息增益的特征返回
      • 6 利用ID3算法生成决策树
      • 7 利用数据构造一颗决策树
      • Scikit-learn实例
      • 决策树分类
      • 决策树回归
      • Scikit-learn 的决策树参数
      • 决策树调参
      • 实验1 通过sklearn来做breast_cancer数据集的决策树分类器训练
      • 准备数据
      • 训练模型
      • 测试模型
      • 实验2 构造下面的数据,并调用前面手写代码实现决策树分类器
      • 采用下面的样本进行测试

决策树

1.分类决策树模型是表示基于特征对实例进行分类的树形结构。决策树可以转换成一个if-then规则的集合,也可以看作是定义在特征空间划分上的类的条件概率分布。

2.决策树学习旨在构建一个与训练数据拟合很好,并且复杂度小的决策树。因为从可能的决策树中直接选取最优决策树是NP完全问题。现实中采用启发式方法学习次优的决策树。

决策树学习算法包括3部分:特征选择、树的生成和树的剪枝。常用的算法有ID3、C4.5和CART。

3.特征选择的目的在于选取对训练数据能够分类的特征。特征选择的关键是其准则。常用的准则如下:

(1)样本集合 D D D对特征 A A A的信息增益(ID3)

g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D, A)=H(D)-H(D|A) g(D,A)=H(D)H(DA)

H ( D ) = − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ log ⁡ 2 ∣ C k ∣ ∣ D ∣ H(D)=-\sum_{k=1}^{K} \frac{\left|C_{k}\right|}{|D|} \log _{2} \frac{\left|C_{k}\right|}{|D|} H(D)=k=1KDCklog2DCk

H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) H(D | A)=\sum_{i=1}^{n} \frac{\left|D_{i}\right|}{|D|} H\left(D_{i}\right) H(DA)=i=1nDDiH(Di)

其中, H ( D ) H(D) H(D)是数据集 D D D的熵, H ( D i ) H(D_i) H(Di)是数据集 D i D_i Di的熵, H ( D ∣ A ) H(D|A) H(DA)是数据集 D D D对特征 A A A的条件熵。 D i D_i Di D D D中特征 A A A取第 i i i个值的样本子集, C k C_k Ck D D D中属于第 k k k类的样本子集。 n n n是特征 A A A取 值的个数, K K K是类的个数。

(2)样本集合 D D D对特征 A A A的信息增益比(C4.5)

g R ( D , A ) = g ( D , A ) H ( D ) g_{R}(D, A)=\frac{g(D, A)}{H(D)} gR(D,A)=H(D)g(D,A)

其中, g ( D , A ) g(D,A) g(D,A)是信息增益, H ( D ) H(D) H(D)是数据集 D D D的熵。

(3)样本集合 D D D的基尼指数(CART)

Gini ⁡ ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 \operatorname{Gini}(D)=1-\sum_{k=1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2} Gini(D)=1k=1K(DCk)2

特征 A A A条件下集合 D D D的基尼指数:

Gini ⁡ ( D , A ) = ∣ D 1 ∣ ∣ D ∣ Gini ⁡ ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ Gini ⁡ ( D 2 ) \operatorname{Gini}(D, A)=\frac{\left|D_{1}\right|}{|D|} \operatorname{Gini}\left(D_{1}\right)+\frac{\left|D_{2}\right|}{|D|} \operatorname{Gini}\left(D_{2}\right) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)

4.决策树的生成。通常使用信息增益最大、信息增益比最大或基尼指数最小作为特征选择的准则。决策树的生成往往通过计算信息增益或其他指标,从根结点开始,递归地产生决策树。这相当于用信息增益或其他准则不断地选取局部最优的特征,或将训练集分割为能够基本正确分类的子集。

5.决策树的剪枝。由于生成的决策树存在过拟合问题,需要对它进行剪枝,以简化学到的决策树。决策树的剪枝,往往从已生成的树上剪掉一些叶结点或叶结点以上的子树,并将其父结点或根结点作为新的叶结点,从而简化生成的决策树。

import numpy as np
import pandas as pd
import math
from math import log

1 创建数据

def create_data():datasets = [['青年', '否', '否', '一般', '否'],['青年', '否', '否', '好', '否'],['青年', '是', '否', '好', '是'],['青年', '是', '是', '一般', '是'],['青年', '否', '否', '一般', '否'],['中年', '否', '否', '一般', '否'],['中年', '否', '否', '好', '否'],['中年', '是', '是', '好', '是'],['中年', '否', '是', '非常好', '是'],['中年', '否', '是', '非常好', '是'],['老年', '否', '是', '非常好', '是'],['老年', '否', '是', '好', '是'],['老年', '是', '否', '好', '是'],['老年', '是', '否', '非常好', '是'],['老年', '否', '否', '一般', '否'],]labels = [u'年龄', u'有工作', u'有自己的房子', u'信贷情况', u'类别']# 返回数据集和每个维度的名称return datasets, labels
datasets, labels = create_data()
train_data = pd.DataFrame(datasets, columns=labels)
train_data
年龄有工作有自己的房子信贷情况类别
0青年一般
1青年
2青年
3青年一般
4青年一般
5中年一般
6中年
7中年
8中年非常好
9中年非常好
10老年非常好
11老年
12老年
13老年非常好
14老年一般

2 定义香农信息熵

def calc_ent(datasets):data_length = len(datasets)label_count = {}for i in range(data_length):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1ent = -sum([(p / data_length) * log(p / data_length, 2)for p in label_count.values()])return ent

3 条件熵

def cond_ent(datasets, axis=0):data_length = len(datasets)feature_sets = {}for i in range(data_length):feature = datasets[i][axis]if feature not in feature_sets:feature_sets[feature] = []feature_sets[feature].append(datasets[i])cond_ent = sum([(len(p) / data_length) * calc_ent(p)for p in feature_sets.values()])return cond_ent
calc_ent(datasets)
0.9709505944546686

4 信息增益

def info_gain(ent, cond_ent):return ent - cond_ent

5 计算所有特征的信息增益,选择最优最大信息增益的特征返回

def info_gain_train(datasets):count = len(datasets[0]) - 1ent = calc_ent(datasets)best_feature = []for c in range(count):c_info_gain = info_gain(ent, cond_ent(datasets, axis=c))best_feature.append((c, c_info_gain))print('特征({}) 的信息增益为: {:.3f}'.format(labels[c], c_info_gain))# 比较大小best_ = max(best_feature, key=lambda x: x[-1])return '特征({})的信息增益最大,选择为根节点特征'.format(labels[best_[0]])
info_gain_train(np.array(datasets))
特征(年龄) 的信息增益为: 0.083
特征(有工作) 的信息增益为: 0.324
特征(有自己的房子) 的信息增益为: 0.420
特征(信贷情况) 的信息增益为: 0.363'特征(有自己的房子)的信息增益最大,选择为根节点特征'

6 利用ID3算法生成决策树

# 定义节点类 二叉树
class Node:def __init__(self, root=True, label=None, feature_name=None, feature=None):self.root = rootself.label = labelself.feature_name = feature_nameself.feature = featureself.tree = {}self.result = {'label:': self.label,'feature': self.feature,'tree': self.tree}def __repr__(self):return '{}'.format(self.result)def add_node(self, val, node):self.tree[val] = nodedef predict(self, features):if self.root is True:return self.labelcurrent_tree=self.tree[features[self.feature]]features.pop(self.feature)return current_tree.predict(features)class DTree:def __init__(self, epsilon=0.1):self.epsilon = epsilonself._tree = {}# 熵@staticmethoddef calc_ent(datasets):data_length = len(datasets)label_count = {}for i in range(data_length):label = datasets[i][-1]if label not in label_count:label_count[label] = 0label_count[label] += 1ent = -sum([(p / data_length) * log(p / data_length, 2) for p in label_count.values()])return ent# 经验条件熵def cond_ent(self, datasets, axis=0):data_length = len(datasets)feature_sets = {}for i in range(data_length):feature = datasets[i][axis]if feature not in feature_sets:feature_sets[feature] = []feature_sets[feature].append(datasets[i])cond_ent = sum([(len(p) / data_length) * self.calc_ent(p) for p in feature_sets.values()])return cond_ent# 信息增益@staticmethoddef info_gain(ent, cond_ent):return ent - cond_entdef info_gain_train(self, datasets):count = len(datasets[0]) - 1ent = self.calc_ent(datasets)best_feature = []for c in range(count):c_info_gain = self.info_gain(ent, self.cond_ent(datasets, axis=c))best_feature.append((c, c_info_gain))# 比较大小best_ = max(best_feature, key=lambda x: x[-1])return best_def train(self, train_data):"""input:数据集D(DataFrame格式),特征集A,阈值etaoutput:决策树T"""_, y_train, features = train_data.iloc[:,:-1], train_data.iloc[:,-1], train_data.columns[:-1]# 1,若D中实例属于同一类Ck,则T为单节点树,并将类Ck作为结点的类标记,返回Tif len(y_train.value_counts()) == 1:return Node(root=True, label=y_train.iloc[0])# 2, 若A为空,则T为单节点树,将D中实例树最大的类Ck作为该节点的类标记,返回Tif len(features) == 0:return Node(root=True,label=y_train.value_counts().sort_values(ascending=False).index[0])# 3,计算最大信息增益 同5.1,Ag为信息增益最大的特征max_feature, max_info_gain = self.info_gain_train(np.array(train_data))max_feature_name = features[max_feature]# 4,Ag的信息增益小于阈值eta,则置T为单节点树,并将D中是实例数最大的类Ck作为该节点的类标记,返回Tif max_info_gain < self.epsilon:return Node(root=True,label=y_train.value_counts().sort_values(ascending=False).index[0])# 5,构建Ag子集node_tree = Node(root=False, feature_name=max_feature_name, feature=max_feature)feature_list = train_data[max_feature_name].value_counts().indexfor f in feature_list:sub_train_df = train_data.loc[train_data[max_feature_name] == f].drop([max_feature_name], axis=1)# 6, 递归生成树sub_tree = self.train(sub_train_df)node_tree.add_node(f, sub_tree)return node_treedef fit(self, train_data):self._tree = self.train(train_data)return self._treedef predict(self, X_test):return self._tree.predict(X_test)

7 利用数据构造一颗决策树

datasets, labels = create_data()
data_df = pd.DataFrame(datasets, columns=labels)
dt = DTree()
tree = dt.fit(data_df)
data_df
年龄有工作有自己的房子信贷情况类别
0青年一般
1青年
2青年
3青年一般
4青年一般
5中年一般
6中年
7中年
8中年非常好
9中年非常好
10老年非常好
11老年
12老年
13老年非常好
14老年一般
tree
{'label:': None, 'feature': 2, 'tree': {'否': {'label:': None, 'feature': 1, 'tree': {'否': {'label:': '否', 'feature': None, 'tree': {}}, '是': {'label:': '是', 'feature': None, 'tree': {}}}}, '是': {'label:': '是', 'feature': None, 'tree': {}}}}有无房子否            是 ↓             ↓有无工作         是否      是↓      ↓否      是
tree.predict(['老年', '否', '否', '一般'])
'否'
datasets
[['青年', '否', '否', '一般', '否'],['青年', '否', '否', '好', '否'],['青年', '是', '否', '好', '是'],['青年', '是', '是', '一般', '是'],['青年', '否', '否', '一般', '否'],['中年', '否', '否', '一般', '否'],['中年', '否', '否', '好', '否'],['中年', '是', '是', '好', '是'],['中年', '否', '是', '非常好', '是'],['中年', '否', '是', '非常好', '是'],['老年', '否', '是', '非常好', '是'],['老年', '否', '是', '好', '是'],['老年', '是', '否', '好', '是'],['老年', '是', '否', '非常好', '是'],['老年', '否', '否', '一般', '否']]
labels
['年龄', '有工作', '有自己的房子', '信贷情况', '类别']
dt.predict(['老年', '否', '否', '一般'])
'否'

Scikit-learn实例

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from collections import Counter

使用Iris数据集,我们可以构建如下树:

# data
def create_data():iris = load_iris()df = pd.DataFrame(iris.data, columns=iris.feature_names)df['label'] = iris.targetdf.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']data = np.array(df.iloc[:100, [0, 1, -1]])# print(data)return data[:, :2], data[:, -1],iris.feature_names[0:2]X, y,feature_name= create_data()
X, y,feature_name
(array([[5.1, 3.5],[4.9, 3. ],[4.7, 3.2],[4.6, 3.1],[5. , 3.6],[5.4, 3.9],[4.6, 3.4],[5. , 3.4],[4.4, 2.9],[4.9, 3.1],[5.4, 3.7],[4.8, 3.4],[4.8, 3. ],[4.3, 3. ],[5.8, 4. ],[5.7, 4.4],[5.4, 3.9],[5.1, 3.5],[5.7, 3.8],[5.1, 3.8],[5.4, 3.4],[5.1, 3.7],[4.6, 3.6],[5.1, 3.3],[4.8, 3.4],[5. , 3. ],[5. , 3.4],[5.2, 3.5],[5.2, 3.4],[4.7, 3.2],[4.8, 3.1],[5.4, 3.4],[5.2, 4.1],[5.5, 4.2],[4.9, 3.1],[5. , 3.2],[5.5, 3.5],[4.9, 3.6],[4.4, 3. ],[5.1, 3.4],[5. , 3.5],[4.5, 2.3],[4.4, 3.2],[5. , 3.5],[5.1, 3.8],[4.8, 3. ],[5.1, 3.8],[4.6, 3.2],[5.3, 3.7],[5. , 3.3],[7. , 3.2],[6.4, 3.2],[6.9, 3.1],[5.5, 2.3],[6.5, 2.8],[5.7, 2.8],[6.3, 3.3],[4.9, 2.4],[6.6, 2.9],[5.2, 2.7],[5. , 2. ],[5.9, 3. ],[6. , 2.2],[6.1, 2.9],[5.6, 2.9],[6.7, 3.1],[5.6, 3. ],[5.8, 2.7],[6.2, 2.2],[5.6, 2.5],[5.9, 3.2],[6.1, 2.8],[6.3, 2.5],[6.1, 2.8],[6.4, 2.9],[6.6, 3. ],[6.8, 2.8],[6.7, 3. ],[6. , 2.9],[5.7, 2.6],[5.5, 2.4],[5.5, 2.4],[5.8, 2.7],[6. , 2.7],[5.4, 3. ],[6. , 3.4],[6.7, 3.1],[6.3, 2.3],[5.6, 3. ],[5.5, 2.5],[5.5, 2.6],[6.1, 3. ],[5.8, 2.6],[5. , 2.3],[5.6, 2.7],[5.7, 3. ],[5.7, 2.9],[6.2, 2.9],[5.1, 2.5],[5.7, 2.8]]),array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),['sepal length (cm)', 'sepal width (cm)'])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
((70, 2), (30, 2), (70,), (30,))

决策树分类

from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import graphviz
#1 导入相关包
from sklearn import tree
#2 构建一个决策树分类器模型
clf = DecisionTreeClassifier(criterion="entropy")
#3 采用数据来构建决策树
clf.fit(X_train, y_train)
#4 对决策树模型进行测试
clf.score(X_test, y_test)
0.9

一旦经过训练,就可以用 plot_tree函数绘制树:

tree.plot_tree(clf) 
[Text(0.6, 0.9, 'X[1] <= 3.15\nentropy = 0.998\nsamples = 70\nvalue = [37, 33]'),Text(0.4, 0.7, 'X[0] <= 4.95\nentropy = 0.639\nsamples = 37\nvalue = [6, 31]'),Text(0.3, 0.5, 'X[1] <= 2.7\nentropy = 0.592\nsamples = 7\nvalue = [6, 1]'),Text(0.2, 0.3, 'X[0] <= 4.7\nentropy = 1.0\nsamples = 2\nvalue = [1, 1]'),Text(0.1, 0.1, 'entropy = 0.0\nsamples = 1\nvalue = [1, 0]'),Text(0.3, 0.1, 'entropy = 0.0\nsamples = 1\nvalue = [0, 1]'),Text(0.4, 0.3, 'entropy = 0.0\nsamples = 5\nvalue = [5, 0]'),Text(0.5, 0.5, 'entropy = 0.0\nsamples = 30\nvalue = [0, 30]'),Text(0.8, 0.7, 'X[0] <= 6.05\nentropy = 0.33\nsamples = 33\nvalue = [31, 2]'),Text(0.7, 0.5, 'entropy = 0.0\nsamples = 31\nvalue = [31, 0]'),Text(0.9, 0.5, 'entropy = 0.0\nsamples = 2\nvalue = [0, 2]')]

1

也可以导出树

tree_pic = export_graphviz(clf, out_file="mytree.pdf")
with open('mytree.pdf') as f:dot_graph = f.read()

或者,还可以使用函数 export_text以文本格式导出树。此方法不需要安装外部库,而且更紧凑:

from sklearn.tree import export_text
r = export_text(clf)
print(r)
|--- feature_1 <= 3.15
|   |--- feature_0 <= 4.95
|   |   |--- feature_1 <= 2.70
|   |   |   |--- feature_0 <= 4.70
|   |   |   |   |--- class: 0.0
|   |   |   |--- feature_0 >  4.70
|   |   |   |   |--- class: 1.0
|   |   |--- feature_1 >  2.70
|   |   |   |--- class: 0.0
|   |--- feature_0 >  4.95
|   |   |--- class: 1.0
|--- feature_1 >  3.15
|   |--- feature_0 <= 6.05
|   |   |--- class: 0.0
|   |--- feature_0 >  6.05
|   |   |--- class: 1.0

决策树回归

import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
rng = np.random.RandomState(1)
rng
RandomState(MT19937) at 0x1AD2E576840
X = np.sort(5 * rng.rand(80, 1), axis=0)
# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))
X.shape,y.shape
((80, 1), (80,))
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
X_test.shape
(500, 1)
# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)# Predict
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)# Plot the results
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

2

Scikit-learn 的决策树参数

DecisionTreeClassifier(criterion=“gini”,
splitter=“best”,
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features=None,
random_state=None,
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
class_weight=None,
presort=False)

参数含义:

  1. criterion:string, optional (default=“gini”)
    (1).criterion=‘gini’,分裂节点时评价准则是Gini指数。
    (2).criterion=‘entropy’,分裂节点时的评价指标是信息增益。
  2. max_depth:int or None, optional (default=None)。指定树的最大深度。
    如果为None,表示树的深度不限。直到所有的叶子节点都是纯净的,即叶子节点
    中所有的样本点都属于同一个类别。或者每个叶子节点包含的样本数小于min_samples_split。
  3. splitter:string, optional (default=“best”)。指定分裂节点时的策略。
    (1).splitter=‘best’,表示选择最优的分裂策略。
    (2).splitter=‘random’,表示选择最好的随机切分策略。
  4. min_samples_split:int, float, optional (default=2)。表示分裂一个内部节点需要的做少样本数。
    (1).如果为整数,则min_samples_split就是最少样本数。
    (2).如果为浮点数(0到1之间),则每次分裂最少样本数为ceil(min_samples_split * n_samples)
  5. min_samples_leaf: int, float, optional (default=1)。指定每个叶子节点需要的最少样本数。
    (1).如果为整数,则min_samples_split就是最少样本数。
    (2).如果为浮点数(0到1之间),则每个叶子节点最少样本数为ceil(min_samples_leaf * n_samples)
  6. min_weight_fraction_leaf:float, optional (default=0.)
    指定叶子节点中样本的最小权重。
  7. max_features:int, float, string or None, optional (default=None).
    搜寻最佳划分的时候考虑的特征数量。
    (1).如果为整数,每次分裂只考虑max_features个特征。
    (2).如果为浮点数(0到1之间),每次切分只考虑int(max_features * n_features)个特征。
    (3).如果为’auto’或者’sqrt’,则每次切分只考虑sqrt(n_features)个特征
    (4).如果为’log2’,则每次切分只考虑log2(n_features)个特征。
    (5).如果为None,则每次切分考虑n_features个特征。
    (6).如果已经考虑了max_features个特征,但还是没有找到一个有效的切分,那么还会继续寻找
    下一个特征,直到找到一个有效的切分为止。
  8. random_state:int, RandomState instance or None, optional (default=None)
    (1).如果为整数,则它指定了随机数生成器的种子。
    (2).如果为RandomState实例,则指定了随机数生成器。
    (3).如果为None,则使用默认的随机数生成器。
  9. max_leaf_nodes: int or None, optional (default=None)。指定了叶子节点的最大数量。
    (1).如果为None,叶子节点数量不限。
    (2).如果为整数,则max_depth被忽略。
  10. min_impurity_decrease:float, optional (default=0.)
    如果节点的分裂导致不纯度的减少(分裂后样本比分裂前更加纯净)大于或等于min_impurity_decrease,则分裂该节点。
    加权不纯度的减少量计算公式为:
    min_impurity_decrease=N_t / N * (impurity - N_t_R / N_t * right_impurity
    - N_t_L / N_t * left_impurity)
    其中N是样本的总数,N_t是当前节点的样本数,N_t_L是分裂后左子节点的样本数,
    N_t_R是分裂后右子节点的样本数。impurity指当前节点的基尼指数,right_impurity指
    分裂后右子节点的基尼指数。left_impurity指分裂后左子节点的基尼指数。
  11. min_impurity_split:float
    树生长过程中早停止的阈值。如果当前节点的不纯度高于阈值,节点将分裂,否则它是叶子节点。
    这个参数已经被弃用。用min_impurity_decrease代替了min_impurity_split。
  12. class_weight:dict, list of dicts, “balanced” or None, default=None
    类别权重的形式为{class_label: weight}
    (1).如果没有给出每个类别的权重,则每个类别的权重都为1。
    (2).如果class_weight=‘balanced’,则分类的权重与样本中每个类别出现的频率成反比。
    计算公式为:n_samples / (n_classes * np.bincount(y))
    (3).如果sample_weight提供了样本权重(由fit方法提供),则这些权重都会乘以sample_weight。
  13. presort:bool, optional (default=False)
    指定是否需要提前排序数据从而加速训练中寻找最优切分的过程。设置为True时,对于大数据集
    会减慢总体的训练过程;但是对于一个小数据集或者设定了最大深度的情况下,会加速训练过程。

决策树调参

# 导入库
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeRegressor
from sklearn import metrics
# 导入数据集
X = datasets.load_iris()  # 以全部字典形式返回,有data,target,target_names三个键
data = X.data
target = X.target
name = X.target_names
x, y = datasets.load_iris(return_X_y=True)  # 能一次性取前2个
print(x.shape, y.shape)
(150, 4) (150,)
# 数据分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.2,random_state=100)
# 用GridSearchCV寻找最优参数(字典)
param = {'criterion': ['gini'],'max_depth': [30, 50, 60, 100],'min_samples_leaf': [2, 3, 5, 10],'min_impurity_decrease': [0.1, 0.2, 0.5]
}
grid = GridSearchCV(DecisionTreeClassifier(), param_grid=param, cv=6)
grid.fit(x_train, y_train)
print('最优分类器:', grid.best_params_, '最优分数:', grid.best_score_)  # 得到最优的参数和分值
最优分类器: {'criterion': 'gini', 'max_depth': 50, 'min_impurity_decrease': 0.2, 'min_samples_leaf': 10} 最优分数: 0.9416666666666665
param = {'criterion': ['gini',"entropy"],'max_depth': [30, 50, 60, 100,80],'min_samples_leaf': [2, 3, 5, 10],'min_impurity_decrease': [0.1, 0.2, 0.5,0.8],"splitter":["random","best"]
}
grid=GridSearchCV(DecisionTreeClassifier(),param_grid=param,cv=5)
grid.fit(x_train,y_train)
print(grid.best_params_,grid.best_score_,grid.n_splits_)
{'criterion': 'entropy', 'max_depth': 50, 'min_impurity_decrease': 0.1, 'min_samples_leaf': 10, 'splitter': 'random'} 0.95 5

实验1 通过sklearn来做breast_cancer数据集的决策树分类器训练

准备数据

from sklearn.datasets import load_breast_cancer
bst = load_breast_cancer()
data=bst.data
bst.feature_names
array(['mean radius', 'mean texture', 'mean perimeter', 'mean area','mean smoothness', 'mean compactness', 'mean concavity','mean concave points', 'mean symmetry', 'mean fractal dimension','radius error', 'texture error', 'perimeter error', 'area error','smoothness error', 'compactness error', 'concavity error','concave points error', 'symmetry error','fractal dimension error', 'worst radius', 'worst texture','worst perimeter', 'worst area', 'worst smoothness','worst compactness', 'worst concavity', 'worst concave points','worst symmetry', 'worst fractal dimension'], dtype='<U23')
data.shape
(569, 30)
x=data[:,:2]
labels=bst.feature_names[:2]
labels 
array(['mean radius', 'mean texture'], dtype='<U23')
y=bst.target
datasets=np.insert(x,x.shape[1],y,axis=1)
datasets.shape
(569, 3)
data_df = pd.DataFrame(datasets,columns=['mean radius', 'mean texture',"结果"])
data_df
mean radiusmean texture结果
017.9910.380.0
120.5717.770.0
219.6921.250.0
311.4220.380.0
420.2914.340.0
............
56421.5622.390.0
56520.1328.250.0
56616.6028.080.0
56720.6029.330.0
5687.7624.541.0

569 rows × 3 columns

# 数据分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
X_train.shape,X_test.shape,y_train.shape,y_test.shape
((398, 2), (171, 2), (398,), (171,))

训练模型

from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import graphviz
clf = DecisionTreeClassifier(criterion="entropy")
clf.fit(X_train, y_train)
DecisionTreeClassifier(criterion='entropy')

测试模型

#4 对决策树模型进行测试
clf.score(X_test, y_test)
0.8713450292397661

实验2 构造下面的数据,并调用前面手写代码实现决策树分类器

3

def create_demo():datasets=[['sunny','hot','high','False','No'],['sunny','hot','high','True','No'],['overcast','hot','high','False','Yes'],['rain','mild','high','False','Yes'],['rain','cool','normal','False','Yes'],['rain','cool','normal','True','No'],['overcast','cool','normal','True','Yes'],['sunny','mild','high','False','No'],['sunny','cool','normal','False','Yes'],['rain','mild','normal','True','Yes'],['sunny','mild','normal','False','Yes'],['overcast','mild','high','True','Yes'],['overcast','hot','normal','False','Yes'],['rain','mild','high','True','No']]labels=['Outlook','Temperature','Humidity','Windy','Play']return datasets,labels
datasets,labels=create_demo()
data_df = pd.DataFrame(datasets,columns=labels)
data_df
OutlookTemperatureHumidityWindyPlay
0sunnyhothighFalseNo
1sunnyhothighTrueNo
2overcasthothighFalseYes
3rainmildhighFalseYes
4raincoolnormalFalseYes
5raincoolnormalTrueNo
6overcastcoolnormalTrueYes
7sunnymildhighFalseNo
8sunnycoolnormalFalseYes
9rainmildnormalTrueYes
10sunnymildnormalFalseYes
11overcastmildhighTrueYes
12overcasthotnormalFalseYes
13rainmildhighTrueNo
train_data=pd.DataFrame(datasets,columns=labels)
dt = DTree()
tree = dt.fit(data_df)
tree
{'label:': None, 'feature': 0, 'tree': {'sunny': {'label:': None, 'feature': 1, 'tree': {'high': {'label:': 'No', 'feature': None, 'tree': {}}, 'normal': {'label:': 'Yes', 'feature': None, 'tree': {}}}}, 'rain': {'label:': None, 'feature': 2, 'tree': {'True': {'label:': None, 'feature': 0, 'tree': {'mild': {'label:': None, 'feature': 0, 'tree': {'normal': {'label:': 'Yes', 'feature': None, 'tree': {}}, 'high': {'label:': 'No', 'feature': None, 'tree': {}}}}, 'cool': {'label:': 'No', 'feature': None, 'tree': {}}}}, 'False': {'label:': 'Yes', 'feature': None, 'tree': {}}}}, 'overcast': {'label:': 'Yes', 'feature': None, 'tree': {}}}}Outlooksunny            rain           overcast↓                 ↓               ↓Humidity          Windy            Yeshigh    normal    True       False↓        ↓         ↓          ↓No     Yes   Temperature	   Yesmild      cool↓        ↓Humidity     Nonormal  high  ↓       ↓Yes     No

采用下面的样本进行测试

test=["sunny","hot","normal","True"]
tree.predict(test)
'Yes'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/30712.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js2-js中的数据结构

1、什么是数据结构 数据结构是计算机存储、组织数据的方式。 数据结构意味着接口或封装&#xff0c;一个数据结构可被视为两个函数之间的接口&#xff0c;或者是由数据类型联合组成的存储内容的访问方法封装。 每天的编码中都会用到数据结构&#xff0c;其中数组是最简单的内存…

FFmpeg安装和使用

sudo apt install ffmpeg sudo apt-get install libavfilter-devcmakelist模板 CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(ffmpeg_demo)# 设置ffmpeg依赖库及头文件所在目录&#xff0c;并存进指定变量 set(ffmpeg_libs_DIR /usr/lib/x86_64-linux-gnu) …

【GO】 33.go-zero 示例

1. 获取go-zero库 go get -u github.com/zeromicro/go-zero 2. 安装goctl brew install goctlgoctl -v #goctl version 1.5.4 darwin/amd64 3. 创建.api文件&#xff0c; greet.api goctl api -o greet.api syntax "v1"info (title: // TODO: add titledesc: //…

如何使用appuploader制作apple证书​

转载&#xff1a;如何使用appuploader制作apple证书​ 如何使用appuploader制作apple证书​ 一.证书管理​ 点击首页的证书管理 二.新建证书​ 点击“添加”&#xff0c;新建一个证书文件 免费账号制作证书只有7天有效期&#xff0c;没有推送消息功能&#xff0c;推送证书…

UNet Model

论文地址 第一阶段 conv2d(33) first conv&#xff1a;5725721 → 57057064 second conv&#xff1a;57057064 → 56856864 代码 # first 33 convolutional layer self.first nn.Conv2d(in_channels, out_channels, kernel_size3, padding1) self.act1 nn.ReLU() # Seco…

浏览器无法连接网络问题

问题描述 电脑其他程序都能正常联网&#xff0c;但是所有的浏览器都无法联网&#xff0c;同时外部网站都能ping通 问题诊断 查看电脑Internet连接的问题报告显示&#xff1a;该设备或资源(Web 代理)未设置为接受端口"7890"上的连接。 解决方案 经过检查发现不是IP地址…

若依vue -【 100 ~ 更 】

100 主子表代码生成详解 1 新建数据库表结构&#xff08;主子表&#xff09; -- ---------------------------- -- 客户表 -- ---------------------------- drop table if exists sys_customer; create table sys_customer (customer_id bigint(20) not null…

浅谈AI浪潮下的视频大数据发展趋势与应用

视频大数据的发展趋势是多样化和个性化的。随着科技的不断进步&#xff0c;人们对于视频内容的需求也在不断变化。从传统的电视节目到现在的短视频、直播、VR等多种形式&#xff0c;视频内容已经不再是单一的娱乐方式&#xff0c;更是涉及到教育、医疗、商业等各个领域。 为了满…

crypto-js中AES的加解密封装

在项目中安装依赖&#xff1a; npm i crypto-js在使用的页面引入&#xff1a; import CryptoJS from crypto-jscrypto-js中AES的加解密简单的封装了一下&#xff1a; //加密const KEY 000102030405060708090a0b0c0d0e0f // 秘钥 这两个需要和后端统一const IV 8a8c8fd8fe3…

API HOOK技术在MFC程序破解过程中的应用

更新&#xff0c;修改了一下typora的上传脚本&#xff0c;把图片全部上传到看雪上了 本文已于2023-08-02首发于个人博客 图片加载不出来&#xff0c;放了一个PDF版本在附件里 文中有几张图片是动图&#xff0c;如果不会动&#xff0c;可以去我的个人博客看 最近破解了一个M…

你不知道的阴影

我们在开发的时候&#xff0c;使用box-shadow添加阴影是这样的&#xff1a; .img {width: 500px;height: 500px;display: block;box-shadow: 0 0 15px #333333;} 但是我们想给这个图片加阴影应该怎么加那&#xff08;让UI做&#xff0c;我真聪明&#xff01;&#xff09; &…

Kali Hyper-V安装正常启动后 黑屏 只能进命令模式

问题: Hyper-V安装虚拟机Kali系统一切安装正常, 没有出现错误. 安装成功后重启,只能进入命令模式,tt1-tt6,进不去GUI桌面. 尝试: 一代二代虚拟硬盘都试过,同样问题,只能开进后进入命令模式,在命令模式下一切运行正常, 也修复过系统 GNOM等的,不管用. 以下为国外论坛给的建议,尝…

Centos7单机部署ElasticSearch

Centos7单机部署ElasticSearch 引言 Elasticsearch是一种广泛使用的开源搜索引擎&#xff0c;专门为分布式环境设计&#xff0c;但也可以在单机上运行。它使存储、搜索和分析大量数据变得更加容易和高效。此教程将引导你通过在Centos7上单机部署Elasticsearch&#xff0c;涵盖…

flutter项目给安卓打正式包 和升级版本号

1.首先把flutter项目里的android目录整个拖进android studo里,运行一下看看是否能运行 2.Build->Generate Signed Bundle/APK… 点击APK->Next 如果没有key酒店及Create new…就生成新的key 点击Key store path:右边的图标选择保存路径 选择保存的路径,并且在Save…

webpack基础知识二:说说webpack的构建流程?

一、运行流程 webpack 的运行流程是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会广播事件&#xff0c;插件只需要监听它所关心的事件&#xff0c;就能加入到这条webpack机制中&#xff0c;去改变webpack的运作&#xff0c;使得整个系统扩展…

【Android NDK开发】Android Studio 编写 JNI (C++)代码无提示

随笔记 Android Studio在编写C代码时候&#xff0c;引入对应的头文件&#xff0c;Android Studio里却不提示对应的方法&#xff0c;需要在Studio中设置一下。 Mac中&#xff0c;选择 Android Studio > Preferences&#xff0c;选择Clangd >>Disable Clangd completio…

C++-排序

文章目录 常数操作时间复杂度空间复杂度O(N^2) O(1) 数据情况发生变化不影响流程 选择排序冒泡排序使用抑或运算提取出不为零的数最右边的1 1. 实现两个变量交换值2. 数组中一种数字出现奇数次,other是偶数次,找到那一种数字3. 数组中有两种数字出现奇数次,other是偶数次,找到那…

如何理解MySQL隔离性---3个记录隐藏字段、undo日志、Read View

目录 一、3个记录隐藏字段 二、undo 日志 三、read view 一、3个记录隐藏字段 本片文章是帮助理解上篇文章Mysql隔离性的辅助知识。 mysql在建表时&#xff0c;不仅仅创建了表的结构&#xff0c;还创建了3个隐藏字段。 DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修…

iOS开发-JsonModel的学习及使用

IOS JsonModel的学习及使用 当我们从服务端获取到json数据后的时候&#xff0c;我们需要在界面上展示或者保存起来&#xff0c;下面来看下直接通过NSDictionary取出数据的情况。 NSDictionary直接取出数据的诟病。 NSString *name [self.responseObj objectForKey:"nam…

巧用Maya轴心操作技巧,让工作事半功倍!

Maya 是一款专业的三维软件&#xff0c;可以用于创建规模宏大的世界、复杂的角色和炫酷的特效。Maya的用户遍布动画行业、影视特效、广告和片头、平面设计行业&#xff0c;用户数量十分庞大。本文分享了maya轴心操作的小技巧&#xff0c;让设计师工作事半功倍&#xff0c;一起来…