决策树算法

Cart 分类树

采用 基 尼 系 数 基尼系数 的指标选择最佳划分特征及决策值

基尼系数

对一个数据集 S (X,y),假如有K个类别,任意一个样本 x i x_i xi属于第k类的概率 p k p_k pk,则数据集S的基尼指数表示为
G i n i ( S ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(S) = \sum_{k=1}^K p_k(1-p_k)=1-\sum_{k=1}^Kp_k^2 Gini(S)=k=1Kpk(1pk)=1k=1Kpk2

使用 F F F特征的 f f f决策值,二分数据集S,得到 S 1 S_1 S1, S 2 S_2 S2,则划分后的基尼指数:
G i n i ( S , F f ) = ∣ S 1 ∣ ∣ S ∣ ∗ G i n i ( S 1 ) + ∣ S 2 ∣ ∣ S ∣ ∗ G i n i ( S 2 ) Gini(S,F_f) = \frac {|S_1|} {|S|}*Gini(S_1)+\frac {|S_2|} {|S|}*Gini(S_2) Gini(SFf)=SS1Gini(S1)+SS2Gini(S2)

其中:
∣ S 1 ∣ |S1| S1 ∣ S 2 ∣ |S2| S2为划分的左右子集样本数

Cart分类树的算法过程

传入一个数据集S,指定数据集划分最小样本数min_samples_split,基尼指数缩减阈值min_impurity_decrease

  1. 若S中样本数小于min_samples_split,则建立叶子节点,类别为最多的那一类,算法结束

  2. 若S中的样本数大于等于min_samples_split,计算S的基尼指数 G i n i o l d Gini_{old} Giniold,遍历所有的特征(遍历每个特征的决策值)进行二分数据集S,计算划分后的基尼指数 G i n i n e w Gini_{new} Gininew ,选择基尼指数减少最多的划分特征及其决策值。

  3. 若使用当前最优的特征及决策值划分后, G i n i o l d − G i n i n e w < m i n _ i m p u r i t y _ d e c r e a s e Gini_{old}-Gini_{new}<min\_impurity\_decrease GinioldGininew<min_impurity_decrease,则对数据集S建立叶节点,类别为当前最多的那一类,算法结束;
    否则,使用当前最优特征及决策值,二分数据集S,得到左右子集 S 1 , S 2 S_1,S_2 S1,S2

  4. 递归的解决左右子集

sklearn中的API

#决策树分类
from sklearn.tree import DecisionTreeClassifier
#随机森林分类
from sklearn.ensemble import RandomForestClassifier

#正向激励分类
from sklearn.ensemble import AdaBoostClassifier
#梯度提升
from sklearn.ensemble import GradientBoostingClassifier

Cart 回归树

使用 方 差 ( 均 方 误 差 m s e ) 方差(均方误差mse) mse 指标选择最佳划分特征及决策值

方差指标

对于一个数据集 S ( X , y ) S(X,y) S(X,y),样本数为m,其标记均值
m e a n = ∑ i m y i m mean =\frac {\sum_i^my_i}{m} mean=mimyi
σ 2 = ∑ i m ( y i − m e a n ) 2 m \sigma^2 = \frac {\sum_i^m(y_i-mean)^2}{m} σ2=mim(yimean)2

回归问题中,叶子节点的预测值即为该节点所有样本的标记值的平均值,方差也即均方误差

Cart回归树算法的过程

传入一个数据集S,此时max_depth = 0

  1. 计算数据集S 的标记 方 差 方差 ,若 σ 2 = 0 \sigma^2 = 0 σ2=0,则算法结束,建立叶子节点,预测值取所有样本标记的均值

  2. 若数据集S 标记 σ 2 > 0 \sigma^2 \gt 0 σ2>0,,遍历所有的特征(遍历每个特征的决策值)进行二分数据集S(left ≤ \le / right > \gt >),计算划分后的子集S1的标记 σ 1 2 \sigma_1^2 σ12、子集S2的标记若 σ 2 2 \sigma_2^2 σ22 ,选择使 σ 1 2 + σ 2 2 最 小 \sigma_1^2+\sigma_2^2 最小 σ12+σ22的特征及其决策值,优先划分数据集

  3. 使用当前最优的特征及决策值划分后max_depth+1,若子集中有 σ 2 = 0 \sigma^2 = 0 σ2=0,则对该子集建立叶节点,预测值为该节点所有样本标记的平均值,当然也可以指定方差阈值, σ 2 \sigma^2 σ2小于这个阈值时,可以认为子集已经纯净,建立叶子节点

  4. 递归的划分左右子集

算法终止条件

  1. 特征使用完
  2. 子集样本数为1,无法继续划分
  3. 指定max_depth,预剪枝,防止过拟合
  4. 指定min_samples_split ,预剪枝

sklearn中的回归树

from sklearn.tree import DecisionTreeRegressor
rg = DecisionTreeRegressor(max_depth=3,min_samples_split=2)
rg.fit(X_train,y_train)
y_pred = rg.predict(X_test)

使用回归树预测波士顿房价


from sklearn.datasets import load_boston
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error

boston = load_boston()

X,y = boston.data,boston.target

print(X,y)

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=3)
"""stratify=y 只用于分类"""

rg = DecisionTreeRegressor(max_depth=3)
rg.fit(X_train,y_train)

