I 决策树定义(Decision Tree)
应用:可以解决多分类问题~
举一个栗子🌰,阔以直观感受一下什么是决策树
组成:根节点(x属性变量)、内部根节点(x属性变量)、叶子节点(y分类变量)
实质:一系列if-then规则组成
II 决策树算法
选择结点划分的常用方法:min(Entropy)
ID3(Quinlan, 1986)、C4.5、CART(Breiman, 1984)
说明:ID3算法基于信息增益划分节点,C4.5算法基于信息增益率划分节点,CART算法基于基尼系数来划分节点。
本文主要讲解C4.5算法
C4.5主要是在ID3的基础上改进,ID3选择(属性)树节点是选择信息增益值最大的属性作为节点。而C4.5引入了新概念“信息增益率” (information gain ratio) ,C4.5是选择信息增益率最大的属性作为树节点。
III 剪枝
剪枝的处理是解决决策树模型过拟合的主要手段,通过限制层数来防止过拟合的发生。
预剪枝:是指在决策树生成的过程中,对每个节点在划分前先进行估计
后剪枝:是指在决策树生成之后,在进行剪枝的处理
特征选择
标准:熵增益率
IV CART算法
注:sklearn这个包中DecisionTreeClassifier功能,只能依靠信息增益和基尼系数来分类(i.e. 分类时只有这两个可选参数),因此也就决定了利用这个package只能实现CART算法和ID3算法,而C4.5算法还是只有靠自己老实写。
import pandas as pd
import copy
import numpy as np
from WindPy import w
from datetime import *
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler
w.start()
## STEP1: 函数getAsharePanels(),获取A股历史面板数据
def getAsharePanels(stockcodes,start_date,end_date):
## 参数
stockcodes=['000001.SZ'] #测试所用的三只股票代码
start_date='20080101' #样本数据起始日期
end_date='20171231' #样本数据结束日期
append_data=pd.DataFrame(columns=['trade_date','stock_code','open','high','low','close','volume']) #产生一个辅助数据集,帮助后面循环时汇总
individual_data=pd.DataFrame() #存放个股交易信息的数据集
for individual_stockcode in stockcodes:
# 依次生成个股数据集(变量包括:日期、代码、开盘价、最高价、最低价、收盘价、成交量)
stock=w.wsd(individual_stockcode, "trade_code,open,high,low,close,volume",start_date,end_date)
individual_data['trade_date']=stock.Times
individual_data['stock_code']=stock.Data[0]
individual_data['open']=stock.Data[1]
individual_data['high']=stock.Data[2]
individual_data['low']=stock.Data[3]
individual_data['close']=stock.Data[4]
individual_data['volume']=stock.Data[5]
# 垂直合并个股记录,汇总到一张总表里,命名为panels
panels=append_data.append(individual_data)
append_data=copy.copy(panels) #为了使每次迭代后上一次的信息保留下来,把panels的信息复制给append_data
return(panels)
## 调用函数
stockpanel=getAsharePanels('000001.SZ','20080101','20171231')
stockpanel.head()
trade_date | stock_code | open | high | low | close | volume | |
---|---|---|---|---|---|---|---|
0 | 2008-01-02 | 000001 | 38.50 | 38.74 | 37.65 | 37.98 | 20052473.0 |
1 | 2008-01-03 | 000001 | 38.00 | 38.08 | 36.51 | 37.35 | 27564831.0 |
2 | 2008-01-04 | 000001 | 37.40 | 38.70 | 37.38 | 38.37 | 19870438.0 |
3 | 2008-01-07 | 000001 | 38.18 | 39.78 | 38.00 | 39.17 | 31514015.0 |
4 | 2008-01-08 | 000001 | 39.42 | 41.34 | 39.41 | 40.39 | 49992445.0 |
# 生成叶子节点属性:y向量
stockpanel['ret']=stockpanel['close']/stockpanel['open']-1
y_vector=[]
for i in stockpanel['ret']:
if i<0:
y_vector.append('lose')
else:
y_vector.append('win')
stockpanel['y']=y_vector
## STEP2: 划分样本,分为训练集和测试集(ps:这里还不算完善,因为没有划分验证集)
#删除多余的变量,注意:拟合时x变量的属性只能是float,不能是string
x=copy.copy(stockpanel)
x.drop('trade_date',axis=1, inplace=True)
x.drop('stock_code',axis=1, inplace=True)
x.drop('y',axis=1, inplace=True)
x.drop('ret',axis=1, inplace=True)
x.drop('high',axis=1, inplace=True)
x.drop('low',axis=1, inplace=True)
x_train=x.iloc[:1000,::] #前1000行记录划分为训练集
y_train=stockpanel['y'][:1000]
x_test=x.iloc[1000:,::] #后1000行记录划分为测试集
y_test=stockpanel['y'][1000:]
print("x训练集:",x_train.head())
print("y训练集:",y_train.head())
x训练集: open close volume
0 38.50 37.98 20052473.0
1 38.00 37.35 27564831.0
2 37.40 38.37 19870438.0
3 38.18 39.17 31514015.0
4 39.42 40.39 49992445.0
y训练集: 0 lose
1 lose
2 win
3 win
4 win
Name: y, dtype: object
#对x变量进行标准化处理
scaler=StandardScaler()
scaler.fit(x_)
y=np.array(stockpanel['y']).flatten()
x_std=scaler.transform(x_)
## STEP3: 用训练集生成决策树,进行拟合
dt=DecisionTreeClassifier()
dt.fit(x_train,y_train)
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='best')
# 用测试集数据查看模型拟合效果,获得评分
dt.score(x_test,y_test)
0.62970711297071125
## STEP4: 利用训练好的决策树进行预测
dt.predict(x_test)
array(['lose', 'win', 'lose', ..., 'win', 'win', 'win'], dtype=object)
决策树剪枝
参考资料
李航,统计学习方法,清华大学出版社,2012,p55
CSDN博客:C4.5算法详解(非常仔细)
sklearn关于决策树的官方使用文档
Ricequant决策树