機器學習三(學習筆記) 樸素貝葉斯和隨機森林1.2(轉)

一、樸素貝葉斯

樸素貝葉斯(Naive Bayes)是一個非常簡單,但是實用性很強的分類模型。樸素貝葉斯分類器的構造基礎是貝葉斯理論。

img

1、概率論基礎

概率定義爲一件事情發生的可能性。事情發生的概率可以 通過觀測數據中的事件發生次數來計算,事件發生的概率等於改事件發生次數除以所有事件發生的總次數。舉一些例子:

  • 扔出一個硬幣,結果頭像朝上
  • 某天是晴天
  • 某個單詞在未知文檔中出現

我們將事件的概率記作P\left({X}\right)P(X),那麼假設這一事件爲X屬於樣本空間中的一個類別,那麼{0}\le{P}\left({X}\right)\le{1}0≤P(X)≤1。

聯合概率與條件概率

  • 聯合概率

是指兩件事情同時發生的概率。那麼我們假設樣本空間有一些天氣數據:

編號 星期幾 天氣
1 2 晴天
2 1 下雨
3 3 晴天
4 4 晴天
5 1 下雨
6 2 下雪
7 3 下雪

那麼天氣被分成了三類,那麼P\left(X=sun\right){=}\frac{3}{7}P(X=sun)=73,假如說天氣=下雪且星期幾=2?這個概率怎麼求?這個概率應該等於兩件事情爲真的次數除以所有事件發生 的總次數。我們可以看到只有一個樣本滿足天氣=下雪且星期幾=2,所以這個概率爲\frac{1}{7}71。一般對於X和Y來說,對應的聯合概率記爲P\left({XY}\right)P(XY)。

  • 條件概率

那麼條件概率形如P\left({X}\mid{Y}\right)P(X∣Y),這種格式的。表示爲在Y發生的條件下,發生X的概率。假設X代表星期,Y代表天氣,則 P\left({X=3}\mid{Y=sun}\right)P(X=3∣Y=sun)如何求?

從表中我們可以得出,P\left({X=3,Y=sun}\right){=}\frac{1}{7}P(X=3,Y=sun)=71,P\left({Y}\right){=}\frac{3}{7}P(Y)=73

P\left({X=3}\mid{Y=sun}\right){=}\frac{1}{3}{=}\frac{P\left({X=3,Y=sun}\right)}{P\left({Y}\right)}P(X=3∣Y=sun)=31=P(Y)P(X=3,Y=sun)

在條件概率中,有一個重要的特性

  • 如果每個事件之間相互獨立

那麼則有P\left({X_1,X_2,X_3,…,X_n}\mid{Y_i}\right){=}{P}\left({X_1}\mid{Y_i}\right) {P}\left({X_2}\mid{Y_i}\right) {P}\left({X_3}\mid{Y_i}\right){…}{P}\left({X_n}\mid{Y_i}\right)P(X1,X2,X3,…,Xn∣Yi)=P(X1∣Yi)P(X2∣Yi)P(X3∣Yi)…P(Xn∣Yi)

這個式子的意思是給定條件下,所有的X的概率爲單獨的Y條件下每個X發生的概率乘積,我們通過後面再繼續去理解這個式子的具體含義。

貝葉斯公式

首先我們給出該公式的表示

貝葉斯公式最常用於文本分類,上式左邊可以理解爲給定一個文本詞向量WW,那麼它屬於類別c_ici的概率是多少。那麼式子右邊分幾部分,P\left({W}\mid{c_i}\right)P(W∣ci)理解爲在給定類別的情況下,該文檔的詞向量的概率。可以通過條件概率中的重要特性來求解。

假設我們有已分類的文檔,

a = "life is short,i like python"
b = "life is too long,i dislike python"
c = "yes,i like python"
label=[1,0,1]

詞袋法的特徵值計算

若使用詞袋法,且以訓練集中的文本爲詞彙表,即將訓練集中的文本中出現的單詞(不重複)都統計出來作爲詞典,那麼記單詞的數目爲n,這代表了文本的n個維度。以上三個文本在這8個特徵維度上的表示爲:

life is i short long like dislike too python yes
a’ 1 1 1 1 0 1 0 0 1 0
b’ 1 1 1 0 1 0 1 1 1 0
c’ 0 0 1 0 0 1 0 0 1 1

