決策樹引入
邏輯迴歸是一種線性有監督離散型分類模型
決策樹是一種非線性有監督離散型分類模型
隨機森林也是一種非線性有監督離散型分類模型
離散化
案例分析: 離散化
數據類型
-
離散的數據 需指明取值數量 2^M 種分割方式
天氣 : 晴天 雨天 多雲
學歷: 高中 本科 研究生 -
連續的數據 需離散化, 需指明離散化後的數量
車速:
低速 (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)損失函數:
- 基尼係數
- 熵
- 方差
這三種,都是值越大,純度越高
純度:當我們應用一個特徵(比如說頭髮長度)對數據(男女)進行分類的時候,如果這個特徵能把數據都分到一邊去(全部男,或者全部女),我們就說這個特徵可分類的純度高
有很多參數都在圍繞純度進行調式:splitter (best, random)…
(4) 決策樹的參數:都是爲了構建一個優秀的決策樹,提供的支持
max_leaf_node, max_depth…
(5)剪枝:就是決策數的正則化
爲了減少過擬合的現象
預剪枝:在樹沒有生成前,通過對將要生成樹的判斷,來進行限制max_depth
後剪枝:在樹生成之後,通過對某些葉子節點的刪除,來進行限制max_leaf_perc
2.隨機森林
隨機森林,就是由很多決策樹構成的
(1)並行思想:因爲隨機森林中的樹都是相互獨立的,所以這些樹可以在不同的機器上,或者CPU,GPU上運行,這樣能極大縮短建模的時間