日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

boost原理与sklearn源码_机器学习sklearn系列之决策树

發布時間:2023/12/1 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost原理与sklearn源码_机器学习sklearn系列之决策树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、 Sklearn庫

Scikit learn 也簡稱 sklearn, 自2007年發布以來,scikit-learn已經成為Python重要的機器學習庫了。支持包括分類、回歸、降維和聚類四大機器學習算法。還包含了特征提取、數據處理和模型評估三大模塊。sklearn是Scipy的擴展,建立在NumPy和matplotlib庫的基礎上。利用這幾大模塊的優勢,可以大大提高機器學習的效率。sklearn擁有著完善的文檔,上手容易,具有著豐富的API,在學術界頗受歡迎。sklearn已經封裝了大量的機器學習算法,包括LIBSVM和LIBINEAR。同時sklearn內置了大量數據集,節省了獲取和整理數據集的時間。

SKlearn官網:http://scikit-learn.org/stable/index.html

上圖是它的官網,從官網上看到Sklearn包含了很多種機器學習的方式,分別有:Classification 分類,Regression 回歸,Clustering 非監督分類,Dimensionality reduction 數據降維,Model Selection 模型選擇,Preprocessing 數據預處理

每個模塊中有又包含了多種機器學習算法,

? 分類:識別某個對象屬于哪個類別,常用的算法有:SVM(支持向量機)、nearest neighbors(最近鄰)、random forest(隨機森林),常見的應用有:垃圾郵件識別、圖像識別。

? 回歸:預測與對象相關聯的連續值屬性,常見的算法有:SVR(支持向量機)、 ridge regression(嶺回歸)、Lasso,常見的應用有:藥物反應,預測股價。

? 聚類:將相似對象自動分組,常用的算法有:k-Means、 spectral clustering、mean-shift,常見的應用有:客戶細分,分組實驗結果。

? 降維:減少要考慮的隨機變量的數量,常見的算法有:PCA(主成分分析)、feature selection(特征選擇)、non-negative matrix factorization(非負矩陣分解),常見的應用有:可視化,提高效率。

? 模型選擇:比較,驗證,選擇參數和模型,常用的模塊有:grid search(網格搜索)、cross validation(交叉驗證)、 metrics(度量)。它的目標是通過參數調整提高精度。

? 預處理:特征提取和歸一化,常用的模塊有:preprocessing,feature extraction,常見的應用有:把輸入數據(如文本)轉換為機器學習算法可用的數據。

由于幫助文檔是英文,如下圖,對于國內的編程人員說來說是個挑戰,很遺憾到現在沒有很好的中文版本的文檔。

我們知道在工程應用中,用python手寫代碼來從頭實現一個算法的可能性非常低,這樣不僅耗時耗力,還不一定能夠寫出構架清晰,穩定性強的模型。更多情況下,是分析采集到的數據,根據數據特征選擇適合的算法,在工具包中調用算法,調整算法的參數,獲取需要的信息,從而實現算法效率和效果之間的平衡。而sklearn,正是這樣一個可以幫助我們高效實現算法應用的工具包。

如果你有興趣,并且想進一步深入學習機器學習算法,可以讀取它的源碼來學習。這里推薦兩本書給大家

該書特點:以實例為重,給出了常用算法的偽代碼,和《模式識別》、《模式分類》等專著比起來,該書略去了各個定理的證明部分,并通過大量枚舉具體的分類實例,來簡要說明算法的流程和意義。

任何想深入討談分類、回歸、相關分析或者預測的問題,無論你想使用的是神經網絡還是支持向量機,還是最原始的貝葉斯分類器,這本書都提供了一個比較完整的該領域的輪廓。

雖然對于具體的分類器和算法的分析淺嘗輒止,但是該書最大的優點是能讓初學者以最快的速度總覽全局,掌握該領域的基本要點,而且該書對于數學和統計的相關概念,是我看過的相關書籍里要求最低的,高中生應該都能看懂的。

作者:http://cs.nju.edu.cn/zhouzh/

很著名的西瓜書,機器學習入門必備,書里舉的很多例子都通俗易懂,特別是決策樹章節關于西瓜特征分類的描述。很多算法論述都省略了大量細節,初學者想要靠它自行推導還是存在很大難度,大家別覺得恐怖,可以慢慢看多看幾遍,才能體會到它的美感。

二、 決策樹

1. 什么是決策樹

決策樹算法,人如其名,結構就像一棵樹,有分叉的枝丫和樹葉。枝丫的分叉處是關于目標某一個特征的判斷,枝丫本體則是關于該特征的判斷結果,而葉子則是判斷過后產生的決策結果。

上圖就是一個最為簡單的分類樹決策,當我們看天氣預報時,根據降雨、霧霾、氣溫、活動范圍是室內活動還是室外活動等等特征將自己的行為分類為出門和不出門。簡單來說,決策樹可以被看做由一大堆if-then的判斷,每一條枝丫都是一條規則。

給決策樹(Decision Tree)下個定義就是一種非參數的有監督學習方法,有監督學習就是需要輸入標簽的數據,它能夠從一系列有特征和標簽的數據中總結出決策規則。并用樹狀圖的結構來呈現這些規則,以解決分類和回歸問題。決策樹算法容易理解,適用各種數據,在解決各種問題時都有良好表現,尤其是以樹模型為核心的各種集成算法,在各個行業和領域都有廣泛的應用。比如:金融行業可以用決策樹做貸款風險評估