上面a’,b’就是兩個文檔的詞向量的表現形式,對於貝葉斯公式,從label中我們可以得出兩個類別的概率爲:

P\left({c_i=1}\right){=}0.5,P\left({c_i=0}\right){=}0.5P(ci=1)=0.5,P(ci=0)=0.5

對於一個給定的文檔類別,每個單詞特徵向量的概率是多少呢?

提供一種TF計算方法,爲類別y_kyk每個單詞出現的次數N_iNi,除以文檔類別y_kyk中所有單詞出現次數的總數NN:

P_i{=}\frac{N_i}{N}Pi=NNi

首先求出現總數,對於1類別文檔,在a’中,就可得出總數爲1+1+1+1+1+1=6,c’中,總共1+1+1+1=4,故在1類別文檔中總共有10次

每個單詞出現總數,假設是兩個列表,a’+c’就能得出每個單詞出現次數,比如P\left({w=python}\right){=}\frac{2}{10}{=}{0.20000000}P(w=python)=102=0.20000000,同樣可以得到其它的單詞概率。最終結果如下:

# 類別1文檔中的詞向量概率
p1 = [0.10000000,0.10000000,0.20000000,0.10000000,0,0.20000000,0,0,0.20000000,0.10000000]
# 類別0文檔中的詞向量概率
p0 = [0.16666667,0.16666667,0.16666667,0,0.16666667,0,0.16666667,0.16666667,0.16666667,0]

拉普拉斯平滑係數

爲了避免訓練集樣本對一些特徵的缺失,即某一些特徵出現的次數爲0,在計算P\left({X_1,X_2,X_3,…,X_n}\mid{Y_i}\right)P(X1,X2,X3,…,Xn∣Yi)的時候,各個概率相乘最終結果爲零,這樣就會影響結果。我們需要對這個概率計算公式做一個平滑處理:

P_i{=}\frac{N_i+\alpha}{N+\alpha*m}Pi=N+α∗mNi+α

其中mm爲特徵詞向量的個數,\alphaα爲平滑係數,當\alpha{=}1α=1,稱爲拉普拉斯平滑

2、MultinomialNB

class sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
  """
  :param alpha:float,optional(default = 1.0)加法(拉普拉斯/ Lidstone)平滑參數(0爲無平滑)
  """

在這裏插入圖片描述

3、互聯網新聞分類

讀取20類新聞文本的數據細節

from sklearn.datasets import fetch_20newsgroups

news = fetch_20newsgroups(subset='all')

print news.data[0]

上述代碼得出該數據共有18846條新聞,但是這些文本數據既沒有被設定特徵,也沒有數字化的亮度。因此,在交給樸素貝葉斯分類器學習之前,要對數據做進一步的處理。

20類新聞文本數據分割

from sklearn.cross_validation import train_test_split

X_train,X_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25,random_state=42)

文本轉換爲特徵向量進行TF特徵抽取

from sklearn.feature_extraction.text import CountVectorizer

vec = CountVectorizer()
# 訓練數據輸入,並轉換爲特徵向量
X_train = vec.fit_transform(X_train)
# 測試數據轉換
X_test = vec.transform(X_test)

樸素貝葉斯分類器對文本數據進行類別預測

from sklearn.naive_bayes import MultinomialNB

# 使用平滑處理初始化的樸素貝葉斯模型
mnb = MultinomialNB(alpha=1.0)

# 利用訓練數據對模型參數進行估計
mnb.fit(X_train,y_train)

# 對測試驗本進行類別預測。結果存儲在變量y_predict中
y_predict = mnb.predict(X_test)

性能測試

  • 特點分析

樸素貝葉斯模型被廣泛應用於海量互聯網文本分類任務。由於其較強的特徵條件獨立假設,使得模型預測所需要估計的參數規模從冪指數量級想線性量級減少,極大的節約了內存消耗和計算時間。到那時,也正是受這種強假設的限制,模型訓練時無法將各個特徵之間的聯繫考量在內,使得該模型在其他數據特徵關聯性較強的分類任務上的性能表現不佳

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.naive_bayes import MultinomialNB