y_pred = rg.predict(X_test)
score = r2_score(y_test,y_pred)
print("模型评分:",score)

ID3算法

使用 信 息 增 益 信息增益 作为指标,选择最佳的划分特征及决策值

信 息 量 信息量 ,单个事件的不确定性
I ( x ) = − l o g ( p ) I(x) = -log(p) I(x)=log(p)
熵 熵 ,所有事件的平均不确定性,即期望
H ( x ) = − ∑ i k p i ∗ l o g ( p i ) H(x) =-\sum_i^kp_i*log(p_i) H(x)=ikpilog(pi)

有如下数据:计算数据集S的熵
在这里插入图片描述
任意取一个样本,‘否’类的概率 p ( 否 ) = 2 5 p(否) = \frac{2}{5} p()=52,‘是’类的概率 p ( 是 ) = 3 5 p(是) = \frac{3}{5} p()=53

则熵 H ( S ) = − [ 2 5 ∗ l o g ( 2 5 ) + 3 5 ∗ l o g ( 3 5 ) ] H(S) = -[\frac{2}{5}*log(\frac{2}{5})+\frac{3}{5}*log(\frac{3}{5})] H(S)=[52log(52)+53log(53)]

信息增益

数据集S的熵:
H ( S ) = − ∑ i k p i ∗ l o g ( p i ) H(S) =-\sum_i^kp_i*log(p_i) H(S)=ikpilog(pi)

数据集S经过最佳特征F及决策值f,划分后的熵
H ( S , F f ) = ∣ S 1 ∣ ∣ S ∣ ∗ H ( S 1 ) + ∣ S 2 ∣ ∣ S ∣ ∗ H ( S 2 ) H(S,F_f) = \frac {|S_1|}{|S|} *H(S_1)+\frac {|S_2|}{|S|} *H(S_2) H(SFf)=SS1H(S1)+SS2H(S2)

信 息 增 益 G a i n ( S , F f ) = H ( S ) − H ( S , F f ) 信息增益Gain(S,F_f) = H(S) - H(S,F_f) Gain(S,Ff)=H(S)H(S,Ff)

选择信息增益最大的特征及其决策值,优先划分数据集

缺点:偏向于取值多的特征
解决:采用信息增益比

C4.5算法

采用 信 息 增 益 比 信息增益比 作为指标,选择最佳划分特征及决策值

G a i n r a t i o = G a i n ( S , F f ) s p l i t I n f o Gain_{ratio} = \frac{Gain(S,F_f)}{splitInfo} Gainratio=splitInfoGain(S,Ff)
s p l i t I n f o = − ∑ i k ∣ S i ∣ ∣ S ∣ ∗ l o g ( ∣ S i ∣ ∣ S ∣ ) splitInfo = -\sum_i^k\frac{|S_i|}{|S|}*log(\frac{|S_i|}{|S|}) splitInfo=ikSSilog(SSi)

策略:先选择信息增益高于平均水平的特征,再从中选择信息增益比 最大的特征,优先划分数据集

项目案例

小汽车评级分类
部分数据及特征:

汽车价格,维修费用,车门数,载客数,后备箱大小,安全性,规格
vhigh,vhigh,2,2,small,low,unacc
vhigh,vhigh,2,2,small,med,unacc
vhigh,vhigh,2,2,small,high,unacc
vhigh,vhigh,2,2,med,low,unacc

  1. 加载数据
import numpy as np
import pandas as pd
df = pd.read_csv("car.txt",header=None,dtype="object")

  1. 简单数据分析
df.head()
df[0].value_counts()
df[1].value_counts()
...
df[6].value_counts()

#是否有缺失值
df.info()
df.isnull().sum()
  1. 对字符串的数据编码
from sklearn.preprocessing import LabelEncoder
temp_df = pd.DataFrame()
encoders = {}
for k,v in df.items():
	encoder = LabelEncoder()
	temp_df[k] = encoder.fit_transform(v)
	encoders[k] = encoder

#获取数据集
X,y = temp_df.iloc[:,:-1],temp_df[6]

  1. 交叉验证模型
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=200,max_depth=7,random_state=7)

cv_scores = cross_val_score(rf,X,y,cv=5,scoring="f1_weighted")
print("平均准确率:",cv_scores.mean())
  1. 实际的训练
	rf.fit(X,y)
	#加载测试数据
	rf.fit(X,y)
    test_df = pd.read_csv("test_car.txt",header=None,dtype="object")
    temp_df = pd.DataFrame()
    print("测试数据:\n",test_df)
    #对测试数据编码
    for k,v in test_df.items():
        
        #使用存储的编码器
        try:
            temp_df[k] = encoders[k].transform(v)
            
        except ValueError:
            print("\n")
            print(k,"\n",v)
        
    print("编码后的测试数据:\n",temp_df)
    
    
    #预测类别
    X = temp_df.iloc[:,:-1]
    y_pred = rf.predict(X)
    
    print("预测标签:\n",y_pred)
    print("等级:\n",encoders[6].inverse_transform(y_pred))
    
    print("不正确就调参")

预测结果:
[‘unacc’ ‘acc’ ‘good’ ‘vgood’]
全部正确

链接:项目整体代码
提取码:jqwu

基于树模型的集合模型

集合模型

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

laufing

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

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

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

打赏作者

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

抵扣说明:

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

余额充值