決策樹

1. sklearn 實(shí)現(xiàn)決策樹

1.1 語法與參數(shù)

class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort='deprecated', ccp_alpha=0.0)
參數(shù)說明:


- criterion: 不純度計(jì)算指標(biāo) {“gini”, “entropy”},

- splitter: {“best”, “random”}, default=”best” 節(jié)點(diǎn)切分方法,默認(rèn)是選擇最優(yōu)特征進(jìn)行切分.

- max_depth: 樹能達(dá)到的最大深度,防止模型太深,控制模型復(fù)雜度

- min_samples_split: int or float, default=2  抑制模型分裂

    一個節(jié)點(diǎn)想要向下進(jìn)行切分,當(dāng)前樣本個數(shù)必須要大于這個參數(shù)值.
    例如設(shè)置為10,當(dāng)這個節(jié)點(diǎn)中如果有9個樣本,則這個節(jié)點(diǎn)只能作為葉節(jié)點(diǎn).

- min_samples_leaf:  int or float, default=1  抑制模型分裂

    最小葉節(jié)點(diǎn)樣本個數(shù),如果上層節(jié)點(diǎn)分裂之后,分裂出來后的葉節(jié)點(diǎn)當(dāng)中樣本個數(shù)不足這兒參數(shù)值,則本次分裂不能進(jìn)行.

- max_features : int, float or {“auto”, “sqrt”, “l(fā)og2”}, default=None

    最大特征,在尋找最優(yōu)分裂點(diǎn)的時(shí)候,要考慮的特征個數(shù)

    If int, 考慮特征個數(shù),舉例有100個特征, 填寫20,就是每次分裂的時(shí)候,只計(jì)算20個特征.

    If float, 百分比 0-1的浮點(diǎn)數(shù). 100個特征, 填寫0.3,那就是計(jì)算30個特征.

    If “auto”, then max_features=sqrt(n_features). 根號個特征.100個特征就是計(jì)算10個特征

    If “sqrt”, then max_features=sqrt(n_features). 同上

    If “l(fā)og2”, then max_features=log2(n_features). 計(jì)算log2個特征,64個特征,6個.

    If None, then max_features=n_features. 所有特征
    

- random_state: 隨機(jī)數(shù)種子

- max_leaf_nodes:  抑制模型分裂恬涧,最大葉節(jié)點(diǎn)個數(shù),最多能夠分裂出多少個葉節(jié)點(diǎn). 

- min_impurity_decrease: 分裂中的最小不純度下降的值. 

    如果一次分裂過程中,Gain的下降不能超過這個值,那么就不能進(jìn)行本次分裂. 

- class_weight: 類別權(quán)重設(shè)置,(類別不均衡數(shù)據(jù)集的問題)

屬性:


- classes_ : 分類標(biāo)簽,沒用

- feature_importances_: 特征重要性.

方法:

- get_depth(self) : 樹的深度

- get_n_leaves(self): 葉節(jié)點(diǎn)的個數(shù)


2. 泰坦尼克數(shù)據(jù)集應(yīng)用決策樹

導(dǎo)包 --> 導(dǎo)入數(shù)據(jù) --> 數(shù)據(jù)探索 --> 數(shù)據(jù)預(yù)處理 --> 切分X,y --> 構(gòu)建模型 --> 評價(jià)

2.1 讀入數(shù)據(jù)

import pandas as pd
import numpy as np
import matplotlib.pylab as plt

train = pd.read_csv('titanic/train.csv')
test = pd.read_csv('titanic/test.csv')
answer = pd.read_csv('titanic/gender_submission.csv')
  • PassengerId: 乘客ID,沒用
  • Pclass: 票等級
  • Name: 姓名,沒用
  • Sex: 性別
  • Age: 年齡
  • SibSp: 乘客同在船上的兄弟姐妹/配偶的個數(shù)(整數(shù)值)
  • Parch:乘客同在船上的乘客父母/孩子的個數(shù)(整數(shù)值)
  • Ticket:票號(字符串) 沒用
  • Fare:乘客所持票的價(jià)格(浮點(diǎn)數(shù),0-500不等)
  • Cabin:乘客所在船艙(有缺失)
  • Embark:乘客登船港口:S席噩、C模捂、Q(有缺失)


    train數(shù)據(jù)