class Model_SK(object):
    '''K近鄰和貝葉斯的比較'''

    def __init__(self):
        '''
        讀取數據,特徵化處理
        '''

        # 讀取數據
        li = fetch_20newsgroups(subset='all')
        # 進行分割
        self.X_data, self.Y_data, self.X_tar, self.Y_tar = train_test_split(li.data, li.target, test_size=0.2)
        # 進行特徵化抽取
        cv = CountVectorizer()
        # 訓練數據特徵化處理
        self.X_data = cv.fit_transform(self.X_data)
        # 測試數據特徵化處理
        self.Y_data = cv.transform(self.Y_data)

    def k_func(self):
        '''
        K近鄰算法
        :return:
        '''
        # 創建K近鄰模型實例
        knn = KNeighborsClassifier(n_neighbors=10)
        # 訓練模型
        knn.fit(self.X_data, self.X_tar)

        # 獲取模型識別的精確率
        kk = knn.score(self.Y_data, self.Y_tar)

        print('k近鄰的識別成功率:', kk)

    def mnb_func(self):
        '''
        樸素貝葉斯算法
        :return:
        '''
        # 創建貝葉斯模型實例
        mnb = MultinomialNB()

        # 訓練數據
        mnb.fit(self.X_data, self.X_tar)

        # 獲取模型識別的精確率
        kk = mnb.score(self.Y_data, self.Y_tar)

        print('樸素貝葉斯的識別成功率', kk)


if __name__ == '__main__':
    md1 = Model_SK()

    md1.k_func()

    md1.mnb_func()

二、分類決策樹

決策樹是一種基本的分類方法,當然也可以用於迴歸。我們一般只討論用於分類的決策樹。決策樹模型呈樹形結構。在分類問題中,表示基於特徵對實例進行分類的過程,它可以認爲是if-then規則的集合。在決策樹的結構中,每一個實例都被一條路徑或者一條規則所覆蓋。通常決策樹學習包括三個步驟:特徵選擇、決策樹的生成和決策樹的修剪

優點:計算複雜度不高,輸出結果易於理解,對中間值的缺失不敏感,可以處理邏輯迴歸等不能解決的非線性特徵數據

缺點:可能產生過度匹配問題

適用數據類型:數值型和標稱型

1、特徵選擇

特徵選擇在於選取對訓練數據具有分類能力的特徵。這樣可以提高決策樹學習的效率,如果利用一個特徵進行分類的結果與隨機分類的結果沒有很大差別,則稱這個特徵是沒有分類能力的。經驗上扔掉這樣的特徵對決策樹學習的京都影響不大。通常特徵選擇的準則是信息增益,這是個數學概念。通過一個例子來了解特徵選擇的過程。

ID 年齡 有工作 有自己的房子 信貸情況 類別
1 青年 一般
2 青年
3 青年
4 青年 一般
5 青年 一般
6 中年 一般
7 中年
8 中年
9 中年 非常好
10 中年 非常好
11 老年 非常好
12 老年
13 老年
14 老年 非常好
15 老年 一般

我們希望通過所給的訓練數據學習一個貸款申請的決策樹,用以對文萊的貸款申請進行分類,即當新的客戶提出貸款申請是,根據申請人的特徵利用決策樹決定是否批准貸款申請。特徵選擇其實是決定用那個特徵來劃分特徵空間。下圖中分別是按照年齡,還有是否有工作來劃分得到不同的子節點

問題是究竟選擇哪個特徵更好些呢?那麼直觀上,如果一個特徵具有更好的分類能力,是的各個自己在當前的條件下有最好的分類,那麼就更應該選擇這個特徵。信息增益就能很好的表示這一直觀的準則。這樣得到的一棵決策樹只用了兩個特徵就進行了判斷:

通過信息增益生成的決策樹結構,更加明顯、快速的劃分類別。下面介紹scikit-learn中API的使用

2、信息的度量和作用

我們常說信息有用,那麼它的作用如何客觀、定量地體現出來呢?信息用途的背後是否有理論基礎呢?這個問題一直沒有很好的回答,直到1948年,香農在他的論文“通信的數學原理”中提到了“信息熵”的概念,才解決了信息的度量問題,並量化出信息的作用。