保險行業可以用決策樹做險種推廣預測

醫療行業可以用決策樹生成輔助診斷處置模型,

游戲行業內的流失預測模型。通過回溯用戶歷史行為,選擇登錄間隔、游戲內停留時長甚至某一關卡是否過關等等,從而去判斷究竟是哪一環節讓用戶對游戲失去興趣,從而實施對策。

2. 決策樹的工作過程

決策樹是在機器學習中非常有用的一個模型。

我們簡單了解一下決策樹如何工作的,決策算法本質上是一種圖的結構,我們只需要問一系列的問題就可以對數據進行分類了,比如說看看面的數據組,這是一系列已知的物種以及所屬類別的數據,

前八列都是特征,第九列就是我們所謂的標簽,上表是我們在機器學習中最常見的一種數據表格。決策樹就是把這張表總結起來看起來非常簡單的樹(下圖),來讓我們做出非常簡單的決策,

如我們的目標是將上表中的數據分為哺乳動物和非哺乳類,根據已經收集的(上表)數據,決策樹算法為我們算出下面的這顆決策樹。

決策樹利用如上圖所示的樹結構進行決策,每一個非葉子節點是一個判斷條件,每一個葉子節點是結論。從跟節點開始,經過多次判斷得出結論。

下面我們用上面的數據按照這個樹來不斷提問,比如第五行的數據蛙,他是不是恒溫,答案為不是,蛙就是非哺乳動物。再用貓舉例,貓是否恒溫,答案是恒溫,它選擇左側的節點,問是否胎生,答案是,繼續選擇左側的節點,答案是哺乳動物。

現在只要給你任一動物,你只要按照這個樹,不斷的提問就可以知道它是否是哺乳動物。

假設有一種新物種是java,它是恒溫,體表帶毛,并且是胎生,我們就可以通過這個巨冊書判斷它的所屬類別。

我們可以看出,在這個決策過程中,我們是一只對記錄的特征進行提問,最初的問題所在地方叫做根節點,在得到結論前的每一個問題都是中間節點,而得到的每一個結論(動物的類別)都叫做葉子結點。

知識點:

父節點和子節點是相對的,說白了子節點由父節點根據某一規則分裂而來,然后子節點作為新的父親節點繼續分裂,直至不能分裂為止。而根節點是沒有父節點的節點,即初始分裂節點,葉子節點是沒有子節點的節點,如下圖所示:

決策樹利用如上圖所示的樹結構進行決策,每一個非葉子節點是一個判斷條件,每一個葉子節點是結論。從跟節點開始,經過多次判斷得出結論。

決策樹算法的核心解決兩個問題:

? 如何從數據表中找出最佳節點和最佳分枝?

決策樹是對特征提問,如何找出最佳節點和最佳分支,我怎么知道哪些特征提問,才能生成有效的樹呢?

? 如何讓決策樹停止增長,防止過擬合?

如果我有無數個特征,決策樹會長成什么樣子,他是不是會長成無數層深,我們要怎么樣讓它停止成長呢?怎么樣防止過擬合呢?

所有決策樹相關模型調整的方法,都圍繞這個問題展開,這兩個問題背后的原理非常復雜,如果大家對里面的原理感興趣建議學習相關數學知識。

3. Sklearn中的決策樹

sklearn中決策樹中的類都在tree這個模塊下,這個模塊包含5個類,不包括集成算法:

4. Sklearn的建模流程

建模編碼流程:

? 導入所需庫

? 建立評估模型對象

? 訓練數據

? 通過模型提取所需信息,

對應流程代碼:

from sklearn import tree #導入指定模塊

clf = tree.DecisionTreeClassifier() #實例化

clf = clf.fit(a_train , b_train) #用訓練的數據訓練模型

result = clf.score(a_test , b_test) @導入測試集,從街口中調用需要的信息

只要記憶這個過程,編寫就變得很簡單了。

上面代碼中score方法是提取我們需要的信息,他是導入測試集,然后可以得到這個模型的評估指標,默認是預測的精確性。

5. DecisionTreeClassifier重要參數

sklearn中決策樹算法參數共有13個,如下:

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=False)

A. 重要參數:criterion

為了要將表格轉化為一棵樹,決策樹需要找出最佳節點和最佳的分枝方法,對分類樹來說,衡量這個“最佳”的指標叫做“不純度”。通常來說,不純度越低,決策樹對訓練集的擬合越好。現在使用的決策樹算法在分枝方法上的核心大多是圍繞在對某個不純度相關指標的最優化上。

不純度基于節點來計算,樹中的每個節點都會有一個不純度,并且子節點的不純度一定是低于父節點的,這是有詳細的數學證明的。也就是說,在同一棵決策樹上,葉子節點的不純度一定是最低的。

Criterion這個參數正是用來決定不純度的計算方法的。sklearn提供了兩種選擇:

1)輸入”entropy“,使用信息熵(Entropy)

2)輸入”gini“,使用基尼系數(Gini Impurity)

下面是兩個參數的計算方法。

其中t代表給定的節點,i代表標簽的任意分類,p (i|t)代表標簽分類i在節點t上所占的比例。如果你實在無法理解也不要緊,因為sklearn是不需要你懂的,哈哈。注意,當使用信息熵時,sklearn實際計算的是基于信息熵的信息增益(Information Gain),即父節點的信息熵和子節點的信息熵之差。