2.2 數(shù)據(jù)探索

# 各個客艙人數(shù)
train['Pclass'].value_counts()
各客艙人數(shù)
# 各類票價(jià)均值
train.groupby(by = 'Pclass').mean()['Fare']
各類票價(jià)均值
# 性別比例
train['Sex'].value_counts()

plt.style.use('seaborn') # 改變繪圖風(fēng)格
# Series里面有封裝自帶的畫圖功能
train.Sex.value_counts().plot(kind='barh')
性別比例
# 男女獲救比例
train.groupby('Sex').mean()
男女獲救比例
# 年齡分布
train['Age'].plot(kind = 'hist')

# 將年齡離散化然后看獲救比例(10歲一級)
age_cut = pd.cut(train['Age'],bins = [0,10,20,30,40,50,60,70,80])
train['age_cut'] = age_cut

# 存活下來的Survived標(biāo)簽都是1捶朵,所以直接分類累加聚合就是比例蜘矢,0累加還是0
print("平均生存率: {:.3f}\n".format(train['Survived'].mean()))
print("各倉位等級存活率:\n{}\n".format(train.groupby(by = 'Pclass')['Survived'].mean()))
print("各年齡段生存率如下: \n{}".format(train.groupby(by = 'age_cut').mean()['Survived']))
存活率
# 構(gòu)造函數(shù),查看所有特征與生存率
def survive(feature):
    #return train.groupby(by=feature).mean()['Survived']
    Survived = train.groupby(by = feature)['Survived'].mean()
    print(feature + "存活率:\n{}".format(Survived))
    Survived.plot(kind = 'pie')
    plt.show()
    print('-'*40)

for i in ['Pclass','Sex','SibSp','Parch','Embarked']:
    survive(i)
函數(shù)得到的存活率

2.3 數(shù)據(jù)預(yù)處理

  1. 刪除無效特征

  2. 填充空值

  3. 特征編碼

2.3.1 刪除無效特征

# inplace  = True 直接在原表改泉孩,省去賦值
train.drop(columns=['PassengerId','Name','Cabin','Ticket'],inplace=True)
train.pop('age_cut') # 直接刪

test.drop(columns=['PassengerId','Name','Cabin','Ticket'],inplace=True)

2.3.2 填充空值

train.info()
數(shù)據(jù)總覽
# 將年齡空值填充中位數(shù)
train.Age.fillna(train.Age.median(),inplace=True)

# 登錄港口空值填充眾數(shù)
train.Embarked.fillna('S',inplace=True)

# 測試集填充硼端,測試集也用訓(xùn)練集數(shù)據(jù)填充,參考KNN歸一化
test.Age.fillna(28,inplace=True)
test.Embarked.fillna('S',inplace=True)

2.3.3 特征編碼

# 對性別進(jìn)行編碼 0:男 1:女
train['Sex'] = (train.Sex == 'female').astype('int')

# 對倉位進(jìn)行編碼
train['Embarked'] = train.Embarked.map({'S':0,'C':1,'Q':2})

test['Sex'] = (test.Sex == 'female').astype('int')

# 對倉位進(jìn)行編碼
test['Embarked'] = test.Embarked.map({'S':0,'C':1,'Q':2})

test.Fare.fillna(train.Fare.mean(),inplace=True)

2.4 拆分X寓搬,y

train_y = train.pop('Survived')
train_X = train.copy() #拷貝

test_X = test.copy()# 提取X
test_y = submission.Survived #提取y
train_X

2.5 決策樹建模

導(dǎo)包 --> 實(shí)例化 --> fit --> 評估
from sklearn.tree import DecisionTreeClassifier

dtc = DecisionTreeClassifier(random_state = 666)
dtc.fit(train_X,train_y)
dtc.score(train_X,train_y)  # 訓(xùn)練精度 0.9797
dtc.score(test_X,test_y) # 測試精度 0.8086 過擬合了

3. 過擬合

上邊的結(jié)果明顯過擬合:訓(xùn)練集的準(zhǔn)確率,遠(yuǎn)遠(yuǎn)高于測試集的準(zhǔn)確率

  • 擬合: 模型對數(shù)據(jù)的學(xué)習(xí)過程,模型去適配數(shù)據(jù)

  • 噪聲: 代表了我們數(shù)據(jù)中存在的一些和普適性的規(guī)律不一樣的信息.

