機器學習:決策樹與隨機森林

決策樹引入

邏輯迴歸是一種線性有監督離散型分類模型

決策樹是一種非線性有監督離散型分類模型

隨機森林也是一種非線性有監督離散型分類模型

離散化

案例分析: 離散化

數據類型

  1. 離散的數據 需指明取值數量 2^M 種分割方式
    天氣 : 晴天 雨天 多雲
    學歷: 高中 本科 研究生

  2. 連續的數據 需離散化, 需指明離散化後的數量
    車速:
    低速 (60)中速 (80 )高速
    M+1種分割方式

決策樹是通過固定的條件來對類別進行判斷:
在這裏插入圖片描述
在這裏插入圖片描述

決策樹的生成:

數據在不斷分裂的遞歸過程,每一次分裂,儘可能讓類別一樣的數據在樹的一邊,當樹的葉子節點的數據都是一類的時候,則停止分裂(if lese語句)
在這裏插入圖片描述

計算純度的方式

在這裏插入圖片描述
基尼係數,熵越大,方差越大,數據集越不一樣,純度越高

基尼係數

基尼係數是指國際上通用的、用以衡量一個國家或地區居民收入差距的常用指標

  • 若低於0.2表示指數等級極低;(高度平均)
  • 0.2-0.29表示指數等級低;(比較平均)
  • 0.3-0.39表示指數等級中;(相對合理)
  • 0.4-0.59表示指數等級高;(差距較大)
  • 0.6以上表示指數等級極高。(差距懸殊)

一般發達國家的基尼指數在0.24到0.36之間,美國偏高,爲0.45。中國國家統計局公佈基尼係數2012年爲0.474,2013年爲0.473,2014年爲0.469,2015年爲0.462,2016年爲0.465

熵和方差我們前面講過,這裏不再贅述

決策樹的分割方式:非線性

在這裏插入圖片描述

單顆決策樹的缺陷

單顆決策樹的缺點:

運算量大,需要一次加載所有數據進內存。並且找尋分割條件是一個極耗資源的工作

訓練樣本中出現異常數據時,將會對決策樹產生很大影響。抗干擾能力差

解決方法:

減少決策樹所需訓練樣本(減少列或者減少行)

隨機採樣,降低異常數據的影響

邏輯迴歸的優點:

和邏輯迴歸比,邏輯迴歸可以給告訴我們概率(或者設置閾值),二決策樹只能0, 1

隨機森林

森林:由樹組成

隨機:生成樹的數據都是從數據集中隨機選取的

當數據集很大的時候,我們隨機選取數據集的一部分,生成一顆樹,重複上述過程,我們可以生成一堆
形態各異的樹,這些樹放在一起就叫森林
在這裏插入圖片描述
在這裏插入圖片描述

隨機森林VS邏輯迴歸

在這裏插入圖片描述

剪枝

預剪枝: 在這棵樹還沒開始分裂的時候,提前設定好一些條件,在達到這些條件以後就不長了

後剪枝:先長,長完了再去掉(比如合併葉子節點)

預剪枝的方式:

(1)控制分裂的層次
(2)控制葉子節點的樣本數量

剪枝保證了模型的通用性

決策樹做迴歸

在這裏插入圖片描述
通過求均值的方式來讓分類結果可數

代碼實現

決策樹

# encoding:utf-8
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
# 決策數的分類器
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt

iris = load_iris()
data = pd.DataFrame(iris.data)
data.columns = iris.feature_names
data['Species'] = iris.target
# print(data)

# 花萼長度和寬度
x = data.iloc[:, :2]
y = data.iloc[:, -1]

# 對數據集進行切分
# 相同的隨機種子產生的隨機數是一樣
# 不同的隨機種子產生的隨機數不一樣
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.75, random_state=42)

# 創建一個決策數的模型
tree_clf = DecisionTreeClassifier(max_depth=4, criterion='entropy')
tree_clf.fit(x_train, y_train)
y_test_hat = tree_clf.predict(x_test)
print("acc score:", accuracy_score(y_test, y_test_hat))

depth = np.arange(1, 15)
err_list = []