比起基尼系數,信息熵對不純度更加敏感,對不純度的懲罰最強。但是在實際使用中,信息熵和基尼系數的效果基本相同。就個人經驗來說信息熵的計算比基尼系數緩慢一些,因為基尼系數的計算不涉及對數。另外,因為信息熵對不純度更加敏感,所以信息熵作為指標時,決策樹的生長會更加“精細”,更加具體到我們的訓練值上,因此對于高維數據或者噪音很多的數據,信息熵很容易過擬合,基尼系數在這種情況下效果往往比較好。當然,這不是絕對的。

到這里,決策樹的基本流程其實可以簡單概括如下:

直到沒有更多的特征可用,或整體的不純度指標已經最優,決策樹就會停止生長。

l 建立一棵樹

#導入所需要的算法庫和模塊

from sklearn import tree

from sklearn.datasets import load_wine #用到sklearn自帶的數據集,是紅酒數據集

from sklearn.model_selection import train_test_split

(我用的環境是pycharm ,python3.7,macos)

#下面探索數據

wine = load_wine()

print(wine)

執行結果:

{'data': array([[1.423e+01, 1.710e+00, 2.430e+00, ..., 1.040e+00, 3.920e+00,

1.065e+03],

[1.320e+01, 1.780e+00, 2.140e+00, ..., 1.050e+00, 3.400e+00,

1.050e+03],

[1.316e+01, 2.360e+00, 2.670e+00, ..., 1.030e+00, 3.170e+00,

1.185e+03],

...,

[1.327e+01, 4.280e+00, 2.260e+00, ..., 5.900e-01, 1.560e+00,

8.350e+02],

[1.317e+01, 2.590e+00, 2.370e+00, ..., 6.000e-01, 1.620e+00,

8.400e+02],

[1.413e+01, 4.100e+00, 2.740e+00, ..., 6.100e-01, 1.600e+00,

5.600e+02]]), 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,

2, 2]), 'target_names': array(['class_0', 'class_1', 'class_2'], dtype='<U7'), 'DESCR': '.. _wine_dataset:nnWine recognition datasetn------------------------nn**Data Set Characteristics:**nn :Number of Instances: 178 (50 in each of three classes)n :Number of Attributes: 13 numeric, predictive attributes and the classn :Attribute Information:n tt- Alcoholn tt- Malic acidn tt- Ashntt- Alcalinity of ash n tt- Magnesiumntt- Total phenolsn tt- Flavanoidsn tt- Nonflavanoid phenolsn tt- Proanthocyaninsntt- Color intensityn tt- Huen tt- OD280/OD315 of diluted winesn tt- Prolinenn - class:n - class_0n - class_1n - class_2nttn :Summary Statistics:n n ============================= ==== ===== ======= =====n Min Max Mean SDn ============================= ==== ===== ======= =====n Alcohol: 11.0 14.8 13.0 0.8n Malic Acid: 0.74 5.80 2.34 1.12n Ash: 1.36 3.23 2.36 0.27n Alcalinity of Ash: 10.6 30.0 19.5 3.3n Magnesium: 70.0 162.0 99.7 14.3n Total Phenols: 0.98 3.88 2.29 0.63n Flavanoids: 0.34 5.08 2.03 1.00n Nonflavanoid Phenols: 0.13 0.66 0.36 0.12n Proanthocyanins: 0.41 3.58 1.59 0.57n Colour Intensity: 1.3 13.0 5.1 2.3n Hue: 0.48 1.71 0.96 0.23n OD280/OD315 of diluted wines: 1.27 4.00 2.61 0.71n Proline: 278 1680 746 315n ============================= ==== ===== ======= =====nn :Missing Attribute Values: Nonen :Class Distribution: class_0 (59), class_1 (71), class_2 (48)n :Creator: R.A. Fishern :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)n :Date: July, 1988nnThis is a copy of UCI ML Wine recognition datasets.nhttps://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.datannThe data is the results of a chemical analysis of wines grown in the samenregion in Italy by three different cultivators. There are thirteen differentnmeasurements taken for different constituents found in the three types ofnwine.nnOriginal Owners: nnForina, M. et al, PARVUS - nAn Extendible Package for Data Exploration, Classification and Correlation. nInstitute of Pharmaceutical and Food Analysis and Technologies,nVia Brigata Salerno, 16147 Genoa, Italy.nnCitation:nnLichman, M. (2013). UCI Machine Learning Repositoryn[http://archive.ics.uci.edu/ml]. Irvine, CA: University of California,nSchool of Information and Computer Science. nn.. topic:: Referencesnn (1) S. Aeberhard, D. Coomans and O. de Vel, n Comparison of Classifiers in High Dimensional Settings, n Tech. Rep. no. 92-02, (1992), Dept. of Computer Science and Dept. of n Mathematics and Statistics, James Cook University of North Queensland. n (Also submitted to Technometrics). nn The data was used with many others for comparing various n classifiers. The classes are separable, though only RDA n has achieved 100% correct classification. n (RDA : 100%, QDA 99.4%, LDA 98.9%, 1NN 96.1% (z-transformed data)) n (All results using the leave-one-out technique) nn (2) S. Aeberhard, D. Coomans and O. de Vel, n "THE CLASSIFICATION PERFORMANCE OF RDA" n Tech. Rep. no. 92-01, (1992), Dept. of Computer Science and Dept. of n Mathematics and Statistics, James Cook University of North Queensland. n (Also submitted to Journal of Chemometrics).n', 'feature_names': ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']}