數(shù)據(jù)信息兩類(規(guī)律, 噪聲):舉例: 大部分年齡大的男性都死亡了,但是有幾個活下來了,這幾個就不符合常規(guī)的規(guī)律,就是數(shù)據(jù)集中的異常數(shù)據(jù),或者說是噪聲.

如果模型的學(xué)習(xí)能力太強(qiáng),就不但會學(xué)習(xí)到數(shù)據(jù)中的規(guī)律,還會學(xué)習(xí)到數(shù)據(jù)中的噪聲.

這個時(shí)候模型表現(xiàn): 對訓(xùn)練集預(yù)測非常準(zhǔn)確,但是對測試集表現(xiàn)就會很差,這種情況下,我們就稱為模型過擬合了.

  • 欠擬合:模型的學(xué)習(xí)能力太差了,連訓(xùn)練集中的規(guī)律都沒學(xué)會.

  • 表現(xiàn): 無論是訓(xùn)練集還是測試集,它的表現(xiàn)都很差.

解決方案:網(wǎng)格搜索 調(diào)參(降低訓(xùn)練精度珍昨,提高測試精度)

3.1 語法

GridSearchCV: 交叉驗(yàn)證網(wǎng)格搜索

class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, iid='deprecated', refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False)

參數(shù)說明:

- estimator: 模型

- param_grid : 參數(shù)字典

- scoring : 模型評估指標(biāo),默認(rèn)準(zhǔn)確率

- n_jobs: CPU個數(shù)

- cv: 交叉驗(yàn)證折數(shù)

- verbose: 日志

屬性:

- best_estimator_ : estimator  在網(wǎng)格搜索過程中,找到的最好的分類器.

- best_score_: 最好的分類器,對應(yīng)的交叉驗(yàn)證分?jǐn)?shù)

- best_params_: 最好的分類器對應(yīng)的參數(shù)

3.2 對泰坦尼克模型使用

from sklearn.model_selection import GridSearchCV

# 實(shí)例化
# 參數(shù)分成兩部分: 1.你要調(diào)參的,就不用設(shè)置  2.你不打算調(diào)的,就可以設(shè)置
dtc = DecisionTreeClassifier( random_state=666)
# max_depth=None, 非常重要
# min_samples_split=2, min_samples_leaf=1, 最小葉節(jié)點(diǎn)分裂個數(shù),可選
# max_leaf_nodes=None, 有一定作用
# min_impurity_decrease=0.0 有一定作用,范圍不好確定

決策樹參數(shù)說明:


- criterion: 不純度計(jì)算指標(biāo) {“gini”, “entropy”},

- splitter: {“best”, “random”}, default=”best” 節(jié)點(diǎn)切分方法,默認(rèn)是選擇最優(yōu)特征進(jìn)行切分.

- max_depth: 樹能達(dá)到的最大深度,防止模型太深,控制模型復(fù)雜度

- min_samples_split: int or float, default=2  抑制模型分裂

    一個節(jié)點(diǎn)想要向下進(jìn)行切分,當(dāng)前樣本個數(shù)必須要大于這個參數(shù)值.
    例如設(shè)置為10,當(dāng)這個節(jié)點(diǎn)中如果有9個樣本,則這個節(jié)點(diǎn)只能作為葉節(jié)點(diǎn).

- min_samples_leaf:  int or float, default=1  抑制模型分裂

    最小葉節(jié)點(diǎn)樣本個數(shù),如果上層節(jié)點(diǎn)分裂之后,分裂出來后的葉節(jié)點(diǎn)當(dāng)中樣本個數(shù)不足這兒參數(shù)值,則本次分裂不能進(jìn)行.