一條信息的信息量與其不確定性有着直接的關係,比如我們要搞清一件非常不確定的事,就需要大量的信息。相反如果對某件事瞭解較多,則不需要太多的信息就能把它搞清楚 。所以從這個角度看,可以認爲,信息量就等於不確定的多少。那麼如何量化信息量的度量呢?2022年舉行世界盃,大家很關係誰是冠軍。假如我錯過了看比賽,賽後我問朋友 ,“誰是冠軍”?他不願意直接告訴我,讓我每猜一次給他一塊錢,他告訴我是否猜對了,那麼我需要掏多少錢才能知道誰是冠軍?我可以把球編上號,從1到32,然後提問:冠 軍在1-16號嗎?依次詢問,只需要五次,就可以知道結果。所以誰是世界盃冠軍這條消息只值五塊錢。當然香農不是用錢,而是用“比特”這個概念來度量信息量。一個比特是 一位二進制數,在計算機中一個字節是8比特。

那麼如果說有一天有64支球隊進行決賽階段的比賽,那麼“誰是世界盃冠軍”的信息量就是6比特,因爲要多猜一次,有的同學就會發現,信息量的比特數和所有可能情況的對數函數log有關,(log32=5,log64=6)

另外一方面你也會發現實際上我們不需要猜五次就能纔出冠軍,因爲像西班牙、巴西、德國、意大利這樣的球隊奪得冠軍的可能性比南非、尼日利亞等球隊大得多,因此第一次猜測時不需要把32支球隊等分成兩個組,而可以把少數幾支最有可能的球隊分成一組,把其他球隊分成一組。然後才冠軍球隊是否在那幾支熱門隊中。這樣,也許三次就猜出結果。因此,當每支球隊奪冠的可能性不等時,“誰是世界盃冠軍”的信息量比5比特少。香農指出,它的準確信息量應該是:

H = -(p1logp1 + p2logp2 + … + p32log32)

其中,p1…p32爲這三支球隊奪冠的概率。H的專業術語稱之爲信息熵,單位爲比特,當這32支球隊奪冠的機率相同時,對應的信息熵等於5比特,這個可以通過計算得出。有一個特性就是,5比特是公式的最大值。那麼信息熵(經驗熵)的具體定義可以爲如下:

H\left(X\right){=}\sum_{x\in{X}}P\left(x\right)logP\left(x\right)H(X)=∑x∈XP(x)logP(x)

3、信息增益

自古以來,信息和消除不確定性是相聯繫的。所以決策樹的過程其實是在尋找某一個特徵對整個分類結果的不確定減少的過程。那麼這樣就有一個概念叫做信息增益(information gain)。

那麼信息增益表示得知特徵X的信息而是的類Y的信息的不確定性減少的程度,所以我們對於選擇特徵進行分類的時候,當然選擇信息增益較大的特徵,這樣具有較強的分類能力。特徵A對訓練數據集D的信息增益g(D,A),定義爲集合D的經驗熵H(D)與特徵A給定條件下D的經驗條件熵H(D|A)之差,即公式爲:

g\left({D,A}\right){=}H\left(D\right) {-} H\left(D|A\right)g(D,A)=H(D)−H(D∣A)

根據信息增益的準則的特徵選擇方法是:對於訓練數據集D,計算其每個特徵的信息增益,並比較它們的阿笑,選擇信息增益最大的特徵

信息增益的計算

假設訓練數據集爲D,|D|表示樣本個數。設有K個類C_kCk,k=1,2,3,4…k,|C_k|∣Ck∣爲屬於類C_kCk的樣本個數,\sum_{k=1}^{K}{=}{|D|}∑k=1K=∣D∣.設特徵A有n個不同的取值{a1,a2,…,an},根據特徵A的取值將D劃分爲n個子集D1,D2,…,Dn,|Di|∣Di∣爲樣本個數,其中Di中屬於Ck類的樣本的集合爲D_ikDik

所以首先對於經驗熵來說,計算如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-l54aP4HP-1577722363854)(…/images/經驗熵.png)]

那麼條件熵計算如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-y16EaaZo-1577722363856)(…/images/條件熵.png)]