"""
splitter: 分裂的方式
             best   找最好的維度進行分裂
             random 隨機找維度進行分裂
feature: splitter方法中,找best分割維度的時候,需要在多少個維度中找那個最好的 
            none 就是不限制找的數量
            int 就是找n個數進行考量
            float就是找0.5(50%)去試
            sqrt就是找所有特徵數開根號個特徵
max_depth: 樹分裂的最大深度 none
min_sample_split:分裂前我需要保證這個葉子有幾個樣本 
                      int就是要保證葉子裏的樣本數大於n,
                      float 就是要保證葉子裏的樣本數大於某個百分比
min_sample_leaf: 分裂後需要保證每個分裂的葉子有幾個樣本
min_weight_fraction_leaf:每個葉子節點裏的樣本數,必須是所有樣本的10%
max_leaf_nodes:最多的葉子數
min_impurity_split:每個葉子節點裏的不純度,這個參數是爲了保證樹不會過早的停止生長;達不到指標就會繼續往下分裂 
"""

for d in depth:
    clf = DecisionTreeClassifier(criterion='entropy', max_depth=d)
    clf.fit(x_train, y_train)
    y_test_hat = clf.predict(x_test)
    result = (y_test_hat == y_test)
    err = 1 - np.mean(result)
    err_list.append(err)
    print(d, '錯誤率: %.2f%%' % (100 * err))

plt.figure(facecolor='w')
plt.plot(depth, err_list, 'ro-', lw=2)
plt.xlabel('Decision Tree Depth', fontsize=15)
plt.ylabel('Error Rate', fontsize=15)
plt.title('Decision Tree Depth & Over Fit', fontsize=18)
plt.grid(True)
plt.show()

在這裏插入圖片描述
在這裏插入圖片描述

隨機森林

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data[:, :2]  # 花萼的長度和寬度(因爲選花瓣的長寬的話,分類效果太好了)
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=43)

# n_estimators指的是用多少顆樹, max_leaf_1des指樹的複雜程度, n_jobs指用多少個線程
rnd_clf = RandomForestClassifier(n_estimators=30, max_leaf_nodes=16, n_jobs=1)
rnd_clf.fit(X_train, y_train)

# bagging:並行思想,bagging的決策樹和隨機森林其實是等價的
# max_samples 訓練時用所有的樣本  splitter=random 指的是雖然每課小樹取使用所有樣本,但是我只使用隨機出來的一部分維度來訓練每棵小樹
bag_clf = BaggingClassifier(
    DecisionTreeClassifier(splitter="random", max_leaf_nodes=16),
    n_estimators=30, max_samples=1.0, bootstrap=True, n_jobs=1
)
bag_clf.fit(X_train, y_train)

y_pred_rf = rnd_clf.predict(X_test)
y_pred_bag = bag_clf.predict(X_test)
print(accuracy_score(y_test, y_pred_rf))
print(accuracy_score(y_test, y_pred_bag))

# Feature Importance 用隨機森林選擇出來重要的特徵,也就是分裂效果好的特徵,也就是和y相關性大的特徵
# 一般來說,相關性越大的特徵,應該出現在樹的上層
iris = load_iris()
# -1 表示有多少線程用多少線程
rnd_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1)
rnd_clf.fit(iris["data"], iris['target'])
for name, score in zip(iris['feature_names'], rnd_clf.feature_importances_):
    print(name, score)

'''
Xgbost: 並行
GDBT:串行
公司中,特徵提取會用到樹的算法

'''

在這裏插入圖片描述

總結

決策樹和隨機森林

1.決策樹
(1)決策樹是一個有監督的機器學習算法,做分類用的,而且是非線性的。
(2)決策樹的建模過程,不是創造一個方程了,而是構建一棵樹。這棵樹不一定只是二叉樹
(3)損失函數:

  1. 基尼係數
  2. 方差

這三種,都是值越大,純度越高

純度:當我們應用一個特徵(比如說頭髮長度)對數據(男女)進行分類的時候,如果這個特徵能把數據都分到一邊去(全部男,或者全部女),我們就說這個特徵可分類的純度高

有很多參數都在圍繞純度進行調式:splitter (best, random)…

(4) 決策樹的參數:都是爲了構建一個優秀的決策樹,提供的支持
max_leaf_node, max_depth…
(5)剪枝:就是決策數的正則化

爲了減少過擬合的現象

預剪枝:在樹沒有生成前,通過對將要生成樹的判斷,來進行限制max_depth

後剪枝:在樹生成之後,通過對某些葉子節點的刪除,來進行限制max_leaf_perc

2.隨機森林
隨機森林,就是由很多決策樹構成的
(1)並行思想:因爲隨機森林中的樹都是相互獨立的,所以這些樹可以在不同的機器上,或者CPU,GPU上運行,這樣能極大縮短建模的時間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章