- max_features : int, float or {“auto”, “sqrt”, “l(fā)og2”}, default=None

    最大特征,在尋找最優(yōu)分裂點(diǎn)的時(shí)候,要考慮的特征個數(shù)

    If int, 考慮特征個數(shù),舉例有100個特征, 填寫20,就是每次分裂的時(shí)候,只計(jì)算20個特征.

    If float, 百分比 0-1的浮點(diǎn)數(shù). 100個特征, 填寫0.3,那就是計(jì)算30個特征.

    If “auto”, then max_features=sqrt(n_features). 根號個特征.100個特征就是計(jì)算10個特征

    If “sqrt”, then max_features=sqrt(n_features). 同上

    If “l(fā)og2”, then max_features=log2(n_features). 計(jì)算log2個特征,64個特征,6個.

    If None, then max_features=n_features. 所有特征
    

- random_state: 隨機(jī)數(shù)種子

- max_leaf_nodes:  抑制模型分裂句喷,最大葉節(jié)點(diǎn)個數(shù),最多能夠分裂出多少個葉節(jié)點(diǎn). 

- min_impurity_decrease: 分裂中的最小不純度下降的值. 

    如果一次分裂過程中,Gain的下降不能超過這個值,那么就不能進(jìn)行本次分裂. 

- class_weight: 類別權(quán)重設(shè)置,(類別不均衡數(shù)據(jù)集的問題)

參數(shù)調(diào)優(yōu):

# 設(shè)置調(diào)參字典
# 設(shè)置一個調(diào)參字典
d = {"ccp_alpha":np.arange(0.0,0.8,0.1),
    'criterion':["gini",'entropy'],
    "max_depth":[2,3,4,5,6,7],
    "min_samples_split":range(2,10), #最小葉節(jié)點(diǎn)樣本個數(shù)
     "max_leaf_nodes":range(4,20), #最大葉節(jié)點(diǎn)個數(shù) 
     #"min_impurity_decrease":np.arange(0.01,0.11,0.01) #分裂中的最小不純度下降的值
    }

# 實(shí)例化網(wǎng)格搜索
grid = GridSearchCV(dtc,param_grid =d ,n_jobs=-1,cv=5,  verbose=2 )

# 訓(xùn)練
grid.fit(X,y)

# 搜索到的最優(yōu)交叉驗(yàn)證分?jǐn)?shù) : 0.8238026489234824
grid.best_score_
# 搜索到的參數(shù)
grid.best_params_
# 結(jié)果
{'criterion': 'gini',
 'max_depth': 6,
 'max_leaf_nodes': 15,
 'min_samples_split': 2}

# 分類器
best_model = grid.best_estimator_

# 看一下搜索到的這個結(jié)果,在測試集上面表現(xiàn)如何?
best_model.score(X_test,y_test)

# feature_importances_: 特征重要性.
best_model.feature_importances_
#結(jié)果
array([0.1935308 , 0.56999101, 0.09826444, 0.04071957, 0.00751746,
       0.08082954, 0.00914718])
#相對應(yīng)的特征
X.columns
#輸出:
Index(['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked'], dtype='object')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镣典,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唾琼,更是在濱河造成了極大的恐慌兄春,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锡溯,死亡現(xiàn)場離奇詭異赶舆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)祭饭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門芜茵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倡蝙,你說我怎么就攤上這事九串。” “怎么了寺鸥?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵猪钮,是天一觀的道長。 經(jīng)常有香客問我胆建,道長烤低,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任笆载,我火速辦了婚禮扑馁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宰译。我一直安慰自己,他們只是感情好魄懂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布沿侈。 她就那樣靜靜地躺著,像睡著了一般市栗。 火紅的嫁衣襯著肌膚如雪缀拭。 梳的紋絲不亂的頭發(fā)上咳短,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音蛛淋,去河邊找鬼咙好。 笑死,一個胖子當(dāng)著我的面吹牛褐荷,可吹牛的內(nèi)容都是我干的勾效。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叛甫,長吁一口氣:“原來是場噩夢啊……” “哼层宫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起其监,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤萌腿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后抖苦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毁菱,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年锌历,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贮庞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡辩涝,死狀恐怖贸伐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怔揩,我是刑警寧澤捉邢,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站商膊,受9級特大地震影響伏伐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晕拆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一藐翎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧实幕,春花似錦吝镣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至整吆,卻和暖如春拱撵,著一層夾襖步出監(jiān)牢的瞬間辉川,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工拴测, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乓旗,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓集索,卻偏偏與公主長得像屿愚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抄谐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355