[Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)
歡迎大家來到“Python從零到壹”,在這里我將分享約200篇Python系列文章,帶大家一起去學習和玩耍,看看Python這個有趣的世界。所有文章都將結合案例、代碼和作者的經驗講解,真心想把自己近十年的編程經驗分享給大家,希望對您有所幫助,文章中不足之處也請海涵。Python系列整體框架包括基礎語法10篇、網絡爬蟲30篇、可視化分析10篇、機器學習20篇、大數據分析20篇、圖像識別30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的關注、點贊和轉發就是對秀璋最大的支持,知識無價人有情,希望我們都能在人生路上開心快樂、共同成長。
前一篇文章講述了聚類算法的原理知識級案例,包括K-Means聚類、BIRCH算法、PCA降維聚類、均值漂移聚類、文本聚類等。。本文將詳細講解分類算法的原理知識級案例,包括決策樹、KNN、SVM,并通過詳細的分類對比實驗和可視化邊界分析與大家總結。四萬字基礎文章,希望對您有所幫助。
文章目錄
- 一.分類
- 1.分類模型
- 2.常見分類算法
- 3.回歸、聚類和分類的區別
- 4.性能評估
- 二.決策樹
- 1.算法實例描述
- 2.DTC算法
- 3.決策樹分析鳶尾花
- 4.數據集劃分及分類評估
- 5.區域劃分對比
- 三.KNN分類算法
- 1.算法實例描述
- 2.KNeighborsClassifier
- 3.KNN分析紅酒類型
- 四.SVM分類算法
- 1.SVM基礎知識
- 2.SVM分析紅酒數據
- 3.優化SVM分析紅酒數據集
- 五.各模型分類對比實驗
- 1.決策樹
- 2.KNN
- 3.SVM
- 4.邏輯回歸
- 5.樸素貝葉斯
- 6.隨機森林
- 7.AdaBoost
- 8.GradientBoosting
- 9.實驗結果對比
- 六.本章小結
下載地址:
- https://github.com/eastmountyxz/Python-zero2one
前文賞析:
第一部分 基礎語法
- [Python從零到壹] 一.為什么我們要學Python及基礎語法詳解
- [Python從零到壹] 二.語法基礎之條件語句、循環語句和函數
- [Python從零到壹] 三.語法基礎之文件操作、CSV文件讀寫及面向對象
第二部分 網絡爬蟲
- [Python從零到壹] 四.網絡爬蟲之入門基礎及正則表達式抓取博客案例
- [Python從零到壹] 五.網絡爬蟲之BeautifulSoup基礎語法萬字詳解
- [Python從零到壹] 六.網絡爬蟲之BeautifulSoup爬取豆瓣TOP250電影詳解
- [Python從零到壹] 七.網絡爬蟲之Requests爬取豆瓣電影TOP250及CSV存儲
- [Python從零到壹] 八.數據庫之MySQL基礎知識及操作萬字詳解
- [Python從零到壹] 九.網絡爬蟲之Selenium基礎技術萬字詳解(定位元素、常用方法、鍵盤鼠標操作)
- [Python從零到壹] 十.網絡爬蟲之Selenium爬取在線百科知識萬字詳解(NLP語料構造必備技能)
第三部分 數據分析和機器學習
- [Python從零到壹] 十一.數據分析之Numpy、Pandas、Matplotlib和Sklearn入門知識萬字詳解(1)
- [Python從零到壹] 十二.機器學習之回歸分析萬字總結全網首發(線性回歸、多項式回歸、邏輯回歸)
- [Python從零到壹] 十三.機器學習之聚類分析萬字總結全網首發(K-Means、BIRCH、層次聚類、樹狀聚類)
- [Python從零到壹] 十四.機器學習之分類算法三萬字總結全網首發(決策樹、KNN、SVM、分類算法對比)
作者新開的“娜璋AI安全之家”將專注于Python和安全技術,主要分享Web滲透、系統安全、人工智能、大數據分析、圖像識別、惡意代碼檢測、CVE復現、威脅情報分析等文章。雖然作者是一名技術小白,但會保證每一篇文章都會很用心地撰寫,希望這些基礎性文章對你有所幫助,在Python和安全路上與大家一起進步。
分類(Classification)屬于有監督學習(Supervised Learning)中的一類,它是數據挖掘、機器學習和數據科學中一個重要的研究領域。分類模型類似于人類學習的方式,通過對歷史數據或訓練集的學習得到一個目標函數,再用該目標函數預測新數據集的未知屬性。本章主要講述分類算法基礎概念,并結合決策樹、KNN、SVM分類算法案例分析各類數據集,從而讓讀者學會使用Python分類算法分析自己的數據集,研究自己領域的知識,從而創造價值。
一.分類
1.分類模型
與前面講述的聚類模型類似,分類算法的模型如圖1所示。它主要包括兩個步驟:
- 訓練。給定一個數據集,每個樣本包含一組特征和一個類別信息,然后調用分類算法訓練分類模型。
- 預測。利用生成的模型或函數對新的數據集(測試集)進行分類預測,并判斷其分類后的結果,并進行可視化繪圖顯示。
通常為了檢驗學習模型的性能,會使用校驗集。數據集會被分成不相交的訓練集和測試集,訓練集用來構造分類模型,測試集用來檢驗多少類標簽被正確分類。
下面舉一個分類實例進行講解。假設存在一個垃圾分類系統,將郵件劃分為“垃圾郵件”和“非垃圾郵件”,現在有一個帶有是否是垃圾郵件類標的訓練集,然后訓練一個分類模型,對測試集進行預測,步驟如下:
- (1) 分類模型對訓練集進行訓練,判斷每行數據是正向數據還是負向數據,并不斷與真實的結果進行比較,反復訓練模型,直到模型達到某個狀態或超出某個閾值,模型訓練結束。
- (2) 利用該模型對測試集進行預測,判斷其類標是“垃圾郵件”還是“非垃圾郵件”,并計算出該分類模型的準確率、召回率和F特征值。
經過上述步驟,當收到一封新郵件時,我們可以根據它郵件的內容或特征,判斷其是否是垃圾郵件,這為我們提供了很大的便利,能夠防止垃圾郵件信息的騷擾。
2.常見分類算法
監督式學習包括分類和回歸。其中常見的分類算法包括樸素貝葉斯分類器、決策樹、K最近鄰分類算法、支持向量機、神經網絡和基于規則的分類算法等,同時還有用于組合單一類方法的集成學習算法,如Bagging和Boosting等。
(1) 樸素貝葉斯分類器
樸素貝葉斯分類器(Naive Bayes Classifier,簡稱NBC)發源于古典數學理論,有著堅實的數學基礎和穩定的分類效率。該算法是利用Bayes定理來預測一個未知類別的樣本屬于各個類別的可能性,選擇其中可能性最大的一個類別作為該樣本的最終類別。其中,樸素貝葉斯(Naive Bayes)法是基于貝葉斯定理與特征條件獨立假設的方法 ,是一類利用概率統計知識進行分類的算法,該算法被廣泛應用的模型稱為樸素貝葉斯模型(Naive Bayesian Model,簡稱NBM)。
根據貝葉斯定理,對于一個分類問題,給定樣本特征x,樣本屬于類別y的概率如下:
其中p(x)表示x事件發生的概率,p(y)表示y事件發生的概率,p(x|y)表示事件y發生后事件x發生的概率。由于貝葉斯定理的成立本身需要一個很強的條件獨立性假設前提,而此假設在實際情況中經常是不成立的,因而其分類準確性就會下降,同時它對缺失的數據不太敏感。本書沒有詳細介紹樸素貝葉斯分類實例,希望讀者下來自行研究學習。
(2) 決策樹算法
決策樹(Decision Tree)是以實例為基礎的歸納學習(Inductive Learning)算法,它是對一組無次序、無規則的實例建立一棵決策判斷樹,并推理出樹形結果的分類規則。決策樹作為分類和預測的主要技術之一,其構造目的是找出屬性和類別間的關系,用它來預測未知數據的類別。該算法采用自頂向下的遞歸方式,在決策樹的內部節點進行屬性比較,并根據不同屬性值判斷從該節點向下的分支,在決策樹的葉子節點得到反饋的結果。
決策樹算法根據數據的屬性采用樹狀結構建立決策模型,常用來解決分類和回歸問題。常見的算法包括:分類及回歸樹、ID3 、C4.5、隨機森林等。
(3) K最近鄰分類算法
K最近鄰(K-Nearest Neighbor,簡稱KNN)分類算法是一種基于實例的分類方法,是數據挖掘分類技術中最簡單常用的方法之一。所謂K最近鄰,就是尋找K個最近的鄰居,每個樣本都可以用它最接近的K個鄰居來代表。該方法需要找出與未知樣本X距離最近的K個訓練樣本,看這K個樣本中屬于哪一類的數量多,就把未知樣本X歸為那一類。
K-近鄰方法是一種懶惰學習方法,它存放樣本,直到需要分類時才進行分類,如果樣本集比較復雜,可能會導致很大的計算開銷,因此無法應用到實時性很強的場合。
(4) 支持向量機
支持向量機(Support Vector Machine,簡稱SVM)是數學家Vapnik等人根據統計學習理論提出的一種新的學習方法,其基本模型定義為特征空間上間隔最大的線性分類器,其學習策略是間隔最大化,最終轉換為一個凸二次規劃問題的求解。
SVM算法的最大特點是根據結構風險最小化準則,以最大化分類間隔構造最優分類超平面來提高學習機的泛化能力,較好地解決了非線性、高維數、局部極小點等問題,同時維數大于樣本數時仍然有效,支持不同的內核函數(線性、多項式、s型等)。
(5) 神經網絡
神經網絡(Neural Network,也稱之為人工神經網絡)算法是80年代機器學習界非常流行的算法,不過在90年代中途衰落。現在又隨著“深度學習”之勢重新火熱,成為最強大的機器學習算法之一。圖2是一個神經網絡的例子,包括輸入層、隱藏層和輸出層。
人工神經網絡(Artificial Neural Network,簡稱ANN)是一種模仿生物神經網絡的結構和功能的數學模型或計算模型。在這種模型中,大量的節點或稱“神經元”之間相互聯接構成網絡,即“神經網絡”,以達到處理信息的目的。神經網絡通常需要進行訓練,訓練的過程就是網絡進行學習的過程,訓練改變了網絡節點的連接權的值使其具有分類的功能,經過訓練的網絡就可用于對象的識別。
常見的人工神經網絡有BP(Back Propagation)神經網絡、徑向基RBF神經網絡、Hopfield神經網絡、隨機神經網絡(Boltzmann機)、深度神經網絡DNN、卷積神經網絡CNN等。
(6) 集成學習
集成學習(Ensemble Learning)是一種機器學習方法,它使用一系列學習器進行學習,并使用某種規則把各個學習結果進行整合從而獲得比單個學習器更好的學習效果。由于實際應用的復雜性和數據的多樣性往往使得單一的分類方法不夠有效,因此,學者們對多種分類方法的融合即集成學習進行了廣泛的研究,它已儼然成為了國際機器學習界的研究熱點。
集成學習試圖通過連續調用單個的學習算法,獲得不同的基學習器,然后根據規則組合這些學習器來解決同一個問題,可以顯著的提高學習系統的泛化能力。組合多個基學習器主要采用投票(加權)的方法,常見的算法有裝袋(Bagging)、推進(Boosting)等。
3.回歸、聚類和分類的區別
在第12篇文章中我們詳細講解了回歸分析,13篇詳細講解了聚類分析,本章著重講解分類分析,而它們之間究竟存在什么區別和關系呢?
- 分類(Classification)和回歸(Regression)都屬于監督學習,它們的區別在于:回歸是用來預測連續的實數值,比如給定了房屋面積,來預測房屋價格,返回的結果是房屋價格;而分類是用來預測有限的離散值,比如判斷一個人是否患糖尿病,返回值是“是”或“否”。即明確對象屬于哪個預定義的目標類,預定義的目標類是離散時為分類,連續時為回歸。
- 分類屬于監督學習,而聚類屬于無監督學習,其主要區別是:訓練過程中是否知道結果或是否存在類標。比如讓小孩給水果分類,給他蘋果時告訴他這是蘋果,給他桃子時告訴他這是桃子,經過反復訓練學習,現在給他一個新的水果,問他“這是什么?”,小孩對其進行回答判斷,整個過程就是一個分類學習的過程,在訓練小孩的過程中反復告訴他對應水果真實的類別。而如果采用聚類算法對其進行分析,則是給小孩一堆水果,包括蘋果、橘子、桃子,小孩開始不知道需要分類的水果是什么,讓小孩自己對水果進行分類,按照水果自身的特征進行歸納和判斷,小孩分成三堆后,再給小孩新的水果,比如是蘋果,小孩把它放到蘋果堆的整個過程稱之為聚類學習過程。
總之,分類學習在訓練過程中是知道對應的類標結果的,即訓練集是存在對應的類標的;而聚類學習在訓練過程中不知道數據對應的結果,根據數據集的特征特點,按照“物以類聚”的方法,將具有相似屬性的數據聚集在一起。
4.性能評估
分類算法有很多,不同的分類算法又有很多不同的變種,不同的分類算法有不同的特點,在不同的數據集上表現的效果也不同,我們需要根據特定的任務來選擇對應的算法。選擇好了分類算法之后,我們如何評價一個分類算法的好壞呢?
本書主要采用精確率(Precision)、召回率(Recall)和F值(F-measure或F-score)來評價分類算法。
(1) 精確率(Precision)和召回率(Recall)
精確率定義為檢索出相關文檔數與檢索出的文檔總數的比率,衡量的是檢索系統的查準率;召回率定義為檢索出的相關文檔數和文檔庫中所有相關文檔數的比率,衡量的是檢索系統的查全率。公式如下:
其中,參數N表示實驗結果中正確識別出的聚類類簇數,S表示實驗結果中實際識別出的聚類類簇數,T表示數據集中所有真實存在的聚類相關類簇數。
(2) F值(F-measure或F-score)
精確率和召回率兩個評估指標在特定的情況下是相互制約的,因而很難使用單一的評價指標來衡量實驗的效果。F-值是準確率和召回率的調和平均值,它可作為衡量實驗結果的最終評價指標,F值更接近兩個數中較小的那個。F值指的計算公式如下公式所示:
(3) 其他指標
其他常用的分類算法的評價指標包括:
- 準確率(Accuracy)
- 錯誤率(Error Rate)
- 靈敏度(Sensitive)
- 特效度(Specificity)
- ROC曲線
- …
二.決策樹
1.算法實例描述
下面通過一個招聘的案例講述決策樹的基本原理及過程。假設一位程序員與面試官的初次面試的簡單對話,我們利用決策樹分類的思想來構建一棵樹形結構。對話如下:
面試官:多大年紀了? 程序員:25歲。 面試官:本科是不是已經畢業呢? 程序員:是的。 面試官:編程技術厲不厲害? 程序員:不算太厲害,中等水平。 面試官:熟悉Python語言嗎? 程序員:熟悉的,做過數據挖掘相關應用。 面試官:可以的,你通過了。這個面試的決策過程就是典型的分類樹決策。相當于通過年齡、學歷、編程技術和是否熟悉Python語言將程序員初試分為兩個類別:通過和不通過。假設這個面試官對程序員的要求是30歲以下、學歷本科以上并且是編程厲害或熟悉Pyhon語言中等以上編程技術的程序員,這個面試官的決策邏輯過程用圖3表示。
第二個實例是典型的決策樹判斷蘋果的例子,假設存在4個樣本,2個屬性判斷是否是好蘋果,其中第二列1表示蘋果很紅,0表示蘋果不紅;第三列1表示蘋果很大,0表示蘋果很小;第4列結果1表示蘋果好吃,0表示蘋果不好吃。
樣本中有2個屬性,即蘋果紅色屬性和蘋果大小屬性。這里紅蘋果用A0表示,大蘋果用A1表示,構建的決策樹如圖19.4所示。圖中最頂端有四個蘋果(1、2、3、4),然后它將顏色紅的蘋果放在一邊(A0=紅),顏色不紅的蘋果放在另一邊,其結果為1、2是紅蘋果,3、4是不紅的蘋果;再根據蘋果的大小進行劃分,將大的蘋果判斷為好吃的(A1=大),最終輸出結果在圖中第三層顯示,其中1和3是好吃的蘋果,2和4是不好吃的蘋果,該實例表明蘋果越大越好吃。
決策樹算法根據數據的屬性并采用樹狀結構構建決策模型,常用來解決分類和回歸問題。常見的決策樹算法包括:
- 分類及回歸樹(Classification And Regression Tree,簡稱CART)
- ID3算法(Iterative Dichotomiser 3)
- C4.5算法
- 隨機森林算法(Random Forest)
- 梯度推進機算法(Gradient Boosting Machine,簡稱GBM)
決策樹構建的基本步驟包括4步,具體步驟如下:
- 第一步:開始時將所有記錄看作一個節點。
- 第二步:遍歷每個變量的每一種分割方式,找到最好的分割點。
- 第三步:分割成兩個節點N1和N2。
- 第四步:對N1和N2分別繼續執行第二步和第三步,直到每個節點足夠“純”為止。
決策數具有兩個優點:
- 模型可以讀性好,描述性強,有助于人工分析。
- 效率高,決策樹只需要一次構建,可以被反復使用,每一次預測的最大計算次數不超過決策樹的深度。
2.DTC算法
Sklearn機器學習包中,實現決策樹(DecisionTreeClassifier,簡稱DTC)的類是:
- sklearn.tree.DecisionTreeClassifier
它能夠解決數據集的多類分類問題,輸入參數為兩個數組X[n_samples,n_features]和y[n_samples],X為訓練數據,y為訓練數據標記值。DecisionTreeClassifier構造方法為:
sklearn.tree.DecisionTreeClassifier(criterion='gini' , splitter='best' , max_depth=None , min_samples_split=2 , min_samples_leaf=1 , max_features=None , random_state=None , min_density=None , compute_importances=None , max_leaf_nodes=None)DecisionTreeClassifier類主要包括兩個方法:
- clf.fit(train_data, train_target)
用來裝載(train_data,train_target)訓練數據,并訓練分類模型。 - pre = clf.predict(test_data)
用訓練得到的決策樹模型對test_data測試集進行預測分析。
3.決策樹分析鳶尾花
前面第12篇文章介紹過邏輯回歸分析鳶尾花的實例,這里再次講解決策樹分析鳶尾花實例,從而加深讀者印象。
(1) 數據集回顧
在Sklearn機器學習包中,集成了各種各樣的數據集,包括糖尿病數據集、鳶尾花數據集、新聞數據集等。這里使用的是鳶尾花卉Iris數據集,它是一個很常用的數據集,共150行數據,包括四個特征變量:
- 萼片長度
- 萼片寬度
- 花瓣長度
- 花瓣寬度。
同時包括一個類別變量,將鳶尾花劃分為三個類別,即:
- 山鳶尾(Iris-setosa)
- 變色鳶尾(Iris-versicolor)
- 維吉尼亞鳶尾(Iris-virginica)
表2為鳶尾花數據集,詳細信息如下表所示。
iris是鳶尾植物,這里存儲了其萼片和花瓣的長寬,共4個屬性,鳶尾植物分三類。 iris數據集中包括兩個屬性iris.data和iris.target。其中,data數據是一個矩陣,每一列代表了萼片或花瓣的長寬,一共4列,每一行數據代表某個被測量的鳶尾植物,一共采樣了150條記錄。載入鳶尾花數據集代碼如下所示:
from sklearn.datasets import load_iris iris = load_iris() print(iris.data) print(iris.target)(2) 決策樹簡單分析鳶尾花
下述代碼實現了調用Sklearn機器學習包中DecisionTreeClassifier決策樹算法進行分類分析,并繪制預測的散點圖。
輸出結果如圖5所示,可以看到決策樹算法將數據集預測為三類,分別代表著數據集對應的三種鳶尾花,但數據集中存在小部分交叉結果。預測的結果如下:
[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 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 1 1 1 1 1 1 1 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 2 2 2 2 2 2 22 2] 150 (150, 4)DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,max_features=None, max_leaf_nodes=None,min_impurity_decrease=0.0, min_impurity_split=None,min_samples_leaf=1, min_samples_split=2,min_weight_fraction_leaf=0.0, presort=False,random_state=None, splitter='best')下面對上述核心代碼進行簡單描述。
- from sklearn.datasets import load_iris
- iris = load_iris()
該部分代碼是導入sklearn機器學習包自帶的鳶尾花數據集,調用load_iris()函數導入數據,數據共分為數據(data)和類標(target)兩部分。
- from sklearn.tree import DecisionTreeClassifier
- clf = DecisionTreeClassifier()
- clf.fit(iris.data, iris.target)
- predicted = clf.predict(iris.data)
該部分代碼導入決策樹模型,并調用fit()函數進行訓練,predict()函數進行預測。
- import matplotlib.pyplot as plt
- plt.scatter(L1, L2, c=predicted, marker=‘x’)
該部分代碼是導入matplotlib繪圖擴展包,調用scatter()函數繪制散點圖。
但上面的代碼中存在兩個問題:
- 代碼中通過“L1 = [x[0] for x in X]”獲取了第一列和第二列數據集進行了分類分析和繪圖,而真實的iris數據集中包括四個特征,那怎么繪制四個特征的圖形呢? 這就需要利用PCA降維技術處理,參考前一篇文章。
- 第二個問題是在聚類、回歸、分類模型中,都需要先進行訓練,再對新的數據集進行預測,這里卻是對整個數據集進行分類分析,而真實情況是需要把數據集劃分為訓練集和測試集的,例如數據集的70%用于訓練、30%用于預測,或80%用于訓練、20%用于預測。
4.數據集劃分及分類評估
這部分內容主要是進行代碼優化,將數據集劃分為80%訓練集-20%預測集,并對決策樹分類算法進行評估。由于提供的數據集類標是存在一定規律的,前50個類標為0(山鳶尾)、中間50個類標為1(變色鳶尾)、最后50個類標為2(維吉尼亞鳶)。即:
[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 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 1 1 1 1 1 1 1 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 2 2 2 2 2 2 22 2]這里調用NumPy庫中的 concatenate() 函數對數據集進行挑選集成,選擇第0-40行、第50-90行、第100-140行數據作為訓練集,對應的類標作為訓練樣本類標;再選擇第40-50行、第90-100行、第140-150行數據作為測試集合,對應的樣本類標作為預測類標。
代碼如下,“axis=0”表示選取數值的等差間隔為0,即緊挨著獲取數值。
#訓練集 train_data = np.concatenate((iris.data[0:40, :], iris.data[50:90, :], iris.data[100:140, :]), axis = 0) #訓練集樣本類別 train_target = np.concatenate((iris.target[0:40], iris.target[50:90], iris.target[100:140]), axis = 0) #測試集 test_data = np.concatenate((iris.data[40:50, :], iris.data[90:100, :], iris.data[140:150, :]), axis = 0) #測試集樣本類別 test_target = np.concatenate((iris.target[40:50], iris.target[90:100], iris.target[140:150]), axis = 0)同時,調用sklearn機器學習包中metrics類對決策樹分類算法進行評估,它將輸出準確率(Precison)、召回率(Recall)、F特征值(F-score)、支持度(Support)等。
#輸出準確率 召回率 F值 from sklearn import metrics print(metrics.classification_report(test_target, predict_target)) print(metrics.confusion_matrix(test_target, predict_target))分類報告的核心函數為:
sklearn.metrics.classification_report(y_true, y_pred, labels=None,target_names=None,sample_weight=None, digits=2)其中y_true參數表示正確的分類類標,y_pred表示分類預測的類標,labels表示分類報告中顯示的類標簽的索引列表,target_names參數顯示與labels對應的名稱,digits是指定輸出格式的精確度。評價公式如下:
調用 metrics.classification_report() 方法對決策樹算法進行評估后,會在最后一行將對所有指標進行加權平均值,詳見下面完整代碼。
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn import metrics import numpy as np import matplotlib.pyplot as plt#導入數據集iris ''' 重點:分割數據集 構造訓練集/測試集,80/2070%訓練 0-40 50-90 100-14030%預測 40-50 90-100 140-150 ''' iris = load_iris() train_data = np.concatenate((iris.data[0:40, :], iris.data[50:90, :], iris.data[100:140, :]), axis = 0) #訓練集 train_target = np.concatenate((iris.target[0:40], iris.target[50:90], iris.target[100:140]), axis = 0) #訓練集樣本類別 test_data = np.concatenate((iris.data[40:50, :], iris.data[90:100, :], iris.data[140:150, :]), axis = 0) #測試集 test_target = np.concatenate((iris.target[40:50], iris.target[90:100], iris.target[140:150]), axis = 0) #測試集樣本類別#導入決策樹DTC包 clf = DecisionTreeClassifier() clf.fit(train_data, train_target) #注意均使用訓練數據集和樣本類標 print(clf) predict_target = clf.predict(test_data) #測試集 print(predict_target)#預測結果與真實結果比對 print(sum(predict_target == test_target))#輸出準確率 召回率 F值 print(metrics.classification_report(test_target, predict_target)) print(metrics.confusion_matrix(test_target, predict_target))#獲取花卉測試數據集兩列數據 X = test_data L1 = [n[0] for n in X] L2 = [n[1] for n in X]#繪圖 plt.scatter(L1, L2, c=predict_target, marker='x') #cmap=plt.cm.Paired plt.title("DecisionTreeClassifier") plt.show()輸出結果如下,包括對數據集40-50、90-100、140-150的預測結果,接下來輸出的“30”表示整個30組類標預測結果和真實結果是一致的,最后輸出評估結果。
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2] 30precision recall f1-score support0 1.00 1.00 1.00 101 1.00 1.00 1.00 102 1.00 1.00 1.00 10avg / total 1.00 1.00 1.00 30[[10 0 0][ 0 10 0][ 0 0 10]]同時輸出圖形如圖6所示。
讀者可以自行深入研究,調用sklearn.tree.export_graphviz類實現導出決策樹繪制樹形結構的過程,比如鳶尾花數據集輸出如圖7所示的樹形結構。
- https://www.freesion.com/article/894048252/
5.區域劃分對比
下面講述區域劃分對比實驗(前面已經出現過),它是指按照數據集真實的類標,將其劃分為不同顏色區域,這里的鳶尾花數據集共分為三個區域,最后進行散點圖繪制對比。每個區域對應一類散點,表示預測結果和真實結果一致,如果某個區域混入其他類型的散點,則表示該點的預測結果與真實結果不一致。
完整代碼如下所示,代碼首先調用“iris.data[:, :2]”代碼獲取其中兩列數據(兩個特征),再進行決策樹分類分析。
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier #載入鳶尾花數據集 iris = load_iris() X = X = iris.data[:, :2] #獲取花卉前兩列數據 Y = iris.target lr = DecisionTreeClassifier() lr.fit(X,Y)#meshgrid函數生成兩個網格矩陣 h = .02 x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5 y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))#pcolormesh函數將xx,yy兩個網格矩陣和對應的預測結果Z繪制在圖片上 Z = lr.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.figure(1, figsize=(8,6)) plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired)#繪制散點圖 plt.scatter(X[:50,0], X[:50,1], color='red',marker='o', label='setosa') plt.scatter(X[50:100,0], X[50:100,1], color='blue', marker='x', label='versicolor') plt.scatter(X[100:,0], X[100:,1], color='green', marker='s', label='Virginica') plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt.xticks(()) plt.yticks(()) plt.legend(loc=2) plt.show()下面作者對區域劃分對比代碼進行詳細講解。
- x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
- y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
- xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
獲取的鳶尾花兩列數據,對應為萼片長度和萼片寬度,每個點的坐標就是(x,y)。先取X二維數組的第一列(長度)的最小值、最大值和步長h(設置為0.02)生成數組,再取X二維數組的第二列(寬度)的最小值、最大值和步長h生成數組,最后用meshgrid()函數生成兩個網格矩陣xx和yy,如下所示:
[[ 3.8 3.82 3.84 ..., 8.36 8.38 8.4 ][ 3.8 3.82 3.84 ..., 8.36 8.38 8.4 ]..., [ 3.8 3.82 3.84 ..., 8.36 8.38 8.4 ][ 3.8 3.82 3.84 ..., 8.36 8.38 8.4 ]] [[ 1.5 1.5 1.5 ..., 1.5 1.5 1.5 ][ 1.52 1.52 1.52 ..., 1.52 1.52 1.52]..., [ 4.88 4.88 4.88 ..., 4.88 4.88 4.88][ 4.9 4.9 4.9 ..., 4.9 4.9 4.9 ]]- Z = lr.predict(np.c_[xx.ravel(), yy.ravel()])
調用ravel()函數將xx和yy的兩個矩陣轉變成一維數組,再進行預測分析。由于兩個矩陣大小相等,因此兩個一維數組大小也相等。np.c_[xx.ravel(), yy.ravel()]是生成矩陣,即:
xx.ravel() [ 3.8 3.82 3.84 ..., 8.36 8.38 8.4 ] yy.ravel() [ 1.5 1.5 1.5 ..., 4.9 4.9 4.9] np.c_[xx.ravel(), yy.ravel()] [[ 3.8 1.5 ][ 3.82 1.5 ][ 3.84 1.5 ]..., [ 8.36 4.9 ][ 8.38 4.9 ][ 8.4 4.9 ]]總之,上述操作是把第一列萼片長度數據按h取等分作為行,并復制多行得到xx網格矩陣;再把第二列萼片寬度數據按h取等分,作為列,并復制多列得到yy網格矩陣;最后將xx和yy矩陣都變成兩個一維數組,調用np.c_[]函數組合成一個二維數組進行預測。
調用predict()函數進行預測,預測結果賦值給Z。即:
Z = logreg.predict(np.c_[xx.ravel(), yy.ravel()]) [1 1 1 ..., 2 2 2] size: 39501- Z = Z.reshape(xx.shape)
調用reshape()函數修改形狀,將其Z轉換為兩個特征(長度和寬度),則39501個數據轉換為171*231的矩陣。Z = Z.reshape(xx.shape)輸出如下:
- plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired)
調用pcolormesh()函數將xx、yy兩個網格矩陣和對應的預測結果Z繪制在圖片上,可以發現輸出為三個顏色區塊,分別表示三類區域。cmap=plt.cm.Paired表示繪圖樣式選擇Paired主題。輸出的區域如下圖所示:
- plt.scatter(X[:50,0], X[:50,1], color=‘red’,marker=‘o’, label=‘setosa’)
調用scatter()繪制散點圖,第一個參數為第一列數據(長度),第二個參數為第二列數據(寬度),第三、四個參數為設置點的顏色為紅色,款式為圓圈,最后標記為setosa。
最終輸出如圖9所示,經過決策樹分析后劃分為三個區域,左上角部分為紅色的圓點,對應setosa鳶尾花;右邊部分為綠色方塊,對應virginica鳶尾花;中間靠下部分為藍色星形,對應versicolor鳶尾花。散點圖為各數據點真實的花類型,劃分的三個區域為數據點預測的花類型,預測的分類結果與訓練數據的真實結果結果基本一致,部分鳶尾花出現交叉。
三.KNN分類算法
1.算法實例描述
KNN分類算法是最近鄰算法,字面意思就是尋找最近鄰居,由Cover和Hart在1968年提出,它簡單直觀易于實現。下面通過一個經典例子來講解如何尋找鄰居,選取多少個鄰居。圖10需要判斷右邊這個動物是鴨子、雞還是鵝?這就涉及到了KNN算法的核心思想,判斷與這個樣本點相似的類別,再預測其所屬類別。由于它走路和叫聲像一只鴨子,所以右邊的動物很可能是一只鴨子。
KNN分類算法的核心思想是從訓練樣本中尋找所有訓練樣本X中與測試樣本距離(常用歐氏距離)最近的前K個樣本(作為相似度),再選擇與待分類樣本距離最小的K個樣本作為X的K個最鄰近,并檢測這K個樣本大部分屬于哪一類樣本,則認為這個測試樣本類別屬于這一類樣本。
KNN分類的算法步驟如下:
- 計算測試樣本點到所有樣本點的歐式距離dist,采用勾股定理計算
- 用戶自定義設置參數K,并選擇離帶測點最近的K個點
- 從這K個點中,統計各個類型或類標的個數
- 選擇出現頻率最大的類標號作為未知樣本的類標號,反饋最終預測結果
假設現在需要判斷圖11中的圓形圖案屬于三角形還是正方形類別,采用KNN算法分析步驟如下:
- 當K=3時,圖中第一個圈包含了三個圖形,其中三角形2個,正方形一個,該圓的則分類結果為三角形。
- 當K=5時,第二個圈中包含了5個圖形,三角形2個,正方形3個,則以3:2的投票結果預測圓為正方形類標。
- 同理,當K=11原理也是一樣,設置不同的K值,可能預測得到結果也不同。所以,KNN是一個非常簡單、易于理解實現的分類算法。
最后簡單講述KNN算法的優缺點。KNN分類算法存在的優點包括:
- 算法思路較為簡單,易于實現。
- 當有新樣本要加入訓練集中時,無需重新訓練,即重新訓練的代價低。
- 計算時間和空間線性于訓練集的規模。
其缺點主要表現為分類速度慢,由于每次新的待分樣本都必須與所有訓練集一同計算比較相似度,以便取出靠前的K個已分類樣本,所以時間復雜度較高。整個算法的時間復雜度可以用O(m*n)表示,其中m是選出的特征項的個數,而n是訓練集樣本的個數。同時,如果K值確定不好,也會影響整個實驗的結果,這也是KNN算法的另一個缺點。
2.KNeighborsClassifier
Sklearn機器學習包中,實現KNN分類算法的類是neighbors.KNeighborsClassifier。構造方法如下:
KNeighborsClassifier(algorithm='ball_tree', leaf_size=30, metric='minkowski',metric_params=None, n_jobs=1, n_neighbors=3, p=2, weights='uniform')其中最重要的參數是n_neighbors=3,設置最近鄰K值。同時,KNeighborsClassifier可以設置3種算法:brute、kd_tree、ball_tree。具體調用方法如下:
from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=3, algorithm="ball_tree")KNN算法分析時也包括訓練和預測兩個方法。
- 訓練:knn.fit(data, target)
- 預測:pre = knn.predict(data)
下面這段代碼是簡單調用KNN分類算法進行預測的例子,代碼如下。
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 import numpy as np from sklearn.neighbors import KNeighborsClassifier X = np.array([[-1,-1],[-2,-2],[1,2], [1,1],[-3,-4],[3,2]]) Y = [0,0,1,1,0,1] x = [[4,5],[-4,-3],[2,6]] knn = KNeighborsClassifier(n_neighbors=3, algorithm="ball_tree") knn.fit(X,Y) pre = knn.predict(x) print(pre)定義了一個二維數組用于存儲6個點,其中x和y坐標為負數的類標定義為0,x和y坐標為正數的類標定義為1。調用knn.fit(X,Y)函數訓練模型后,再調用predict()函數預測[4,5]、[-4,-3]、[2,6]三個點的坐標,輸出結果分別為:[1, 0, 1],其中x和y坐標為正數的劃分為一類,負數的一類。
同時也可以計算K個最近點的下標和距離,代碼和結果如下,其中,indices表示點的下標,distances表示距離。
distances, indices = knn.kneighbors(X) print(indices) print(distances)>>> [1 0 1] [[0 1 3][1 0 4][2 3 5][3 2 5][4 1 0][5 2 3]] [[ 0. 1.41421356 2.82842712][ 0. 1.41421356 2.23606798][ 0. 1. 2. ][ 0. 1. 2.23606798][ 0. 2.23606798 3.60555128][ 0. 2. 2.23606798]] >>>下面通過一個完整的實例結合可視化技術進行講解,加深讀者的印象。
3.KNN分析紅酒類型
(1) 數據集
該實驗數據集是UCI Machine Learning Repository開源網站提供的MostPopular Data Sets(hits since 2007)紅酒數據集,它是對意大利同一地區生產的三種不同品種的酒,做大量分析所得出的數據。這些數據包括了三種類別的酒,酒中共13種不同成分的特征,共178行數據,如圖13所示。
該數據集包括了三種類型酒中13種不同成分的數量,13種成分分別是:Alcohol、Malicacid、Ash、Alcalinity of ash、Magnesium、Total phenols、Flavanoids、Nonflavanoid phenols、Proanthocyanins、Color intensity、Hue、OD280/OD315 of diluted wines和Proline,每一種成分可以看成一個特征,對應一個數據。三種類型的酒分別標記為“1”、“2”、“3”。數據集特征描述如表3所示。
數據存儲在wine.txt文件中,如圖14所示。每行數據代表一個樣本,共178行數據,每行數據包含14列,即第一列為類標屬性,后面依次是13列特征。其中第1類有59個樣本,第2類有71個樣本,第3類有48個樣本。
注意:前面講述了如何讀取CSV文件數據集或Sklearn擴展包所提供的數據集,但現實分析中,很多數據集會存儲于TXT或DATA文件中,它們采用一定的符號進行分隔,比如圖中采用逗號分隔,如何獲取這類文件中的數據,也是非常重要的知識。所以接下來先教大家讀取這類文件的數據。
(2) 讀取數據集
從圖14可以看到整個數據集采用逗號分隔,常用讀取該類型數據集的方法是調用open()函數讀取文件,依次讀取TXT文件中所有內容,再按照逗號分割符獲取每行的14列數據存儲至數組或矩陣中,從而進行數據分析。這里講述另一種方法,調用loadtxt()函數讀取逗號分隔的數據,代碼如下:
輸出如下所示:
loadtxt()讀入文件函數原型如下:
- loadtxt(fname, dtype, delimiter, converters, usecols)
其中參數fname表示文件路徑,dtype表示數據類型,delimiter表示分隔符,converters將數據列與轉換函數進行映射的字段,如{1:fun},usecols表示選取數據的列。
(3) 數據集拆分訓練集和預測集
由于Wine數據集前59個樣本全是第1類,中間71個樣本為第2類,最后48個樣本是第3類,所以需要將數據集拆分成訓練集和預測集。步驟如下:
- 調用split()函數將數據集的第一列類標(Y數據)和13列特征(X數組)分隔開來。該函數參數包括data數據,分割位置,其中1表示從第一列分割,axis為1表示水平分割、0表示垂直分割。
- 由于數據集第一列存儲的類標為1.0、2.0或3.0浮點型數據,需要將其轉換為整型,這里在for循環中調用int()函數轉換,存儲至y數組中,也可采用np.astype()實現。
- 最后調用np.concatenate()函數將0-40、60-100、140-160行數據分割為訓練集,包括13列特征和類標,其余78行數據為測試集。
代碼如下:
# -*- coding: utf-8 -*- import os import numpy as np path = "wine/wine.txt" data = np.loadtxt(path,dtype=float,delimiter=",") print(data)yy, x = np.split(data, (1,), axis=1) print(yy.shape, x.shape) y = [] for n in yy:y.append(int(n))train_data = np.concatenate((x[0:40,:], x[60:100,:], x[140:160,:]), axis = 0) #訓練集 train_target = np.concatenate((y[0:40], y[60:100], y[140:160]), axis = 0) #樣本類別 test_data = np.concatenate((x[40:60, :], x[100:140, :], x[160:,:]), axis = 0) #測試集 test_target = np.concatenate((y[40:60], y[100:140], y[160:]), axis = 0) #樣本類別print(train_data.shape, train_target.shape) print(test_data.shape, test_target.shape)輸出結果如下:
(178L, 1L) (178L, 13L) (100L, 1L) (100L, 13L) (78L, 1L) (78L, 13L)下面補充一種隨機拆分的方式,調用 sklearn.model_selection.train_test_split 類隨機劃分訓練集與測試集。代碼如下:
from sklearn.model_selection import train_test_split x, y = np.split(data, (1,), axis=1) x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1, train_size=0.7)#Python2調用方法 #from sklearn.cross_validation import train_test_split參數x表示所要劃分的樣本特征集;y是所要劃分的樣本結果;train_size表示訓練樣本占比,0.7表示將數據集劃分為70%的訓練集、30%的測試集;random_state是隨機數的種子。該函數在部分版本的sklearn庫中是導入model_selection類,建議讀者下來嘗試。
(4) KNN分類算法分析
上面已經將178個樣本分成100個訓練樣本和78個測試樣本,采用KNN分類算法訓練模型,再對測試集進行預測,判別出測試樣本所屬于酒的類型,同時輸出測試樣本計算的正確率和錯誤率。KNN核心代碼如下:
預測輸出結果如下所示:
[1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 3 2 2 2 2 2 2 2 2 3 2 3 2 2 2 22 2 3 3 2 2 2 2 2 2 2 2 3 2 3 3 3 3 2 1 2 3 3 2 2 3 2 3 2 2 2 1 2 2 2 3 11 1 1 3](5) 完整代碼
下面代碼實現了調用Sklearn機器學習包中KNeighborsClassifier算法進行分類分析,并繪制預測的散點圖和背景圖,完整代碼如下。
輸出結果如下所示,包括預測的78行類標,共預測正確58行數據,準確率為0.76,召回率為0.74,f特征為0.74。其結果不太理想,需要進一步優化算法。
[1 3 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 3 2 2 3 2 2 2 2 2 3 2 2 2 2 22 1 2 2 2 3 3 3 2 2 2 2 3 2 3 1 1 2 3 3 3 3 3 1 3 3 3 3 3 3 3 1 3 2 1 1 33 3 1 3] 58precision recall f1-score support1 0.68 0.89 0.77 192 0.88 0.74 0.81 313 0.67 0.64 0.65 28avg / total 0.76 0.74 0.74 78輸出圖形如圖15所示,可以看到整個區域劃分為三種顏色,左下角為綠色區域,右下角為紅色區域,右上部分為藍色區域。同時包括78個點分布,對應78行數據的類標,包括綠色、藍色和紅色的點。可以發現,相同顏色的點主要集中于該顏色區域,部分藍色點劃分至紅色區域或綠色點劃分至藍色區域,則表示預測結果與實際結果不一致。
最后簡單總結,整個分析過程包括六個步驟,大致內容如下:
- 1) 加載數據集
采用loadtxt()函數加載酒類數據集,采用逗號(,)分割。 - 2) 劃分數據集
由于Wine數據集第一列為類標,后面13列為13個酒類特征,獲取其中兩列特征,并將其劃分成特征數組和類標數組,調用concatenate()函數實現。 - 3) KNN訓練
調用Sklearn機器學習包中KNeighborsClassifier()函數訓練,設置K值為3類,并調用clf.fit(train_data,train_target)訓練模型,clf.predict(test_data)預測分類結果。 - 4) 評價算法
通過classification_report()函數計算該分類預測結果的準確率、召回率和F值。 - 5) 創建網格
由于繪圖中,擬將預測的類標劃分為三個顏色區域,真實的分類結果以散點圖形式呈現,故需要獲取數據集中兩列特征的最大值和最小值,并創建對應的矩陣網格,調用numpy擴展包的meshgrid()函數實現,在對其顏色進行預測。 - 6) 繪圖可視化
設置不同類標的顏色,調用pcolormesh()函數繪制背景區域顏色,調用scatter()函數繪制實際結果的散點圖,形成如圖15的效果圖。
四.SVM分類算法
支持向量機(Support Vector Machine,簡稱SVM)是常見的一種判別方法。在機器學習領域,是一個有監督的學習模型,通常用來進行模式識別、分類以及回歸分析。該算法的最大特點是根據結構風險最小化準則,以最大化分類間隔構造最優分類超平面來提高學習機的泛化能力,較好地解決了非線性、高維數、局部極小點等問題。
1.SVM基礎知識
(1) 基礎概念
由于作者數學推算能力不太好,同時SVM原理也比較復雜,所以SVM算法基礎知識推薦大家閱讀CSDN博客著名算法大神“JULY”的文章《支持向量機通俗導論(理解SVM的三層境界)》,這篇文章由淺入深的講解了SVM算法,而本小節作者主要講解SVM的用法。
SVM分類算法的核心思想是通過建立某種核函數,將數據在高維尋找一個滿足分類要求的超平面,使訓練集中的點距離分類面盡可能的遠,即尋找一個分類面使得其兩側的空白區域最大。如圖19.16所示,兩類樣本中離分類面最近的點且平行于最優分類面的超平面上的訓練樣本就叫做支持向量。
(2) SVM導入方法
SVM分類算法在Sklearn機器學習包中,實現的類是 svm.SVC,即C-Support Vector Classification,它是基于libsvm實現的。構造方法如下:
其中參數含義如下:
- C表示目標函數的懲罰系數,用來平衡分類間隔margin和錯分樣本的,默認值為1.0;
- cache_size是制定訓練所需要的內存(以MB為單位);
- gamma是核函數的系數,默認是gamma=1/n_features;
- kernel可以選擇RBF、Linear、Poly、Sigmoid,默認的是RBF;
- degree決定了多項式的最高次冪;
- max_iter表示最大迭代次數,默認值為1;
- coef0是核函數中的獨立項;
- class_weight表示每個類所占據的權重,不同的類設置不同的懲罰參數C,缺省為自適應;
- decision_function_shape包括ovo(一對一)、ovr(多對多)或None(默認值)。
SVC算法主要包括兩個步驟:
- 訓練:nbrs.fit(data, target)
- 預測:pre = clf.predict(data)
下面這段代碼是簡單調用SVC分類算法進行預測的例子,數據集中x和y坐標為負數的類標為1,x和y坐標為正數的類標為2,同時預測點[-0.8,-1]的類標為1,點[2,1]的類標為2。
import numpy as np from sklearn.svm import SVCX = np.array([[-1, -1], [-2, -2], [1, 3], [4, 6]]) y = np.array([1, 1, 2, 2]) clf = SVC() clf.fit(X, y) print(clf) print(clf.predict([[-0.8,-1], [2,1]]))#輸出結果:[1, 2]支持向量機分類器還有其他的方法,比如NuSVC核支持向量分類,LinearSVC線性向量支持分類等,這里不再介紹。同時,支持向量機也已經推廣到解決回歸問題,稱為支持向量回歸,比如SVR做線性回歸。
2.SVM分析紅酒數據
接著采用SVM分類算法對酒類數據集Wine進行分析,并對比前面19.3小節的實例代碼,校驗SVM分類算法和KNN分類算法的分析結果和可視化分析的優劣。其分析步驟基本一致,主要包括如下六個步驟:
- 第一步,加載數據集。采用loadtxt()函數加載酒類數據集,采用逗號(,)分割。
- 第二步,劃分數據集。將Wine數據集劃分為訓練集和預測集,僅提取酒類13個特種中的兩列特征進行數據分析。
- 第三步,SVM訓練。導入Sklearn機器學習包中svm.SVC()函數分析,調用fit()函數訓練模型,predict(test_data)函數預測分類結果。
- 第四步,評價算法。通過classification_report()函數計算該分類預測結果的準確率、召回率和F值。
- 第五步,創建網格。獲取數據集中兩列特征的最大值和最小值,并創建對應的矩陣網格,用于繪制背景圖,調用numpy擴展包的meshgrid()函數實現。
- 第六步,繪圖可視化。設置不同類標的顏色,調用pcolormesh()函數繪制背景區域顏色,調用scatter()函數繪制實際結果的散點圖。
完整代碼如下所示:
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 import os import numpy as np from sklearn.svm import SVC from sklearn import metrics import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap#---------------------------------------------------------------------------- #第一步 加載數據集 path = "wine/wine.txt" data = np.loadtxt(path,dtype=float,delimiter=",") print(data)#---------------------------------------------------------------------------- #第二步 劃分數據集 yy, x = np.split(data, (1,), axis=1) #第一列為類標yy,后面13列特征為x print(yy.shape, x.shape) y = [] for n in yy: #將類標浮點型轉化為整數y.append(int(n)) x = x[:, :2] #獲取x前兩列數據,方便繪圖 對應x、y軸 train_data = np.concatenate((x[0:40,:], x[60:100,:], x[140:160,:]), axis = 0) #訓練集 train_target = np.concatenate((y[0:40], y[60:100], y[140:160]), axis = 0) #樣本類別 test_data = np.concatenate((x[40:60, :], x[100:140, :], x[160:,:]), axis = 0) #測試集 test_target = np.concatenate((y[40:60], y[100:140], y[160:]), axis = 0) #樣本類別 print(train_data.shape, train_target.shape) print(test_data.shape, test_target.shape)#---------------------------------------------------------------------------- #第三步 SVC訓練 clf = SVC() clf.fit(train_data,train_target) result = clf.predict(test_data) print(result)#---------------------------------------------------------------------------- #第四步 評價算法 print(sum(result==test_target)) #預測結果與真實結果比對 print(metrics.classification_report(test_target, result)) #準確率 召回率 F值#---------------------------------------------------------------------------- #第五步 創建網格 x1_min, x1_max = test_data[:,0].min()-0.1, test_data[:,0].max()+0.1 #第一列 x2_min, x2_max = test_data[:,1].min()-0.1, test_data[:,1].max()+0.1 #第二列 xx, yy = np.meshgrid(np.arange(x1_min, x1_max, 0.1), np.arange(x2_min, x2_max, 0.1)) #生成網格型數據 z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) #---------------------------------------------------------------------------- #第六步 繪圖可視化 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) #顏色Map cmap_bold = ListedColormap(['#000000', '#00FF00', '#FFFFFF']) plt.figure() z = z.reshape(xx.shape) print(xx.shape, yy.shape, z.shape, test_target.shape) plt.pcolormesh(xx, yy, z, cmap=cmap_light) plt.scatter(test_data[:,0], test_data[:,1], c=test_target,cmap=cmap_bold, s=50) plt.show()代碼提取了178行數據的第一列作為類標,剩余13列數據作為13個特征的數據集,并劃分為訓練集(100行)和測試集(78行)。輸出結果如下,包括78行SVM分類預測的類標結果,其中61行數據類標與真實的結果一致,其準確率為0.78,召回率為0.78,F1特征為0.78。
最后可視化繪圖輸出如下圖所示的結果。
3.優化SVM分析紅酒數據集
前面SVM分析紅酒數據集的代碼存在兩個缺點,一是采用固定的組合方式劃分的數據集,即調用np.concatenate()函數將0-40、60-100、140-160行數據分割為訓練集,其余為預測集;二是只提取了數據集中的兩列特征進行SVM分析和可視化繪圖,即調用“x = x[:, :2]”獲取前兩列特征,而紅酒數據集共有13列特征。
真實的數據分析中通常會隨機劃分數據集,分析過程也是對所有的特征進行訓練及預測操作,再經過降維處理之后進行可視化繪圖展示。下面對SVM分析紅酒數據集實例進行簡單的代碼優化,主要包括:
- 隨機劃分紅酒數據集
- 對數據集的所有特征進行訓練和預測分析
- 采用PCA算法降維后再進行可視化繪圖操作
完整代碼如下,希望讀者也認真學習該部分知識,更好地優化自己的研究或課題。
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 import os import numpy as np from sklearn.svm import SVC from sklearn import metrics import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap from sklearn.model_selection import train_test_split from sklearn.decomposition import PCA#第一步 加載數據集 path = "wine/wine.txt" data = np.loadtxt(path,dtype=float,delimiter=",") print(data)#第二步 劃分數據集 yy, x = np.split(data, (1,), axis=1) #第一列類標yy,后面13列特征為x print(yy.shape, x.shape) y = [] for n in yy: y.append(int(n)) y = np.array(y, dtype = int) #list轉換數組 #劃分數據集 測試集40% train_data, test_data, train_target, test_target = train_test_split(x, y, test_size=0.4, random_state=42) print(train_data.shape, train_target.shape) print(test_data.shape, test_target.shape)#第三步 SVC訓練 clf = SVC() clf.fit(train_data, train_target) result = clf.predict(test_data) print(result) print(test_target)#第四步 評價算法 print(sum(result==test_target)) #預測結果與真實結果比對 print(metrics.classification_report(test_target, result)) #準確率 召回率 F值#第五步 降維操作 pca = PCA(n_components=2) newData = pca.fit_transform(test_data)#第六步 繪圖可視化 plt.figure() cmap_bold = ListedColormap(['#000000', '#00FF00', '#FFFFFF']) plt.scatter(newData[:,0], newData[:,1], c=test_target, cmap=cmap_bold, s=50) plt.show()輸出結果如下所示,其準確率、召回率和F值很低,僅為50%、39%和23%。
(106L, 13L) (106L,) (72L, 13L) (72L,) [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 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 2 2 2 2 2] [1 1 3 1 2 1 2 3 2 3 1 3 1 2 1 2 2 2 1 2 1 2 2 3 3 3 2 2 2 1 1 2 3 1 1 1 33 2 3 1 2 2 2 3 1 2 2 3 1 2 1 1 3 3 2 2 1 2 1 3 2 2 3 1 1 1 3 1 1 2 3] 28precision recall f1-score support1 1.00 0.04 0.07 262 0.38 1.00 0.55 273 0.00 0.00 0.00 19avg / total 0.50 0.39 0.23 72上述代碼如下采用決策樹進行分析,則其準確率、召回率和F值就很高,結果如下所示。所以并不是每種分析算法都適應所有的數據集,不同數據集其特征不同,最佳分析的算也會不同,我們在進行數據分析時,通常會對比多種分析算法,再優化自己的實驗和模型。
from sklearn.tree import DecisionTreeClassifier clf = DecisionTreeClassifier() print(metrics.classification_report(test_target, result))# precision recall f1-score support # # 1 0.96 0.88 0.92 26 # 2 0.90 1.00 0.95 27 # 3 1.00 0.95 0.97 19 # #avg / total 0.95 0.94 0.94 72SVM算法分析后輸出的圖形如下所示。
五.各模型分類對比實驗
算法評價和對比實驗是深度學習重要的知識點,這里作者對各種機器學習分類算法進行對比,以鳶尾花數據集為例,我們從繪制的分類邊界效果以及實驗評估指標(Precision、Recall、F1-socre)分別進行對比。參考文章如下,推薦大家學習:
- 機器學習之sklearn基本分類方法 - 萌弟老師
1.決策樹
原始代碼如下:
# -*- coding: utf-8 -*- # By:Eastmount CSDN 2021-07-06 # 該部分參考知乎萌弟老師:https://zhuanlan.zhihu.com/p/173945775 import numpy as np from sklearn import metrics from sklearn import datasets import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap from sklearn.model_selection import train_test_split from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler#------------------------------------------------------------------------ #第一步 導入數據 iris = datasets.load_iris() X = iris.data[:,[2,3]] y = iris.target print("Class labels:",np.unique(y)) #打印分類類別的種類 [0 1 2]#30%測試數據 70%訓練數據 stratify=y表示訓練數據和測試數據具有相同的類別比例 X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=1,stratify=y)#------------------------------------------------------------------------ #第二步 數據標準化 sc = StandardScaler() #估算訓練數據中的mu和sigma sc.fit(X_train) #使用訓練數據中的mu和sigma對數據進行標準化 X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test) print(X_train_std) print(X_test_std)#------------------------------------------------------------------------ #第三步 可視化函數 畫出決策邊界 def plot_decision_region(X,y,classifier,resolution=0.02):markers = ('s','x','o','^','v')colors = ('red','blue','lightgreen','gray','cyan')cmap = ListedColormap(colors[:len(np.unique(y))])# plot the decision surfacex1_min,x1_max = X[:,0].min()-1,X[:,0].max()+1x2_min,x2_max = X[:,1].min()-1,X[:,1].max()+1xx1,xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),np.arange(x2_min,x2_max,resolution))Z = classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T)Z = Z.reshape(xx1.shape)plt.contourf(xx1,xx2,Z,alpha=0.3,cmap=cmap)plt.xlim(xx1.min(),xx1.max())plt.ylim(xx2.min(),xx2.max())# plot class samplesfor idx,cl in enumerate(np.unique(y)):plt.scatter(x=X[y==cl,0],y = X[y==cl,1],alpha=0.8,c=colors[idx],marker = markers[idx],label=cl,edgecolors='black')#------------------------------------------------------------------------ #第四步 決策樹分類 from sklearn.tree import DecisionTreeClassifier tree = DecisionTreeClassifier(criterion='gini',max_depth=4,random_state=1) tree.fit(X_train_std,y_train) print(X_train_std.shape, X_test_std.shape, len(y_train), len(y_test)) #(105, 2) (45, 2) 105 45 res1 = tree.predict(X_test_std) print(res1) print(metrics.classification_report(y_test, res1, digits=4)) #四位小數plot_decision_region(X_train_std,y_train,classifier=tree,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('DecisionTreeClassifier') plt.legend(loc='upper left') plt.show()實驗的精確率、召回率和F1值輸出如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示,可以看到分類效果明顯。
2.KNN
核心代碼如下:
- macro avg: 0.98 0.98 0.98
輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示:
3.SVM
核心代碼如下:
#第六步 SVM分類 核函數對非線性分類問題建模(gamma=0.20) from sklearn.svm import SVC svm = SVC(kernel='rbf',random_state=1,gamma=0.20,C=1.0) #較小的gamma有較松的決策邊界 svm.fit(X_train_std,y_train) res3 = svm.predict(X_test_std) print(res3) print(metrics.classification_report(y_test, res3, digits=4))plot_decision_region(X_train_std,y_train,classifier=svm,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('SVM') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9361 0.9333 0.9340
繪制的訓練數據分類效果如下圖所示:
如果使用的核函數gamma為100,然后實現非線性分類,則繪制結果如下圖所示:
- svm = SVC(kernel=‘rbf’,random_state=1,gamma=100.0,C=1.0,verbose=1)
引用萌弟老師的結論,非常土建大家去關注他。
從不同的gamma取值的圖像來看:對于高斯核函數,增大gamma值,將增大訓練樣本的影響范圍,導致決策邊界緊縮和波動;較小的gamma值得到的決策邊界相對寬松。雖然較大的gamma值在訓練樣本中有很小的訓練誤差,但是很可能泛化能力較差,容易出現過擬合。
4.邏輯回歸
核心代碼如下:
#第七步 邏輯回歸分類 from sklearn.linear_model import LogisticRegression lr = LogisticRegression(C=100.0,random_state=1) lr.fit(X_train_std,y_train) res4 = lr.predict(X_test_std) print(res4) print(metrics.classification_report(y_test, res4, digits=4))plot_decision_region(X_train_std,y_train,classifier=lr,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('LogisticRegression') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示:
5.樸素貝葉斯
核心代碼如下:
#第八步 樸素貝葉斯分類 from sklearn.naive_bayes import GaussianNB gnb = GaussianNB() gnb.fit(X_train_std,y_train) res5 = gnb.predict(X_test_std) print(res5) print(metrics.classification_report(y_test, res5, digits=4))plot_decision_region(X_train_std,y_train,classifier=gnb,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('GaussianNB') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示,還挺好看的,邊界呈曲線分布。
6.隨機森林
核心代碼如下:
#第九步 隨機森林分類 from sklearn.ensemble import RandomForestClassifier forest = RandomForestClassifier(criterion='gini',n_estimators=25,random_state=1,n_jobs=2,verbose=1) forest.fit(X_train_std,y_train) res6 = gnb.predict(X_test_std) print(res6) print(metrics.classification_report(y_test, res6, digits=4))plot_decision_region(X_train_std,y_train,classifier=forest,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('GaussianNB') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示:
7.AdaBoost
核心代碼如下:
#第十步 集成學習分類 from sklearn.ensemble import AdaBoostClassifier ada = AdaBoostClassifier() ada.fit(X_train_std,y_train) res7 = ada.predict(X_test_std) print(res7) print(metrics.classification_report(y_test, res7, digits=4))plot_decision_region(X_train_std,y_train,classifier=forest,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('AdaBoostClassifier') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示:
8.GradientBoosting
核心代碼如下:
#第11步 GradientBoosting分類 from sklearn.ensemble import GradientBoostingClassifier gb = GradientBoostingClassifier() ada.fit(X_train_std,y_train) res8 = ada.predict(X_test_std) print(res8) print(metrics.classification_report(y_test, res8, digits=4))plot_decision_region(X_train_std,y_train,classifier=forest,resolution=0.02) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('GradientBoostingClassifier') plt.legend(loc='upper left') plt.show()輸出結果如下:
- macro avg: 0.9792 0.9778 0.9778
繪制的訓練數據分類效果如下圖所示:
9.實驗結果對比
最后通常需要對實驗結果進行對比,由于數據集比較少,所有效果都比較好,這里不太好進行對比實驗。簡單給出兩張對比結果圖,但方法是類似的。隨著作者深入會分享更多相關文章。
六.本章小結
寫到這里,這篇文章就結束了,您是否對分類更好的認識呢?
聚類是通過定義一種距離度量方法,表示兩個東西的相似程度,然后將類內相似度高且類間相似度低的數據放在一個類中,它是不需要標注結果的無監督學習算法。與之不同,分類是需要標注類標的,屬于有監督學習,它表示收集某一類數據的共有特征,找出區分度大的特征,用這些特征對要分類的數據進行分類,并且由于是標注結果的,可以通過反復地訓練來提升分類算法。
常見的分類算法包括樸素貝葉斯、邏輯回歸、決策樹、支持向量機等。常見應用比如通過分析市民歷史公交卡交易數據來分類預測乘客的出行習慣和偏好;京東從海量商品圖片中提取圖像特征,通過分類給用戶推薦商品和廣告,比如“找同款”應用;基于短信文本內容的分類智能化識別垃圾短信及其變種,防止騷擾手機用戶;搜索引擎通過訓練用戶的歷史查詢詞和用戶屬性標簽(如性別、年齡、愛好),構建分類算法來預測新增用戶的屬性及偏好等。不同的分類算法有不同的優劣,希望讀者下來編寫代碼體會不同的分類算法的特點。
最后希望讀者能復現每一行代碼,只有實踐才能進步。同時更多聚類算法和原理知識,希望讀者下來自行深入學習研究,也推薦大家結合Sklearn官網和開源網站學習更多的機器學習知識。
該系列所有代碼下載地址:
- https://github.com/eastmountyxz/Python-zero2one
感謝在求學路上的同行者,不負遇見,勿忘初心。這周的留言感慨~
(By:娜璋之家 Eastmount 2021-07-10 夜于武漢 https://blog.csdn.net/Eastmount )
參考文獻:
- [1] 楊秀璋. 專欄:知識圖譜、web數據挖掘及NLP - CSDN博客[EB/OL]. (2016-09-19)[2017-11-07]. http://blog.csdn.net/column/details/eastmount-kgdmnlp.html.
- [2] 張良均,王路,譚立云,蘇劍林. Python數據分析與挖掘實戰[M]. 北京:機械工業出版社,2016.
- [3] (美)Wes McKinney著. 唐學韜等譯. 利用Python進行數據分析[M]. 北京:機械工業出版社,2013.
- [4] Jiawei Han,Micheline Kamber著. 范明,孟小峰譯. 數據挖掘概念與技術. 北京:機械工業出版社,2007.
- [5] 楊秀璋. [Python數據挖掘課程] 四.決策樹DTC數據分析及鳶尾數據集分析[EB/OL].(2016-10-15)[2017-11-26]. http://blog.csdn.net/eastmount/article/details/52820400.
- [6] 楊秀璋. [Python數據挖掘課程] 五.線性回歸知識及預測糖尿病實例[EB\OL]. (2016-10-28)[2017-11-26]. http://blog.csdn.net/eastmount/article/details/52929765.
- [7] jackywu1010. 分類算法概述與比較[EB/OL]. (2011-12-09)[2017-11-26]. http://blog.csdn.net/jackywu1010/article/details/7055561.
- [8] 百度百科. 鄰近算法[EB/OL]. (2015-09-16)[2017-11-26]. https://baike.baidu.com/item/鄰近算法/1151153?fr=aladdin.
- [9] 楊秀璋. [python數據挖掘課程] 十九.鳶尾花數據集可視化、線性回歸、決策樹花樣分析[EB/OL]. (2017-12-02)[2017-12-02]. http://blog.csdn.net/eastmount/article/
details/78692227. - [10]楊秀璋. [python數據挖掘課程] 二十.KNN最近鄰分類算法分析詳解及平衡秤TXT數據集讀取[EB/OL]. (2017-12-08)[2017-12-08]. http://blog.csdn.net/eastmount/article/
details/78747128. - [11] lsldd. 用Python開始機器學習(4:KNN分類算法)[EB/OL]. (2014-11-23)[2017-11-26]. http://blog.csdn.net/lsldd/article/details/41357931.
- [12] UCI官網. UCI Machine Learning Repository: Wine Data Set[EB/OL]. (2017)[2017-12-08]. http://archive.ics.uci.edu/ml/datasets/Wine.
- [13]楊秀璋. [python數據挖掘課程] 二十一.樸素貝葉斯分類器詳解及中文文本輿情分析[EB/OL]. (2018-01-24)[2018-01-24]. http://blog.csdn.net/eastmount/article/
details/79128235. - [14] scikit-learn官網. Nearest Neighbors Classification scikit-learn[EB\OL]. (2017)[2017-12-08]. http://scikit-learn.org/stable/auto_examples/neighbors/
plot_classification.html#sphx-glr-auto-examples-neighbors-plot-classification-py. - [15]July大神. 支持向量機通俗導論(理解SVM的三層境界)[EB/OL]. http://blog.csdn.net/v_JULY_v/article/details/7624837.
總結
以上是生活随笔為你收集整理的[Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Python从零到壹] 十三.机器学习
- 下一篇: [Python人工智能] 三十.Kera