决策树 Decision Tree
基本概念
画决策树的过程本质上是一个提纯(purify) 的过程。决策树最顶端的最大集合是内容繁杂的,我们通过一步一步的分类把一个复杂的大集合,变成多个相对纯粹的小集合。
Purity
那么,如何决定一个集合的纯粹度?举个例子,一个袋子里有十个球,这些球可能是红球可能是白球。最纯粹的情况就是十个全是红球,或者十个全是白球,而最不纯粹的情况就是五个红球,五个白球。在这个系统里我们引入一个度量工具:熵(entropy)。熵越大,就暗示这个系统越混乱,即越不纯粹。我们可以假设:
一个球是红球(X=x1)的概率为:p,
一个球是白球(X=x2)的概率为:1-p,
由此我们可以得出 这个系统里的熵 E = -plogp-(1-p)log(1-p)
如果出现红球与白球的概率相等,即 p=0.5,那么E=-log0.5( 最大值)
如果只可能出现红球或出现白球,即 p=0 or 1, 那么E = 0 (最小值)
由此 E关于p的曲线可以被想象成是一个类似于正态分布的钟形曲线,两边低中间高,最高点位于p=0.5 的时候。
优缺点
优点:
- 直观
- 可以处理类型变量,如:female,male. 我们不用把所有的变量量化。
- 可以应对有缺失值的情况
缺点:
4. 构建树的过程较复杂,很难找到最优化的树
类型
- 分类树(Classification Tree) : 使用熵作为分类标准,一层一层分下去的树。目的是将结果分为两或多类别
- 回归树(Regression Tree) : 使用mean square error最小作为分类标准,结果并非固定的n个类别,而是在一个范围中,如 [5,10]
示例
Wine quality
step 1: 导入数据
url = "http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
import pandas as pd
from pandas import DataFrame
w_df = pd.read_csv(url,header=0,sep=';')
w_df
step2: 建立 train test数据集
from sklearn.model_selection import train_test_split
train, test = train_test_split(w_df, test_size = 0.3)
x_train = train.iloc[0:,0:11]
y_train = train[['quality']]
x_test = test.iloc[0:,0:11]
y_test = test[['quality']]
step3: 建立 regressor
因为wine quality是一个数字大小具有含义的变量,所以我们需要用回归方法来决定如何对集合进行分类. max_depth决定了树的高度,即最后产生了2的几次方个小集合
from sklearn.tree import DecisionTreeRegressor
from sklearn import tree
model = tree.DecisionTreeRegressor(max_depth=3)
model.fit(x_train,y_train)
model.score函数可以返回模型在给定数据集下的R-square表现
print("Training R-Square",model.score(x_train,y_train))
print("Testing R-Square",model.score(x_test,y_test))
step4: 决策树图
在第一步,通过regressor,我们得出按照alcohol = 11.45进行分类,在总体样本中 mse = 0.658,样本数量为1119,整体平均wine quality值为5.662。在往下的每一次分类之后我们都要保证,分下去之后的mse都在减少,即0.658x1119 > 0.542x912 + 0.51x207
Rock vs. Mine
分辨一块石头是普通石头还是矿石,更适合用classification tree 而非 simple regression
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
model = tree.DecisionTreeClassifier(max_depth = 3,criterion='entropy')
model.fit(x_train,y_train)
随机森林方法 (可以deal with 缺失值)
简介:建立多个决策树,决策树不需要考虑所有变量,如随机选择四个independent variable。最后用所有的决策树生成的所有结果来投票,确定最终这个prediction是rock还是mine。
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=10)
model.fit(x_train,np.ravel(y_train))
通过n_estimators可以定义生成决策树的数量。
比较不同的随机森林们?使用GridsearchCV
from sklearn.model_selection import GridSearchCV
parameters = {
'n_estimators':(10, 30, 50), #the number of trees
'max_depth':(4,5,6,8,10,15),
'min_samples_split': (2, 4, 8), #how much subset in one split
'min_samples_leaf': (4,8,12,16) #in the end, how much subsets
}# 通过设置各种我们感兴趣想生成的森林参数,让不同参数形成的森林相互比较
model = GridSearchCV(RandomForestClassifier(),parameters,cv=3,iid=False)
model.fit(x_train, np.ravel(y_train))
model.best_score_, model.best_params_
最终会返回比较之下,分数最高的参数组合。
Bootstrapping方法(bagging)
与随机森林不同的是,随机森林是随机在independent variable当中取样 (纵向) ,通过研究不同自变量对应变量的影响程度大小,让不同决策树对最终结果进行投票。而bootstrapping是随机在数据集的数据行中进行有放回的取样 (横向) ,可能在取样过程中,同一行被选中多次。在这个情况下,每一次取样产生的数据集subset也可以被用来建立一个decision tree。最后,与随机森林一样,根据所有决策树的投票结果选出prediction结果。
from sklearn.ensemble import BaggingClassifier
model=BaggingClassifier()
model.fit(x_train,np.ravel(y_train))
model.score(x_test,y_test)
GridsearchCV也可以用来比较不同的bootstrapping之间的优劣
from sklearn.model_selection import GridSearchCV
parameters = {
'n_estimators':(30, 50), #the number of trees
'max_samples':(30,40,50),
'max_features':(5,10,20),
#'oob_score':np.ravel(y_test)
}
model = GridSearchCV(BaggingClassifier(),parameters,cv=3,iid=False)
model.fit(x_train, np.ravel(y_train))
model.best_score_, model.best_params_