上面可以看到輸出結果是一個字典,(大括號如果不理解,請看一些python基礎教程),有標簽,有特征。

#只是輸出特征

print(wine.data)

輸出結果:

[[1.423e+01 1.710e+00 2.430e+00 ... 1.040e+00 3.920e+00 1.065e+03]

[1.320e+01 1.780e+00 2.140e+00 ... 1.050e+00 3.400e+00 1.050e+03]

[1.316e+01 2.360e+00 2.670e+00 ... 1.030e+00 3.170e+00 1.185e+03]

...

[1.327e+01 4.280e+00 2.260e+00 ... 5.900e-01 1.560e+00 8.350e+02]

[1.317e+01 2.590e+00 2.370e+00 ... 6.000e-01 1.620e+00 8.400e+02]

[1.413e+01 4.100e+00 2.740e+00 ... 6.100e-01 1.600e+00 5.600e+02]]

#只是輸出標簽

print(wine.target) 輸出結果: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 22 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

#我們來輸出一張表看看,需要用到pandas庫

import pandas as pd

#把數據標簽和數據特征變成兩張表后,把用concat把他們結合起來,因為是橫向鏈接,所以axis=1 print(pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)) 輸出結果:0 1 2 3 4 ... 9 10 11 12 0 0 14.23 1.71 2.43 15.6 127.0 ... 5.640000 1.04 3.92 1065.0 0 1 13.20 1.78 2.14 11.2 100.0 ... 4.380000 1.05 3.40 1050.0 0 2 13.16 2.36 2.67 18.6 101.0 ... 5.680000 1.03 3.17 1185.0 0 3 14.37 1.95 2.50 16.8 113.0 ... 7.800000 0.86 3.45 1480.0 0 4 13.24 2.59 2.87 21.0 118.0 ... 4.320000 1.04 2.93 735.0 0 5 14.20 1.76 2.45 15.2 112.0 ... 6.750000 1.05 2.85 1450.0 0 6 14.39 1.87 2.45 14.6 96.0 ... 5.250000 1.02 3.58 1290.0 0 7 14.06 2.15 2.61 17.6 121.0 ... 5.050000 1.06 3.58 1295.0 0 8 14.83 1.64 2.17 14.0 97.0 ... 5.200000 1.08 2.85 1045.0 0 9 13.86 1.35 2.27 16.0 98.0 ... 7.220000 1.01 3.55 1045.0 0 10 14.10 2.16 2.30 18.0 105.0 ... 5.750000 1.25 3.17 1510.0 0 11 14.12 1.48 2.32 16.8 95.0 ... 5.000000 1.17 2.82 1280.0 0 12 13.75 1.73 2.41 16.0 89.0 ... 5.600000 1.15 2.90 1320.0 0 13 14.75 1.73 2.39 11.4 91.0 ... 5.400000 1.25 2.73 1150.0 0 14 14.38 1.87 2.38 12.0 102.0 ... 7.500000 1.20 3.00 1547.0 0 15 13.63 1.81 2.70 17.2 112.0 ... 7.300000 1.28 2.88 1310.0 0 16 14.30 1.92 2.72 20.0 120.0 ... 6.200000 1.07 2.65 1280.0 0 17 13.83 1.57 2.62 20.0 115.0 ... 6.600000 1.13 2.57 1130.0 0 18 14.19 1.59 2.48 16.5 108.0 ... 8.700000 1.23 2.82 1680.0 0 19 13.64 3.10 2.56 15.2 116.0 ... 5.100000 0.96 3.36 845.0 0 20 14.06 1.63 2.28 16.0 126.0 ... 5.650000 1.09 3.71 780.0 0 21 12.93 3.80 2.65 18.6 102.0 ... 4.500000 1.03 3.52 770.0 0 22 13.71 1.86 2.36 16.6 101.0 ... 3.800000 1.11 4.00 1035.0 0 23 12.85 1.60 2.52 17.8 95.0 ... 3.930000 1.09 3.63 1015.0 0 24 13.50 1.81 2.61 20.0 96.0 ... 3.520000 1.12 3.82 845.0 0 25 13.05 2.05 3.22 25.0 124.0 ... 3.580000 1.13 3.20 830.0 0 26 13.39 1.77 2.62 16.1 93.0 ... 4.800000 0.92 3.22 1195.0 0 27 13.30 1.72 2.14 17.0 94.0 ... 3.950000 1.02 2.77 1285.0 0 28 13.87 1.90 2.80 19.4 107.0 ... 4.500000 1.25 3.40 915.0 0 29 14.02 1.68 2.21 16.0 96.0 ... 4.700000 1.04 3.59 1035.0 0 .. ... ... ... ... ... ... ... ... ... ... .. 148 13.32 3.24 2.38 21.5 92.0 ... 8.420000 0.55 1.62 650.0 2 149 13.08 3.90 2.36 21.5 113.0 ... 9.400000 0.57 1.33 550.0 2 150 13.50 3.12 2.62 24.0 123.0 ... 8.600000 0.59 1.30 500.0 2 151 12.79 2.67 2.48 22.0 112.0 ... 10.800000 0.48 1.47 480.0 2 152 13.11 1.90 2.75 25.5 116.0 ... 7.100000 0.61 1.33 425.0 2 153 13.23 3.30 2.28 18.5 98.0 ... 10.520000 0.56 1.51 675.0 2 154 12.58 1.29 2.10 20.0 103.0 ... 7.600000 0.58 1.55 640.0 2 155 13.17 5.19 2.32 22.0 93.0 ... 7.900000 0.60 1.48 725.0 2 156 13.84 4.12 2.38 19.5 89.0 ... 9.010000 0.57 1.64 480.0 2 157 12.45 3.03 2.64 27.0 97.0 ... 7.500000 0.67 1.73 880.0 2 158 14.34 1.68 2.70 25.0 98.0 ... 13.000000 0.57 1.96 660.0 2 159 13.48 1.67 2.64 22.5 89.0 ... 11.750000 0.57 1.78 620.0 2 160 12.36 3.83 2.38 21.0 88.0 ... 7.650000 0.56 1.58 520.0 2 161 13.69 3.26 2.54 20.0 107.0 ... 5.880000 0.96 1.82 680.0 2 162 12.85 3.27 2.58 22.0 106.0 ... 5.580000 0.87 2.11 570.0 2 163 12.96 3.45 2.35 18.5 106.0 ... 5.280000 0.68 1.75 675.0 2 164 13.78 2.76 2.30 22.0 90.0 ... 9.580000 0.70 1.68 615.0 2 165 13.73 4.36 2.26 22.5 88.0 ... 6.620000 0.78 1.75 520.0 2 166 13.45 3.70 2.60 23.0 111.0 ... 10.680000 0.85 1.56 695.0 2 167 12.82 3.37 2.30 19.5 88.0 ... 10.260000 0.72 1.75 685.0 2 168 13.58 2.58 2.69 24.5 105.0 ... 8.660000 0.74 1.80 750.0 2 169 13.40 4.60 2.86 25.0 112.0 ... 8.500000 0.67 1.92 630.0 2 170 12.20 3.03 2.32 19.0 96.0 ... 5.500000 0.66 1.83 510.0 2 171 12.77 2.39 2.28 19.5 86.0 ... 9.899999 0.57 1.63 470.0 2 172 14.16 2.51 2.48 20.0 91.0 ... 9.700000 0.62 1.71 660.0 2 173 13.71 5.65 2.45 20.5 95.0 ... 7.700000 0.64 1.74 740.0 2 174 13.40 3.91 2.48 23.0 102.0 ... 7.300000 0.70 1.56 750.0 2 175 13.27 4.28 2.26 20.0 120.0 ... 10.200000 0.59 1.56 835.0 2 176 13.17 2.59 2.37 20.0 120.0 ... 9.300000 0.60 1.62 840.0 2 177 14.13 4.10 2.74 24.5 96.0 ... 9.200000 0.61 1.60 560.0 2 最后一列是標簽,前面列都是我們的特征。

