Cart 决策树算法

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,指定数据集划分最小样本数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 回归树

使用 方 差 方差 指标选择最佳划分特征及决策值

项目案例

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

汽车价格,维修费用,车门数,载客数,后备箱大小,安全性,规格
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

猜你喜欢

转载自blog.csdn.net/weixin_45228198/article/details/114359602
今日推荐