机器学习算法4
文章目錄
- 精確率和召回率
- 分類器性能評估
- 混淆矩陣
- 分類模型
- sklearn.metrics.classification_report
- 決策樹
- 認識決策樹
- 優缺點
- 信息的度量和作用
- 信息熵
- 決策樹劃分依據之信息增益
- api
- 實戰
- method
- 決策樹優缺點分析
- 實例
- 隨機森林
- 集成方法(分類)之隨機森林
- 學習算法
- sklearn.ensemble,集成方法模塊
- 屬性
- 方法
- 集成學習方法
- 隨機森林優點
精確率和召回率
分類器性能評估
在許多實際問題中,衡量分類器任務的成功程度是通過固定的性能指標來獲取。一般最常見使用的是準確率,即預測結果正確的百分比。然而有時候,我們關注的是負樣本是否被正確診斷出來。例如,關于腫瘤的的判定,需要更加關心多少惡性腫瘤被正確的診斷出來。也就是說,在二類分類任務下,預測結果(Predicted Condition)與正確標記(True Condition)之間存在四種不同的組合,構成混淆矩陣。
在二類問題中,如果將一個正例判為正例,那么就可以認為產生了一個真正例(True Positive,TP);如果對一個反例正確的判為反例,則認為產生了一個真反例(True Negative,TN)。相應地,兩外兩種情況則分別稱為偽反例(False Negative,FN,也稱)和偽正例(False Positive,TP),四種情況如下圖:
混淆矩陣
在分類中,當某個類別的重要性高于其他類別時,我們就可以利用上述定義出多個逼錯誤率更好的新指標。第一個指標就是正確率(Precision),它等于TP/(TP+FP),給出的是預測為正例的樣本中占真實結果總數的比例。第二個指標是召回率(Recall)。它等于TP/(TP+FN),給出的是預測為正例的真實正例占所有真實正例的比例。
那么除了正確率和精確率這兩個指標之外,為了綜合考量召回率和精確率,我們計算這兩個指標的調和平均數,得到F1指標(F1 measure):
分類模型
sklearn.metrics.classification_report
sklearn中metrics中提供了計算四個指標的模塊,也就是classification_report。
classification_report(y_true, y_pred, labels=None, target_names=None, digits=2)"""計算分類指標:param y_true:真實目標值:param y_pred:分類器返回的估計值:param target_names:可選的,計算與目標類別匹配的結果:param digits:格式化輸出浮點值的位數:return :字符串,三個指標值""" from sklearn.metrics import classification_report y_true = [0, 1, 2, 2, 2] y_pred = [0, 0, 2, 2, 1] target_names = ['class 0', 'class 1', 'class 2'] print(classification_report(y_true, y_pred, target_names=target_names))precision recall f1-score supportclass 0 0.50 1.00 0.67 1class 1 0.00 0.00 0.00 1class 2 1.00 0.67 0.80 3avg / total 0.70 0.60 0.61 5決策樹
認識決策樹
決策樹是一種基本的分類方法,當然也可以用于回歸。我們一般只討論用于分類的決策樹。決策樹模型呈樹形結構。在分類問題中,表示基于特征對實例進行分類的過程,它可以認為是if-then規則的集合。在決策樹的結構中,每一個實例都被一條路徑或者一條規則所覆蓋。通常決策樹學習包括三個步驟:特征選擇、決策樹的生成和決策樹的修剪
優缺點
優點:計算復雜度不高,輸出結果易于理解,對中間值的缺失不敏感,可以處理邏輯回歸等不能解決的非線性特征數據
缺點:可能產生過度匹配問題
適用數據類型:數值型和標稱型
特征選擇
特征選擇在于選取對訓練數據具有分類能力的特征。這樣可以提高決策樹學習的效率,如果利用一個特征進行分類的結果與隨機分類的結果沒有很大差別,則稱這個特征是沒有分類能力的。經驗上扔掉這樣的特征對決策樹學習的京都影響不大。通常特征選擇的準則是信息增益,這是個數學概念。通過一個例子來了解特征選擇的過程。
我們希望通過所給的訓練數據學習一個貸款申請的決策樹,用以對文萊的貸款申請進行分類,即當新的客戶提出貸款申請是,根據申請人的特征利用決策樹決定是否批準貸款申請。特征選擇其實是決定用那個特征來劃分特征空間。下圖中分別是按照年齡,還有是否有工作來劃分得到不同的子節點
問題是究竟選擇哪個特征更好些呢?那么直觀上,如果一個特征具有更好的分類能力,是的各個自己在當前的條件下有最好的分類,那么就更應該選擇這個特征。信息增益就能很好的表示這一直觀的準則。這樣得到的一棵決策樹只用了兩個特征就進行了判斷
信息的度量和作用
我們常說信息有用,那么它的作用如何客觀、定量地體現出來呢?信息用途的背后是否有理論基礎呢?這個問題一直沒有很好的回答,直到1948年,香農在他的論文“通信的數學原理”中提到了“信息熵”的概念,才解決了信息的度量問題,并量化出信息的作用。
一條信息的信息量與其不確定性有著直接的關系,比如我們要搞清一件非常不確定的事,就需要大量的信息。相反如果對某件事了解較多,則不需要太多的信息就能把它搞清楚 。所以從這個角度看,可以認為,信息量就等于不確定的多少。那么如何量化信息量的度量呢?2022年舉行世界杯,大家很關系誰是冠軍。假如我錯過了看比賽,賽后我問朋友 ,“誰是冠軍”?他不愿意直接告訴我,讓我每猜一次給他一塊錢,他告訴我是否猜對了,那么我需要掏多少錢才能知道誰是冠軍?我可以把球編上號,從1到32,然后提問:冠 軍在1-16號嗎?依次詢問,只需要五次,就可以知道結果。所以誰是世界杯冠軍這條消息只值五塊錢。當然香農不是用錢,而是用“比特”這個概念來度量信息量。一個比特是 一位二進制數,在計算機中一個字節是8比特。
那么如果說有一天有64支球隊進行決賽階段的比賽,那么“誰是世界杯冠軍”的信息量就是6比特,因為要多猜一次,有的同學就會發現,信息量的比特數和所有可能情況的對數函數log有關,(log32=5,log64=6)
另外一方面你也會發現實際上我們不需要猜五次就能才出冠軍,因為像西班牙、巴西、德國、意大利這樣的球隊奪得冠軍的可能性比南非、尼日利亞等球隊大得多,因此第一次猜測時不需要把32支球隊等分成兩個組,而可以把少數幾支最有可能的球隊分成一組,把其他球隊分成一組。然后才冠軍球隊是否在那幾支熱門隊中。這樣,也許三次就猜出結果。因此,當每支球隊奪冠的可能性不等時,“誰是世界杯冠軍”的信息量比5比特少。香農指出,它的準確信息量應該是:
其中,p1…p32為這三支球隊奪冠的概率。H的專業術語稱之為信息熵,單位為比特,當這32支球隊奪冠的幾率相同時,對應的信息熵等于5比特,這個可以通過計算得出。有一個特性就是,5比特是公式的最大值。那么信息熵(經驗熵)的具體定義可以為如下:
信息熵
信息熵越大,不確定越大
決策樹劃分依據之信息增益
api
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_split=1e-07, class_weight=None, presort=False)""":param max_depth:int或None,可選(默認=無)樹的最大深度。如果沒有,那么節點將被擴展,直到所有的葉子都是純類,或者直到所有的葉子都包含少于min_samples_split樣本:param random_state:random_state是隨機數生成器使用的種子"""實戰
首先我們導入類,以及數據集,還有將數據分成訓練數據集和測試數據集兩部分
from sklearn.model_selection import train_test_split from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier iris = load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) estimator = DecisionTreeClassifier(max_leaf_nodes=3, random_state=0) estimator.fit(X_train, y_trainmethod
apply 返回每個樣本被預測的葉子的索引
estimator.apply(X)array([ 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, 5,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,5, 5, 15, 5, 5, 5, 5, 5, 5, 10, 5, 5, 5, 5, 5, 10, 5,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16, 16,16, 16, 16, 16, 6, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,8, 16, 16, 16, 16, 16, 16, 14, 16, 16, 11, 16, 16, 16, 8, 8, 16,16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16])decision_path 返回樹中的決策路徑
dp = estimator.decision_path(X_test)fit_transform(X,y=None,fit_params)** 輸入數據,然后轉換
predict(X) 預測輸入數據的類型,完整代碼
score(X,y,sample_weight=None) 返回給定測試數據的準確精度
estimator.score(X_test,y_test)0.89473684210526316決策樹優缺點分析
決策樹的一些優點是:
簡單的理解和解釋。樹木可視化。
需要很少的數據準備。其他技術通常需要數據歸一化,需要創建虛擬變量,并刪除空值。但請注意,此模塊不支持缺少值。
使用樹的成本(即,預測數據)在用于訓練樹的數據點的數量上是對數的。
決策樹的缺點包括:
決策樹學習者可以創建不能很好地推廣數據的過于復雜的樹。這被稱為過擬合。修剪(目前不支持)的機制,設置葉節點所需的最小采樣數或設置樹的最大深度是避免此問題的必要條件。
決策樹可能不穩定,因為數據的小變化可能會導致完全不同的樹被生成。通過使用合奏中的決策樹來減輕這個問題。
實例
def decision():"""決策樹對泰坦尼克號進行預測生死:return: None"""# 獲取數據titan=pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")#處理數據,找出特征值和目標值x=titan[['pclass','age','sex']]y=titan['survived']print(x)#缺失值處理x['age'].fillna(x['age'].mean(),inplace=True)#分割數據集為訓練集和測試集x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25,random_state=33)# 進行處理(特征工程)特征-》類別-》one_hot編碼vec=DictVectorizer(sparse=False)x_train=vec.fit_transform(x_train.to_dict(orient='record'))print(vec.get_feature_names)x_test=vec.transform(x_test.to_dict(orient='record'))print(vec.get_feature_names)print(x_train)#用決策樹進行預測dec=DecisionTreeClassifier()dec.fit(x_train,y_train)y_predict = dec.predict(x_test)#預測準確率print("預測的準確率",dec.score(x_test,y_test))print(classification_report(y_predict, y_test, target_names=['died', 'surveved']))C:\Users\HP\Anaconda3\python.exe D:/PycharmProjects/untitled2/算法/算法3.pypclass age sex 0 1st 29.0000 female 1 1st 2.0000 female 2 1st 30.0000 male 3 1st 25.0000 female 4 1st 0.9167 male 5 1st 47.0000 male 6 1st 63.0000 female 7 1st 39.0000 male 8 1st 58.0000 female 9 1st 71.0000 male 10 1st 47.0000 male 11 1st 19.0000 female 12 1st NaN female 13 1st NaN male 14 1st NaN male 15 1st 50.0000 female 16 1st 24.0000 male 17 1st 36.0000 male 18 1st 37.0000 male 19 1st 47.0000 female 20 1st 26.0000 male 21 1st 25.0000 male 22 1st 25.0000 male 23 1st 19.0000 female 24 1st 28.0000 male 25 1st 45.0000 male 26 1st 39.0000 male 27 1st 30.0000 female 28 1st 58.0000 female 29 1st NaN male ... ... ... ... 1283 3rd NaN female 1284 3rd NaN male 1285 3rd NaN male 1286 3rd NaN male 1287 3rd NaN male 1288 3rd NaN male 1289 3rd NaN male 1290 3rd NaN male 1291 3rd NaN male 1292 3rd NaN male 1293 3rd NaN female 1294 3rd NaN male 1295 3rd NaN male 1296 3rd NaN male 1297 3rd NaN male 1298 3rd NaN male 1299 3rd NaN male 1300 3rd NaN male 1301 3rd NaN male 1302 3rd NaN male 1303 3rd NaN male 1304 3rd NaN female 1305 3rd NaN male 1306 3rd NaN female 1307 3rd NaN female 1308 3rd NaN male 1309 3rd NaN male 1310 3rd NaN male 1311 3rd NaN female 1312 3rd NaN male[1313 rows x 3 columns] C:\Users\HP\Anaconda3\lib\site-packages\pandas\core\generic.py:6130: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrameSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copyself._update_inplace(new_data) <bound method DictVectorizer.get_feature_names of DictVectorizer(dtype=<class 'numpy.float64'>, separator='=', sort=True,sparse=False)> <bound method DictVectorizer.get_feature_names of DictVectorizer(dtype=<class 'numpy.float64'>, separator='=', sort=True,sparse=False)> [[31.19418104 0. 0. 1. 0. 1. ][31.19418104 1. 0. 0. 1. 0. ][31.19418104 0. 0. 1. 0. 1. ]...[12. 0. 1. 0. 1. 0. ][18. 0. 1. 0. 0. 1. ][31.19418104 0. 0. 1. 1. 0. ]] 預測的準確率 0.7811550151975684precision recall f1-score supportdied 0.91 0.78 0.84 236surveved 0.58 0.80 0.67 93micro avg 0.78 0.78 0.78 329macro avg 0.74 0.79 0.75 329 weighted avg 0.81 0.78 0.79 329Process finished with exit code 0隨機森林
def randomforest():"""隨機森林對泰坦尼克號進行預測生死:return: None"""# 獲取數據titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")# 處理數據,找出特征值和目標值x = titan[['pclass', 'age', 'sex']]y = titan['survived']print(x)# 缺失值處理x['age'].fillna(x['age'].mean(), inplace=True)# 分割數據集到訓練集合測試集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)# 進行處理(特征工程)特征-》類別-》one_hot編碼dict = DictVectorizer(sparse=False)x_train = dict.fit_transform(x_train.to_dict(orient="records"))print(dict.get_feature_names())x_test = dict.transform(x_test.to_dict(orient="records"))rf=RandomForestClassifier()yd=rf.fit(x_train,y_train)y_predit=rf.predict(x_test)param={"n_estimators":[120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}# 網格搜索與交叉驗證gc=GridSearchCV(rf,param_grid=param,cv=2)gc.fit(x_train,y_train)print("準確率:", gc.score(x_test, y_test))print("查看選擇的參數模型:", gc.best_params_)print(classification_report(y_predit, y_test, target_names=['died', 'surveved']))return NoneC:\Users\HP\Anaconda3\python.exe D:/PycharmProjects/untitled2/算法/算法3.pypclass age sex 0 1st 29.0000 female 1 1st 2.0000 female 2 1st 30.0000 male 3 1st 25.0000 female 4 1st 0.9167 male 5 1st 47.0000 male 6 1st 63.0000 female 7 1st 39.0000 male 8 1st 58.0000 female 9 1st 71.0000 male 10 1st 47.0000 male 11 1st 19.0000 female 12 1st NaN female 13 1st NaN male 14 1st NaN male 15 1st 50.0000 female 16 1st 24.0000 male 17 1st 36.0000 male 18 1st 37.0000 male 19 1st 47.0000 female 20 1st 26.0000 male 21 1st 25.0000 male 22 1st 25.0000 male 23 1st 19.0000 female 24 1st 28.0000 male 25 1st 45.0000 male 26 1st 39.0000 male 27 1st 30.0000 female 28 1st 58.0000 female 29 1st NaN male ... ... ... ... 1283 3rd NaN female 1284 3rd NaN male 1285 3rd NaN male 1286 3rd NaN male 1287 3rd NaN male 1288 3rd NaN male 1289 3rd NaN male 1290 3rd NaN male 1291 3rd NaN male 1292 3rd NaN male 1293 3rd NaN female 1294 3rd NaN male 1295 3rd NaN male 1296 3rd NaN male 1297 3rd NaN male 1298 3rd NaN male 1299 3rd NaN male 1300 3rd NaN male 1301 3rd NaN male 1302 3rd NaN male 1303 3rd NaN male 1304 3rd NaN female 1305 3rd NaN male 1306 3rd NaN female 1307 3rd NaN female 1308 3rd NaN male 1309 3rd NaN male 1310 3rd NaN male 1311 3rd NaN female 1312 3rd NaN male[1313 rows x 3 columns] C:\Users\HP\Anaconda3\lib\site-packages\pandas\core\generic.py:6130: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrameSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copyself._update_inplace(new_data) ['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male'] C:\Users\HP\Anaconda3\lib\site-packages\sklearn\ensemble\forest.py:246: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22."10 in version 0.20 to 100 in 0.22.", FutureWarning) 準確率: 0.8419452887537994 查看選擇的參數模型: {'max_depth': 5, 'n_estimators': 1200}precision recall f1-score supportdied 0.92 0.82 0.87 238surveved 0.64 0.81 0.71 91micro avg 0.82 0.82 0.82 329macro avg 0.78 0.82 0.79 329 weighted avg 0.84 0.82 0.83 329Process finished with exit code 0集成方法(分類)之隨機森林
在機器學習中,隨機森林是一個包含多個決策樹的分類器,并且其輸出的類別是由個別樹輸出的類別的眾數而定。利用相同的訓練數搭建多個獨立的分類模型,然后通過投票的方式,以少數服從多數的原則作出最終的分類決策。例如, 如果你訓練了5個樹, 其中有4個樹的結果是True, 1個數的結果是False, 那么最終結果會是True.
在前面的決策當中我們提到,一個標準的決策樹會根據每維特征對預測結果的影響程度進行排序,進而決定不同的特征從上至下構建分裂節點的順序,如此以來,所有在隨機森林中的決策樹都會受這一策略影響而構建的完全一致,從而喪失的多樣性。所以在隨機森林分類器的構建過程中,每一棵決策樹都會放棄這一固定的排序算法,轉而隨機選取特征。
學習算法
根據下列算法而建造每棵樹:
用N來表示訓練用例(樣本)的個數,M表示特征數目。
輸入特征數目m,用于確定決策樹上一個節點的決策結果;其中m應遠小于M。
從N個訓練用例(樣本)中以有放回抽樣的方式,取樣N次,形成一個訓練集(即bootstrap取樣),并用未抽到的用例(樣本)作預測,評估其誤差。
對于每一個節點,隨機選擇m個特征,決策樹上每個節點的決定都是基于這些特征確定的。根據這m個特征,計算其最佳的分裂方式
sklearn.ensemble,集成方法模塊
sklearn.ensemble提供了準確性更加好的集成方法,里面包含了主要的RandomForestClassifier(隨機森林)方法。
class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, oob_score=False, n_jobs=1, random_state=None)""":param n_estimators:integer,optional(default = 10) 森林里的樹木數量。:param criteria:string,可選(default =“gini”)分割特征的測量方法:param max_depth:integer或None,可選(默認=無)樹的最大深度:param bootstrap:boolean,optional(default = True)是否在構建樹時使用自舉樣本。屬性
classes_:shape = [n_classes]的數組或這樣的數組的列表,類標簽(單輸出問題)或類標簽數組列表(多輸出問題)。
featureimportances:array = [n_features]的數組, 特征重要性(越高,功能越重要)。
方法
fit(X,y [,sample_weight]) 從訓練集(X,Y)構建一棵樹林。
predict(X) 預測X的類
score(X,y [,sample_weight]) 返回給定測試數據和標簽的平均精度。
decision_path(X) 返回森林中的決策路徑
集成學習方法
隨機森林優點
總結
- 上一篇: mysql 主键 最佳实践_Spring
- 下一篇: java技术_2020年最流行的Java