#查看特征值

print(wine.feature_names)

輸出結果:

['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']

#輸出標簽的名字

print(wine.target_names)

輸出結果:

['class_0' 'class_1' 'class_2']

#split方法是把訓練集分拆為兩個數據集,一個是測試集,一個是訓練集,size=0.3意思是說我們用30%是測試集,70%作為我們的訓練集,

xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)

#輸出訓練集

print(xtrain.shape)

輸出結果:

(124,13)

意思是124行,13個標簽

#輸出原有的數據集

print(wine.data.shape)

輸出結果:

(178,13)

上面數據說明178的百分之30,就是124.

#下面建模,可以參考前面的建模流程

clf=tree.DecisionTreeClassifier(criterion="entropy") clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽 score = clf.score(xtest,ytest) #score是針對上面模型評估精確度print(score)

輸出結果:

0.9444444444444444 #結果還不錯

#下面要用到graphviz這個庫,如果不熟悉可以參看我另外一篇文章(機器學習之數據的可視化:https://zhuanlan.zhihu.com/p/58839149)

import graphviz# 自定義特征名字 feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸']#class_name我們知道有三類,就賦值為["琴酒", "雪莉", "貝爾摩德"] dot_data = tree.export_graphviz(clf, feature_names=feature_name,class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True,rounded=True) # filled=True 填充顏色 # rounded=True 圓弧矩形graph = graphviz.Source(dot_data) graph.view() 輸出結果:

注意:export_graphviz是如何影響這里輸出的樹呢? 比如說不輸入feature_names=feature_name參數,代碼修改如下: dot_data = tree.export_graphviz(clf, , class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True,rounded=True) 輸出結果:

可以看到最上面的節點寫的是x[6],不是特征名稱只是數組索引了, 這是因為feature_names中保存的是中文特征名稱。 Class_names影響的是標簽的中文名稱,filled是所有的節點用顏色標示, round參數影響輸出節點為是否為方形。 技巧: 在寫代碼過程中,如果有多個參數,建議把逗號寫在前面,如: dot_data = tree.export_graphviz(clf, class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True ,rounded=True) 這樣注釋代碼會很便捷。 #下面我們繼續探索 print(clf.feature_importances_)輸出結果: [0.02010349 0. 0. 0. 0. 0.100378690. 0. 0. 0.28330831 0.03496086 0.1192440.44200465] 上面的特征中說明只有6個有數據,只有這6個特征用到了,數值越大越重要,就是對上面的樹越重要