既然我們有了這兩個公式,我們可以根據前面的是否通過貸款申請的例子來通過計算得出我們的決策特徵順序。那麼我們首先計算總的經驗熵爲:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Dr2LT5kU-1577722363857)(…/images/計算經驗熵.png)]

然後我們讓A_1,A_2,A_3,A_4A1,A2,A3,A4分別表示年齡、有工作、有自己的房子和信貸情況4個特徵,則計算出年齡的信息增益爲:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OGUbGhpA-1577722363858)(…/images/年齡信息增益.png)]

同理其他的也可以計算出來,g(D,A2)=0.324,g(D,A3)=0.420,g(D,A4)=0.363,相比較來說其中特徵A3(有自己的房子)的信息增益最大,所以我們選擇特徵A3爲最有特徵

4、DecisionTreeClassifier

sklearn.tree.DecisionTreeClassifier是一個能對數據集進行多分類的類

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_train)

method

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) 預測輸入數據的類型,完整代碼

estimator.predict(X_test)
array([2, 1, 0, 2, 0, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0,
       0, 1, 0, 0, 1, 1, 0, 2, 1, 0, 1, 2, 1, 0, 2])

print y_test

array([2, 1, 0, 2, 0, 2, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 0,
       0, 2, 0, 0, 1, 1, 0, 2, 1, 0, 2, 2, 1, 0, 1])

score(X,y,sample_weight=None) 返回給定測試數據的準確精度

estimator.score(X_test,y_test)

0.89473684210526316

5、決策樹本地保存

sklearn.tree.export_graphviz() 該函數能夠導出DOT格式

from sklearn.datasets import load_iris
from sklearn import tree
clf = tree.DecisionTreeClassifier()
iris = load_iris()
clf = clf.fit(iris.data, iris.target)
tree.export_graphviz(clf,out_file='tree.dot')

那麼有了tree.dot文件之後,我們可以通過命令轉換爲png或者pdf格式,首先得安裝graphviz

ubuntu:sudo apt-get install graphviz
Mac:brew install graphviz

然後我們運行這個命令

$ dot -Tps tree.dot -o tree.ps
$ dot -Tpng tree.dot -o tree.png

或者,如果我們安裝了Python模塊pydotplus,我們可以直接在Python中生成PDF文件,通過pip install pydotplus,然後運行

import pydotplus
dot_data = tree.export_graphviz(clf, out_file=None)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("iris.pdf")

擴展:所有各種決策樹算法是什麼,它們之間有什麼不同?哪一個在scikit-learn中實現?

ID3 — 信息增益 最大的準則

C4.5 — 信息增益比 最大的準則

CART 迴歸樹: 平方誤差 最小 分類樹: 基尼係數 最小的準則 在sklearn中可以選擇劃分的原則

決策樹優缺點分析

決策樹的一些優點是:

  • 簡單的理解和解釋。樹木可視化。
  • 需要很少的數據準備。其他技術通常需要數據歸一化,需要創建虛擬變量,並刪除空值。但請注意,此模塊不支持缺少值。
  • 使用樹的成本(即,預測數據)在用於訓練樹的數據點的數量上是對數的。

決策樹的缺點包括:

  • 決策樹學習者可以創建不能很好地推廣數據的過於複雜的樹。這被稱爲過擬合。修剪(目前不支持)的機制,設置葉節點所需的最小採樣數或設置樹的最大深度是避免此問題的必要條件。
  • 決策樹可能不穩定,因爲數據的小變化可能會導致完全不同的樹被生成。通過使用合奏中的決策樹來減輕這個問題。

三、集成方法(分類)之隨機森林

在機器學習中,隨機森林是一個包含多個決策樹的分類器,並且其輸出的類別是由個別樹輸出的類別的衆數而定。利用相同的訓練數搭建多個獨立的分類模型,然後通過投票的方式,以少數服從多數的原則作出最終的分類決策。例如, 如果你訓練了5個樹, 其中有4個樹的結果是True, 1個數的結果是False, 那麼最終結果會是True.

在前面的決策當中我們提到,一個標準的決策樹會根據每維特徵對預測結果的影響程度進行排序,進而決定不同的特徵從上至下構建分裂節點的順序,如此以來,所有在隨機森林中的決策樹都會受這一策略影響而構建的完全一致,從而喪失的多樣性。所以在隨機森林分類器的構建過程中,每一棵決策樹都會放棄這一固定的排序算法,轉而隨機選取特徵。