#特征重要性和特征對應起來,用*zip函數,*zip()函數是zip()函數的逆過程,將zip對象變成原先組合前的數據。

print(*zip(feature_name,clf.feature_importances_)) 輸出的結果:

('酒精', 0.08104609046276126) ('蘋果酸', 0.0) ('灰', 0.0) ('灰的堿性', 0.0) ('鎂', 0.0) ('總酚', 0.0) ('類黃酮', 0.45851091902235463) ('非黃烷類酚類', 0.0) ('花青素', 0.0) ('顏 色強度', 0.09440490422199845) ('色調', 0.0) ('od280/od315稀釋葡萄酒', 0.0) ('脯氨酸', 0.3660380862928856)

從上面的數據看出,我們可以把那些0的特征樹去掉,也不會對結果有任何影響,對于上面的樹影響最大的,數值也會越大。

通過上面的實際例子,我們已經在只了解一個參數的情況下,建立一棵完整的決策樹,但是由于score會在某個值附近波動,結果畫出的樹會每次都不同,

clf=tree.DecisionTreeClassifier(criterion="entropy")

clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽

score = clf.score(xtest,ytest) #score是針對上面模型評估精確度

上面這段代碼多次運行你也會發現結果會不同,上面的測試集和訓練集是隨機分離的。

其實,無論決策樹模型如何進化,在分枝上的本質都還是追求某個不純度相關的指標的優化,而正如我們提到的,不純度是基于節點來計算的,也就是說,決策樹在建樹時,是靠優化節點來追求一棵優化的樹,但最優的節點能夠保證最優的樹嗎?集成算法被用來解決這個問題:sklearn表示,既然一棵樹不能保證最優,那就建更多的不同的樹,然后從中取最好的。怎樣從一組數據集中建不同的樹?在每次分枝時,不從使用全部特征,而是隨機選取一部分特征,從中選取不純度相關指標最優的作為分枝用的節點。這樣,每次生成的樹也就不同了。

如果要讓數據輸出很穩定,可以用random_state這個參數,

clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=30)

clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽

score = clf.score(xtest,ytest) #score是針對上面模型評估精確度

print(score)

決策樹是帶有隨機性的,雖然很多人可能沒有意識到這個問題,sklearn官網也是用鶯尾花作為案例,但是鶯尾花只有4個特征,在如何隨機也是生成不同的樹概率也是非常小的,導致很多人沒有意識到這個問題。

B. 重要參數: random_state & splitter

random_state用來設置分枝中的隨機模式的參數,默認None,在高維度時隨機性會表現更明顯,低維度的數據(比如鳶尾花數據集),隨機性幾乎不會顯現。輸入任意整數,會一直長出同一棵樹,讓模型穩定下來。

splitter也是用來控制決策樹中的隨機選項的,有兩種輸入值,輸入”best",決策樹在分枝時雖然隨機,但是還是會優先選擇更重要的特征進行分枝(重要性可以通過屬性feature_importances_查看),輸入“random",決策樹在分枝時會更加隨機,樹會因為含有更多的不必要信息而更深更大,并因這些不必要信息而降低對訓練集的擬合。這也是防止過擬合的一種方式。當你預測到你的模型會過擬合,用這兩個參數來幫助你降低樹建成之后過擬合的可能性。當然,樹一旦建成,我們依然是使用剪枝參數來防止過擬合。

代碼如下:

from sklearn import tree

from sklearn.datasets import load_wine

from sklearn.model_selection import train_test_split

wine = load_wine()

xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)

clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")

clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽

score = clf.score(xtest,ytest) #score是針對上面模型評估精確度

print(score)

import graphviz

feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸']

dot_data = tree.export_graphviz(clf

, feature_names=feature_name

, class_names=["琴酒", "雪莉", "貝爾摩德"]

, filled=True

, rounded=True

)

graph = graphviz.Source(dot_data)

graph.view()

輸出結果:

你會發現層次加深,說明數據隨機性非常友好,提升了模型的效果。如果有效的參數就保留,因為我們永遠追求的是最好的結果,最高的分數。

C. 剪枝參數

在不加限制的情況下,一棵決策樹會生長到衡量不純度的指標最優,或者沒有更多的特征可用為止。這樣的決策樹往往會過擬合,過擬合這就是說,它會在訓練集上表現很好,在測試集上卻表現糟糕。我們收集的樣本數據不可能和整體的狀況完全一致,因此當一棵決策樹對訓練數據有了過于優秀的解釋性,它找出的規則必然包含了訓練樣本中的噪聲,并使它對未知數據的擬合程度不足。

下面我們訓練集訓練出來的樹對測試數據集的擬合程度,代碼如下:

from sklearn import tree

from sklearn.datasets import load_wine

from sklearn.model_selection import train_test_split

wine = load_wine()

xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)

clf=tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")

clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽

score = clf.score(xtest,ytest) #score是針對上面模型評估精確度

print(score)

import graphviz

feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸']

dot_data = tree.export_graphviz(clf

, feature_names=feature_name

, class_names=["琴酒", "雪莉", "貝爾摩德"]

, filled=True

, rounded=True

)

graph = graphviz.Source(dot_data)

#graph.view()

score_train = clf.score(xtrain,ytrain)

print(score_train)

輸出結果:

1.0

結果說明精確性是1.0,這是一個過擬合的狀況,因為在訓練集上的效果明顯比測試集效果好,我們測試集上的分數有94%,如果這個訓練樹在測試也好,在訓練集也好,就是很完美了。我們應該冷靜看這個數據結果,因為這是用的紅酒數據集,在現實生活中不可能有這么高的分數數據集。

為了讓決策樹有更好的泛化性,我們要對決策樹進行剪枝。剪枝策略對決策樹的影響巨大,正確的剪枝策略是優化決策樹算法的核心。sklearn為我們提供了不同的剪枝策略:

1) max_depth

限制樹的最大深度,超過設定深度的樹枝全部剪掉

這是用得最廣泛的剪枝參數,在高維度低樣本量時非常有效。決策樹多生長一層,對樣本量的需求會增加一倍,所以限制樹深度能夠有效地限制過擬合。在集成算法中也非常實用。實際使用時,建議從=3開始嘗試,看看擬合的效果再決定是否增加設定深度。

2) min_samples_leaf

min_samples_leaf 限定,一個節點在分枝后的每個子節點都必須包含至少min_samples_leaf個訓練樣本,否則分枝就不會發生,或者,分枝會朝著滿足每個子節點都包含min_samples_leaf個樣本的方向去發生

一般搭配max_depth使用,在回歸樹中有神奇的效果,可以讓模型變得更加平滑。這個參數的數量設置得太小會引起過擬合,設置得太大就會阻止模型學習數據。一般來說,建議從=5開始使用。如果葉節點中含有的樣本量變化很大,建議輸入浮點數作為樣本量的百分比來使用。同時,這個參數可以保證每個葉子的最小尺寸,可以在回歸問題中避免低方差,過擬合的葉子節點出現。對于類別不多的分類問題,=1通常就是最佳選擇。

3) min_samples_split

min_samples_split限定,一個節點必須要包含至少min_samples_split個訓練樣本,這個節點才允許被分枝,否則分枝就不會發生。

如果一個樣本包20個樣本,我們在不限定的情況下會不斷分下去的,如果設定min_samples_split=15,那么這個節點就不會分了。

執行下面代碼,設置max_depth=3:

from sklearn import tree from sklearn.datasets import load_wine from sklearn.model_selection import train_test_splitwine = load_wine()xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)clf=tree.DecisionTreeClassifier(criterion="entropy" ,random_state=30,splitter="random" ,max_depth=3) clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽 score = clf.score(xtest,ytest) #score是針對上面模型評估精確度 print(score)import graphviz feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮' ,'非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸'] dot_data = tree.export_graphviz(clf, feature_names=feature_name, class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True , rounded=True )graph = graphviz.Source(dot_data) graph.view() 輸出結果: 0.7962962962962963

輸出只有三層,三層之外的全部被砍掉了,上面的分數來看數據的精準性下降了很多。 限制了過擬合之后,沒有提升它在測試上的表現 #設置min_samples_leaf,之后看看表現 from sklearn import tree from sklearn.datasets import load_wine from sklearn.model_selection import train_test_splitwine = load_wine()xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)clf=tree.DecisionTreeClassifier(criterion="entropy" ,random_state=30,splitter="random" #,max_depth=3 ,min_samples_leaf=10#,min_samples_split=70 ) clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽 score = clf.score(xtest,ytest) #score是針對上面模型評估精確度 print(score)import graphviz feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚' ,'類黃酮','非黃烷類酚類','花青素','顏 色強度' ,'色調','od280/od315稀釋葡萄酒','脯氨酸'] dot_data = tree.export_graphviz(clf, feature_names=feature_name, class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True , rounded=True )graph = graphviz.Source(dot_data) graph.view()輸出結果: 0.8148148148148148

每個節點的樣本量samples都是大于10的。 #下面我們只允許有70的樣本允許分割 from sklearn import tree from sklearn.datasets import load_wine from sklearn.model_selection import train_test_splitwine = load_wine()xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)clf=tree.DecisionTreeClassifier(criterion="entropy" ,random_state=30,splitter="random" ,max_depth=3,min_samples_leaf=10,min_samples_split=70) clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽 score = clf.score(xtest,ytest) #score是針對上面模型評估精確度 print(score)import graphviz feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸'] dot_data = tree.export_graphviz(clf, feature_names=feature_name, class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True , rounded=True )graph = graphviz.Source(dot_data) graph.view()score_train = clf.score(xtrain,ytrain) print(score_train)輸出結果:

可以看出來樣本量只有大于70的才允許分割了。上圖中會看到48小于70所以不分割了節點了。

注意:每個人的樹不一樣,不要追求運行結果完全一致。

4) max_features

一般max_depth使用,用作樹的”精修“

max_features限制分枝時考慮的特征個數,超過限制個數的特征都會被舍棄。和max_depth異曲同工,max_features是用來限制高維度數據的過擬合的剪枝參數,但其方法比較暴力,是直接限制可以使用的特征數量而強行使決策樹停下的參數,在不知道決策樹中的各個特征的重要性的情況下,強行設定這個參數可能會導致模型學習不足。如果希望通過降維的方式防止過擬合,建議使用PCA,ICA或者特征選擇模塊中的降維算法。

5) min_impurity_decrease