學習算法

根據下列算法而建造每棵樹:

  • 用N來表示訓練用例(樣本)的個數,M表示特徵數目。
  • 輸入特徵數目m,用於確定決策樹上一個節點的決策結果;其中m應遠小於M。
  • 從N個訓練用例(樣本)中以有放回抽樣的方式,取樣N次,形成一個訓練集(即bootstrap取樣),並用未抽到的用例(樣本)作預測,評估其誤差。
  • 對於每一個節點,隨機選擇m個特徵,決策樹上每個節點的決定都是基於這些特徵確定的。根據這m個特徵,計算其最佳的分裂方式。

1、RandomForestClassifier

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)是否在構建樹時使用自舉樣本。

  """

2、屬性

  • classes_:shape = [n_classes]的數組或這樣的數組的列表,類標籤(單輸出問題)或類標籤數組列表(多輸出問題)。

  • featureimportances:array = [n_features]的數組, 特徵重要性(越高,功能越重要)。

3、方法

  • fit(X,y [,sample_weight]) 從訓練集(X,Y)構建一棵樹林。
  • predict(X) 預測X的類
  • score(X,y [,sample_weight]) 返回給定測試數據和標籤的平均精度。
  • decision_path(X) 返回森林中的決策路徑

案例

泰坦尼克號乘客數據

這裏我們通過決策樹和隨機森林對這個數據進行一個分類,判斷乘客的生還。

import pandas as pd
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier


titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')

#選取一些特徵作爲我們劃分的依據
x = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']

# 填充缺失值
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)

dt = DictVectorizer(sparse=False)

print(x_train.to_dict(orient="record"))

# 按行,樣本名字爲鍵,列名也爲鍵,[{"1":1,"2":2,"3":3}]
x_train = dt.fit_transform(x_train.to_dict(orient="record"))

x_test = dt.fit_transform(x_test.to_dict(orient="record"))

# 使用決策樹
dtc = DecisionTreeClassifier()

dtc.fit(x_train, y_train)

dt_predict = dtc.predict(x_test)

print(dtc.score(x_test, y_test))

print(classification_report(y_test, dt_predict, target_names=["died", "survived"]))

# 使用隨機森林

rfc = RandomForestClassifier()

rfc.fit(x_train, y_train)

rfc_y_predict = rfc.predict(x_test)

print(rfc.score(x_test, y_test))

print(classification_report(y_test, rfc_y_predict, target_names=["died", "survived"]))

四、分類算法之邏輯迴歸

邏輯迴歸(Logistic Regression),簡稱LR。它的特點是能夠是我們的特徵輸入集合轉化爲0和1這兩類的概率。一般來說,迴歸不用在分類問題上,因爲迴歸是連續型模型,而且受噪聲影響比較大。如果非要應用進入,可以使用邏輯迴歸。瞭解過線性迴歸之後再來看邏輯迴歸可以更好的理解。

優點:計算代價不高,易於理解和實現

缺點:容易欠擬合,分類精度不高

適用數據:數值型和標稱型

對於迴歸問題後面會介紹,Logistic迴歸本質上是線性迴歸,只是在特徵到結果的映射中加入了一層函數映射,即先把特徵線性求和,然後使用函數g(z)將最爲假設函數來預測。g(z)可以將連續值映射到0和1上。Logistic迴歸用來分類0/1問題,也就是預測結果屬於0或者1的二值分類問題

映射函數爲:

g\left({z}\right){=}\frac{1}{1+e^-z}g(z)=1+e−z1

其中z{=}\theta_{0}+\theta_{1}{x_{1}}+\theta_{2}{x_{2}}{+…}z=θ0+θ1x1+θ2x2+…

映射出來的效果如下如:

1、LogisticRegression

LogisticRegression類的各項參數的含義

class sklearn.linear_model.LogisticRegression(penalty='l2', 
          dual=False, tol=0.0001, C=1.0, fit_intercept=True, 
          intercept_scaling=1, class_weight=None, 
          random_state=None, solver='liblinear', max_iter=100, 
          multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
  • penalty='l2': 字符串‘l1’或‘l2’,默認‘l2’。

    • 用來指定懲罰的基準(正則化參數)。只有‘l2’支持‘newton-cg’、‘sag’和‘lbfgs’這三種算法。
    • 如果選擇‘l2’,solver參數可以選擇‘liblinear’、‘newton-cg’、‘sag’和‘lbfgs’這四種算法;如果選擇‘l1’的話就只能用‘liblinear’算法。
  • dual=False : 對偶或者原始方法。Dual只適用於正則化相爲l2的‘liblinear’的情況,通常樣本數大於特徵數的情況下,默認爲False。

  • C=1.0 : C爲正則化係數λ的倒數,必須爲正數,默認爲1。和SVM中的C一樣,值越小,代表正則化越強。

  • fit_intercept=True : 是否存在截距,默認存在。

  • intercept_scaling=1 : 僅在正則化項爲‘liblinear’,且fit_intercept設置爲True時有用。

  • solver='liblinear'
    

    : solver參數決定了我們對邏輯迴歸損失函數的優化方法,有四種算法可以選擇。

    • a) liblinear:使用了開源的liblinear庫實現,內部使用了座標軸下降法來迭代優化損失函數。
    • b) lbfgs:擬牛頓法的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
    • c) newton-cg:也是牛頓法家族的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
    • d) sag:即隨機平均梯度下降,是梯度下降法的變種,和普通梯度下降法的區別是每次迭代僅僅用一部分的樣本來計算梯度,適合於樣本數據多的時候。

LogisticRegression類的常用方法

  • fit(X, y, sample_weight=None)
    
    • 擬合模型,用來訓練LR分類器,其中X是訓練樣本,y是對應的標記向量
    • 返回對象,self。
  • fit_transform(X, y=None, **fit_params)
    
    • fit與transform的結合,先fit後transform。返回X_new:numpy矩陣。
  • predict(X)
    
    • 用來預測樣本,也就是分類,X是測試集。返回array。
  • predict_proba(X)
    
    • 輸出分類概率。返回每種類別的概率,按照分類類別順序給出。如果是多分類問題,multi_class=“multinomial”,則會給出樣本對於每種類別的概率。
    • 返回array-like。
  • score(X, y, sample_weight=None)
    
    • 返回給定測試集合的平均準確率(mean accuracy),浮點型數值。
    • 對於多個分類返回,則返回每個類別的準確率組成的哈希矩陣。

2、邏輯迴歸案例

良/惡性乳腺癌腫瘤預測

原始數據的下載地址爲:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/

數據預處理

import pandas as pd
import numpy as np

# 根據官方數據構建類別
column_names = ['Sample code number','Clump Thickness','Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion','Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class'],

data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/',names = column_names)

# 將?替換成標準缺失值表示
data = data.replace(to_replace='?',value = np.nan)

# 丟棄帶有缺失值的數據(只要一個維度有缺失)
data = data.dropna(how='any')

data.shape

處理的缺失值後的樣本共有683條,特徵包括細胞厚度、細胞大小、形狀等九個維度

準備訓練測試數據

from sklearn.cross_validation import train_test_split

X_train,X_test,y_train,y_test = train_test_split(data[column_names[1:10]],data[column_names[10]],test_size=0.25,random_state=42)

# 查看訓練和測試樣本的數量和類別分佈
y_train.value_counts()

y_test.value_counts()

使用邏輯迴歸進行良/惡性腫瘤預測任務

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression


# 標準化數據,保證每個維度的特徵數據方差爲1,均值爲0。使得預測結果不會被某些維度過大的特徵值而主導
ss = StandardScaler()

X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)

# 初始化 LogisticRegression

lr = LogisticRegression(C=1.0, penalty='l1', tol=0.01)

# 跳用LogisticRegression中的fit函數/模塊來訓練模型參數
lr.fit(X_train,y_train)

lr_y_predict = lr.predict(X_test)

性能分析

from sklearn.metrics import classification_report

# 利用邏輯斯蒂迴歸自帶的評分函數score獲得模型在測試集上的準確定結果
print '精確率爲:',lr.score(X_test,y_test)

print classification_report(y_test,lr_y_predict,target_names = ['Benign','Maligant'])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章