min_impurity_decrease限制信息增益的大小,信息增益小于設定數值的分枝不會發生。這是在0.19版本種更新的功能,在0.19版本之前時使用min_impurity_split。

D. 確認最優的剪枝參數

那具體怎么來確定每個參數填寫什么值呢?這時候,我們就要使用確定超參數的曲線來進行判斷了,繼續使用我們已經訓練好的決策樹模型clf。超參數的學習曲線,是一條以超參數的取值為橫坐標,模型的度量指標為縱坐標的曲線,它是用來衡量不同超參數取值下模型的表現的線。在我們建好的決策樹里,我們的模型度量指標就是score。

#輸出圖形

from sklearn import tree from sklearn.datasets import load_wine from sklearn.model_selection import train_test_splitwine = load_wine()xtrain,xtest,ytrain,ytest = train_test_split(wine.data,wine.target,test_size=0.3)clf=tree.DecisionTreeClassifier(criterion="entropy" ,random_state=30,splitter="random" ,max_depth=3,min_samples_leaf=10,min_samples_split=70) clf=clf.fit(xtrain,ytrain) #把訓練數據集放入到分類器中,fit來尋找相應標簽 score = clf.score(xtest,ytest) #score是針對上面模型評估精確度 print(score)import graphviz feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚' ,'類黃酮','非黃烷類酚類','花青素','顏 色強度','色調','od280/od315稀釋葡萄酒','脯氨酸'] dot_data = tree.export_graphviz(clf, feature_names=feature_name, class_names=["琴酒", "雪莉", "貝爾摩德"], filled=True , rounded=True )graph = graphviz.Source(dot_data) graph.view()import matplotlib.pyplot as plt test = [] for i in range(10):clf=tree.DecisionTreeClassifier(max_depth=i+1,criterion="entropy" ,random_state=30)clf=clf.fit(xtrain,ytrain)score_train = clf.score(xtrain, ytrain)test.append(score) plt.plot(range(1,11),test,color='red',label='max_depth') plt.legend() plt.show()

輸出結果:

橫坐標是每次評估模型打分的結果,縱坐標是次數,圖形說明,樹深度到3的時候就已經達到極限了。我們選擇樹深度就是3,因為從上圖可以看出后續在有更深的深度,數據集也不會有更好的表現。

思考:

剪枝參數一定能夠提升模型在測試集上的表現嗎? - 調參沒有絕對的答案,一切都是看數據本身。

這么多參數,一個個畫學習曲線?

無論如何,剪枝參數的默認值會讓樹無盡地生長,這些樹在某些數據集上可能非常巨大,對內存的消耗。所以如果你手中的數據集非常大,你已經預測到無論如何你都是要剪枝的,那提前設定這些參數來控制樹的復雜性和大小會比較好。

思考:

剪枝參數一定會提升模型在測試集上的表現么?調參是沒有答案的,一起都要看數據本身。

這么多參數,一個一個花學習曲線么?

無論如何,剪枝參數默認值是不會無盡生長的,這些書在某些數據街上可能非常巨大,對內存消耗。搜一如果你手中的數據集非常大,已經預測到你要剪枝,那體現設定這些參數來控制樹的復雜性和大小很有必要。

E. 目標權重參數

1) class_weight

完成樣本標簽平衡的參數。樣本不平衡是指在一組數據集中,標簽的一類天生占有很大的比例。比如說,在銀行要判斷“一個辦了信用卡的人是否會違約”,就是是vs否(1%:99%)的比例。這種分類狀況下,即便模型什么也不做,全把結果預測成“否”,正確率也能有99%。因此我們要使用class_weight參數對樣本標簽進行一定的均衡,給少量的標簽更多的權重,讓模型更偏向少數類,向捕獲少數類的方向建模。該參數默認None,此模式表示自動給與數據集中的所有標簽相同的權重。

2) min_weight_fraction_leaf

有了權重之后,樣本量就不再是單純地記錄數目,而是受輸入的權重影響了,因此這時候剪枝,就需要搭配min_ weight_fraction_leaf這個基于權重的剪枝參數來使用。另請注意,基于權重的剪枝參數(例如min_weight_ fraction_leaf)將比不知道樣本權重的標準(比如min_samples_leaf)更少偏向主導類。如果樣本是加權的,則使用基于權重的預修剪標準來更容易優化樹結構,這確保葉節點至少包含樣本權重的總和的一小部分。

F. 重要屬性和接口

屬性是在模型訓練之后,能夠調用查看的模型的各種性質。對決策樹來說,最重要的是feature_importances_,能夠查看各個特征對模型的重要性。

sklearn中許多算法的接口都是相似的,比如說我們之前已經用到的fit和score,幾乎對每個算法都可以使用。除了這兩個接口之外,決策樹最常用的接口還有apply和predict。apply中輸入測試集返回每個測試樣本所在的葉子節點的索引,predict輸入測試集返回每個測試樣本的標簽。返回的內容一目了然并且非常容易,大家感興趣可以自己下去試試看。

總結:

七個參數:Criterion,兩個隨機性相關的參數(random_state,splitter),四個剪枝參數(max_depth, ,min_sample_leaf,max_feature,min_impurity_decrease)

一個屬性:feature_importances_

四個接口:fit,score,apply,predict

有了這些知識,基本上分類樹的使用大家都能夠掌握了,接下來再到實例中去磨練就好。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的boost原理与sklearn源码_机器学习sklearn系列之决策树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。