爲慈善機構尋找捐助者

 

 

 

 

機器學習納米學位

監督學習

項目2: 爲CharityML尋找捐獻者

 

歡迎來到機器學習工程師納米學位的第二個項目!在此文件中,有些示例代碼已經提供給你,但你還須要實現更多的功能讓項目成功運行。除非有明確要求,你無須修改任何已給出的代碼。以'練習'開始的標題表示接下來的代碼部分中有你必需要實現的功能。每一部分都會有詳細的指導,須要實現的部分也會在註釋中以'TODO'標出。請仔細閱讀全部的提示!javascript

除了實現代碼外,你還必須回答一些與項目和你的實現有關的問題。每個須要你回答的問題都會以'問題 X'爲標題。請仔細閱讀每一個問題,而且在問題後的'回答'文字框中寫出完整的答案。咱們將根據你對問題的回答和撰寫代碼所實現的功能來對你提交的項目進行評分。css

提示:Code 和 Markdown 區域可經過Shift + Enter快捷鍵運行。此外,Markdown能夠經過雙擊進入編輯模式。html

 

開始

在這個項目中,你將使用1994年美國人口普查收集的數據,選用幾個監督學習算法以準確地建模被調查者的收入。而後,你將根據初步結果從中選擇出最佳的候選算法,並進一步優化該算法以最好地建模這些數據。你的目標是創建一個可以準確地預測被調查者年收入是否超過50000美圓的模型。這種類型的任務會出如今那些依賴於捐款而存在的非營利性組織。瞭解人羣的收入狀況能夠幫助一個非營利性的機構更好地瞭解他們要多大的捐贈,或是否他們應該接觸這些人。雖然咱們很難直接從公開的資源中推斷出一我的的通常收入階層,可是咱們能夠(也正是咱們將要作的)從其餘的一些公開的可得到的資源中得到一些特徵從而推斷出該值。html5

這個項目的數據集來自UCI機器學習知識庫。這個數據集是由Ron Kohavi和Barry Becker在發表文章_"Scaling Up the Accuracy of Naive-Bayes Classifiers: A Decision-Tree Hybrid"_以後捐贈的,你能夠在Ron Kohavi提供的在線版本中找到這個文章。咱們在這裏探索的數據集相比於原有的數據集有一些小小的改變,好比說移除了特徵'fnlwgt' 以及一些遺失的或者是格式不正確的記錄。java

 

探索數據

運行下面的代碼單元以載入須要的Python庫並導入人口普查數據。注意數據集的最後一列'income'將是咱們須要預測的列(表示被調查者的年收入會大於或者是最多50,000美圓),人口普查數據中的每一列都將是關於被調查者的特徵。python

In [2]:
# 檢查你的Python版本
from sys import version_info
if version_info.major != 2 and version_info.minor != 7:
    raise Exception('請使用Python 2.7來完成此項目')
In [6]:
# 爲這個項目導入須要的庫
import numpy as np
import pandas as pd
from time import time
from IPython.display import display # 容許爲DataFrame使用display()

# 導入附加的可視化代碼visuals.py
import visuals as vs

# 爲notebook提供更加漂亮的可視化
%matplotlib inline

# 導入人口普查數據
data = pd.read_csv("census.csv")

# 成功 - 顯示第一條記錄
display(data.head(n=10))
 
 
  age workclass education_level education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country income
0 39 State-gov Bachelors 13.0 Never-married Adm-clerical Not-in-family White Male 2174.0 0.0 40.0 United-States <=50K
1 50 Self-emp-not-inc Bachelors 13.0 Married-civ-spouse Exec-managerial Husband White Male 0.0 0.0 13.0 United-States <=50K
2 38 Private HS-grad 9.0 Divorced Handlers-cleaners Not-in-family White Male 0.0 0.0 40.0 United-States <=50K
3 53 Private 11th 7.0 Married-civ-spouse Handlers-cleaners Husband Black Male 0.0 0.0 40.0 United-States <=50K
4 28 Private Bachelors 13.0 Married-civ-spouse Prof-specialty Wife Black Female 0.0 0.0 40.0 Cuba <=50K
5 37 Private Masters 14.0 Married-civ-spouse Exec-managerial Wife White Female 0.0 0.0 40.0 United-States <=50K
6 49 Private 9th 5.0 Married-spouse-absent Other-service Not-in-family Black Female 0.0 0.0 16.0 Jamaica <=50K
7 52 Self-emp-not-inc HS-grad 9.0 Married-civ-spouse Exec-managerial Husband White Male 0.0 0.0 45.0 United-States >50K
8 31 Private Masters 14.0 Never-married Prof-specialty Not-in-family White Female 14084.0 0.0 50.0 United-States >50K
9 42 Private Bachelors 13.0 Married-civ-spouse Exec-managerial Husband White Male 5178.0 0.0 40.0 United-States >50K
 

練習:數據探索

首先咱們對數據集進行一個粗略的探索,咱們將看看每個類別裏會有多少被調查者?而且告訴咱們這些裏面多大比例是年收入大於50,000美圓的。在下面的代碼單元中,你將須要計算如下量:jquery

  • 總的記錄數量,'n_records'
  • 年收入大於50,000美圓的人數,'n_greater_50k'.
  • 年收入最多爲50,000美圓的人數 'n_at_most_50k'.
  • 年收入大於50,000美圓的人所佔的比例, 'greater_percent'.

提示: 您可能須要查看上面的生成的表,以瞭解'income'條目的格式是什麼樣的。linux

In [12]:
# TODO:總的記錄數
n_records = len(data)

# TODO:被調查者的收入大於$50,000的人數
n_greater_50k = len(data[data.income == '>50K'])

# TODO:被調查者的收入最多爲$50,000的人數
n_at_most_50k = len(data[data.income == '<=50K'])

# TODO:被調查者收入大於$50,000所佔的比例
greater_percent = float(n_greater_50k)/n_records*100

# 打印結果
print "Total number of records: {}".format(n_records)
print "Individuals making more than $50,000: {}".format(n_greater_50k)
print "Individuals making at most $50,000: {}".format(n_at_most_50k)
print "Percentage of individuals making more than $50,000: {:.2f}%".format(greater_percent)
 
Total number of records: 45222
Individuals making more than $50,000: 11208
Individuals making at most $50,000: 34014
Percentage of individuals making more than $50,000: 24.78%
 

準備數據

在數據可以被做爲輸入提供給機器學習算法以前,它常常須要被清洗,格式化,和從新組織 - 這一般被叫作預處理。幸運的是,對於這個數據集,沒有咱們必須處理的無效或丟失的條目,然而,因爲某一些特徵存在的特性咱們必須進行必定的調整。這個預處理均可以極大地幫助咱們提高几乎全部的學習算法的結果和預測能力。android

得到特徵和標籤

income 列是咱們須要的標籤,記錄一我的的年收入是否高於50K。 所以咱們應該把他從數據中剝離出來,單獨存放。css3

In [13]:
# 將數據切分紅特徵和對應的標籤
income_raw = data['income']
features_raw = data.drop('income', axis = 1)
 

轉換傾斜的連續特徵

一個數據集有時可能包含至少一個靠近某個數字的特徵,但有時也會有一些相對來講存在極大值或者極小值的不平凡分佈的的特徵。算法對這種分佈的數據會十分敏感,而且若是這種數據沒有可以很好地規一化處理會使得算法表現不佳。在人口普查數據集的兩個特徵符合這個描述:'capital-gain''capital-loss'

運行下面的代碼單元以建立一個關於這兩個特徵的條形圖。請注意當前的值的範圍和它們是如何分佈的。

In [14]:
# 可視化 'capital-gain'和'capital-loss' 兩個特徵
vs.distribution(features_raw)
 
 

對於高度傾斜分佈的特徵如'capital-gain''capital-loss',常見的作法是對數據施加一個對數轉換,將數據轉換成對數,這樣很是大和很是小的值不會對學習算法產生負面的影響。而且使用對數變換顯著下降了因爲異常值所形成的數據範圍異常。可是在應用這個變換時必須當心:由於0的對數是沒有定義的,因此咱們必須先將數據處理成一個比0稍微大一點的數以成功完成對數轉換。

運行下面的代碼單元來執行數據的轉換和可視化結果。再次,注意值的範圍和它們是如何分佈的。

In [15]:
# 對於傾斜的數據使用Log轉換
skewed = ['capital-gain', 'capital-loss']
features_raw[skewed] = data[skewed].apply(lambda x: np.log(x + 1))

# 可視化對數轉換後 'capital-gain'和'capital-loss' 兩個特徵
vs.distribution(features_raw, transformed = True)
 
 

規一化數字特徵

除了對於高度傾斜的特徵施加轉換,對數值特徵施加一些形式的縮放一般會是一個好的習慣。在數據上面施加一個縮放並不會改變數據分佈的形式(好比上面說的'capital-gain' or 'capital-loss');可是,規一化保證了每個特徵在使用監督學習器的時候可以被平等的對待。注意一旦使用了縮放,觀察數據的原始形式再也不具備它原本的意義了,就像下面的例子展現的。

運行下面的代碼單元來規一化每個數字特徵。咱們將使用sklearn.preprocessing.MinMaxScaler來完成這個任務。

In [16]:
from sklearn.preprocessing import MinMaxScaler

# 初始化一個 scaler,並將它施加到特徵上
scaler = MinMaxScaler()
numerical = ['age', 'education-num', 'capital-gain', 'capital-loss', 'hours-per-week']
features_raw[numerical] = scaler.fit_transform(data[numerical])

# 顯示一個通過縮放的樣例記錄
display(features_raw.head(n = 1))
 
 
  age workclass education_level education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country
0 0.30137 State-gov Bachelors 0.8 Never-married Adm-clerical Not-in-family White Male 0.02174 0.0 0.397959 United-States
 

練習:數據預處理

從上面的數據探索中的表中,咱們能夠看到有幾個屬性的每一條記錄都是非數字的。一般狀況下,學習算法指望輸入是數字的,這要求非數字的特徵(稱爲類別變量)被轉換。轉換類別變量的一種流行的方法是使用獨熱編碼方案。獨熱編碼爲每個非數字特徵的每個可能的類別建立一個_「虛擬」_變量。例如,假設someFeature有三個可能的取值AB或者C,。咱們將把這個特徵編碼成someFeature_A, someFeature_BsomeFeature_C.

特徵X   特徵X_A 特徵X_B 特徵X_C
B   0 1 0
C ----> 獨熱編碼 ----> 0 0 1
A   1 0 0

此外,對於非數字的特徵,咱們須要將非數字的標籤'income'轉換成數值以保證學習算法可以正常工做。由於這個標籤只有兩種可能的類別("<=50K"和">50K"),咱們沒必要要使用獨熱編碼,能夠直接將他們編碼分別成兩個類01,在下面的代碼單元中你將實現如下功能:

  • 使用pandas.get_dummies()'features_raw'數據來施加一個獨熱編碼。
  • 將目標標籤'income_raw'轉換成數字項。
    • 將"<=50K"轉換成0;將">50K"轉換成1
In [18]:
# TODO:使用pandas.get_dummies()對'features_raw'數據進行獨熱編碼
features = pd.get_dummies(features_raw)

# TODO:將'income_raw'編碼成數字值
from sklearn import preprocessing
income = pd.Series(preprocessing.LabelEncoder().fit_transform(income_raw))

# 打印通過獨熱編碼以後的特徵數量
encoded = list(features.columns)
print "{} total features after one-hot encoding.".format(len(encoded))

# 移除下面一行的註釋以觀察編碼的特徵名字
#print encoded
 
103 total features after one-hot encoding.
 

混洗和切分數據

如今全部的 類別變量 已被轉換成數值特徵,並且全部的數值特徵已被規一化。和咱們通常狀況下作的同樣,咱們如今將數據(包括特徵和它們的標籤)切分紅訓練和測試集。其中80%的數據將用於訓練和20%的數據用於測試。而後再進一步把訓練數據分爲訓練集和驗證集,用來選擇和優化模型。

運行下面的代碼單元來完成切分。

In [19]:
# 導入 train_test_split
from sklearn.model_selection import train_test_split

# 將'features'和'income'數據切分紅訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(features, income, test_size = 0.2, random_state = 0,
                                                    stratify = income)
# 將'X_train'和'y_train'進一步切分爲訓練集和驗證集
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=0,
                                                    stratify = y_train)

# 顯示切分的結果
print "Training set has {} samples.".format(X_train.shape[0])
print "Validation set has {} samples.".format(X_val.shape[0])
print "Testing set has {} samples.".format(X_test.shape[0])
 
Training set has 28941 samples.
Validation set has 7236 samples.
Testing set has 9045 samples.
 

評價模型性能

在這一部分中,咱們將嘗試四種不一樣的算法,並肯定哪個可以最好地建模數據。四種算法包含一個天真的預測器 和三個你選擇的監督學習器。

 

評價方法和樸素的預測器

CharityML經過他們的研究人員知道被調查者的年收入大於\$50,000最有可能向他們捐款。由於這個緣由*CharityML*對於準確預測誰可以得到\$50,000以上收入尤爲有興趣。這樣看起來使用準確率做爲評價模型的標準是合適的。另外,把沒有收入大於\$50,000的人識別成年收入大於\$50,000對於CharityML來講是有害的,由於他想要找到的是有意願捐款的用戶。這樣,咱們指望的模型具備準確預測那些可以年收入大於\$50,000的能力比模型去查全這些被調查者更重要。咱們可以使用F-beta score做爲評價指標,這樣可以同時考慮查準率和查全率:

$$ F_{\beta} = (1 + \beta^2) \cdot \frac{precision \cdot recall}{\left( \beta^2 \cdot precision \right) + recall} $$

尤爲是,當 $\beta = 0.5$ 的時候更多的強調查準率,這叫作F$_{0.5}$ score (或者爲了簡單叫作F-score)。

 

問題 1 - 天真的預測器的性能

經過查看收入超過和不超過 \$50,000 的人數,咱們能發現多數被調查者年收入沒有超過 \$50,000。若是咱們簡單地預測說「這我的的收入沒有超過 \$50,000」,咱們就能夠獲得一個 準確率超過 50% 的預測。這樣咱們甚至不用看數據就能作到一個準確率超過 50%。這樣一個預測被稱做是天真的。一般對數據使用一個天真的預測器是十分重要的,這樣可以幫助創建一個模型表現是否好的基準。 使用下面的代碼單元計算天真的預測器的相關性能。將你的計算結果賦值給'accuracy', ‘precision’, ‘recall’'fscore',這些值會在後面被使用,請注意這裏不能使用scikit-learn,你須要根據公式本身實現相關計算。

若是咱們選擇一個不管什麼狀況都預測被調查者年收入大於 \$50,000 的模型,那麼這個模型在驗證集上的準確率,查準率,查全率和 F-score是多少?

In [29]:
#不能使用scikit-learn,你須要根據公式本身實現相關計算。

# 假陽性FP
FP = float(len(y_val[y_val == 0]))
# 真陽性TP
TP = float(len(y_val[y_val == 1]))
# 假陰性
FN = 0

#TODO: 計算準確率
accuracy = TP/len(y_val)

# TODO: 計算查準率 Precision
precision = TP / (TP+FP)

# TODO: 計算查全率 Recall
recall = TP / (TP+FN)

# TODO: 使用上面的公式,設置beta=0.5,計算F-score
fscore = (1+0.5**2) * ( (precision*recall) / (0.5**2*precision + recall) )

# 打印結果
print "Naive Predictor on validation data: \n\
    Accuracy score: {:.4f} \n\
    Precision: {:.4f} \n\
    Recall: {:.4f} \n\
    F-score: {:.4f}".format(accuracy, precision, recall, fscore)
 
Naive Predictor on validation data: 
     Accuracy score: 0.2478 
     Precision: 0.2478 
     Recall: 1.0000 
     F-score: 0.2917
 

監督學習模型

問題 2 - 模型應用

你可以在 scikit-learn 中選擇如下監督學習模型

  • 高斯樸素貝葉斯 (GaussianNB)
  • 決策樹 (DecisionTree)
  • 集成方法 (Bagging, AdaBoost, Random Forest, Gradient Boosting)
  • K近鄰 (K Nearest Neighbors)
  • 隨機梯度降低分類器 (SGDC)
  • 支撐向量機 (SVM)
  • Logistic迴歸(LogisticRegression)

從上面的監督學習模型中選擇三個適合咱們這個問題的模型,並回答相應問題。

 

模型1

模型名稱

回答:k近鄰

描述一個該模型在真實世界的一個應用場景。(你須要爲此作點研究,並給出你的引用出處)

回答: 使用k近鄰分類海倫的約會對象,將其分爲3類

參考文章:http://www.javashuo.com/article/p-yuwdaqgq-ba.html

這個模型的優點是什麼?他什麼狀況下表現最好?

回答: 1.簡單,容易理解,精度高,對異常數據不敏感。 2.目標變量是數值型且有限

這個模型的缺點是什麼?什麼條件下它表現不好?

回答: 1.計算複雜度高,空間複雜度高,樣本不平衡 2.數值很大時

根據咱們當前數據集的特色,爲何這個模型適合這個問題。

回答: 1.數值可能存在異常值,k近鄰能夠下降對異常值的敏感程度 2.二分類問題,k值能夠選爲奇數 3.數據量不是很大

 

模型2

模型名稱

回答:集成方法(Random Forest)

描述一個該模型在真實世界的一個應用場景。(你須要爲此作點研究,並給出你的引用出處)

回答:手寫體數字識別

網址:http://www.javashuo.com/article/p-rjfuhvgz-bc.html

這個模型的優點是什麼?他什麼狀況下表現最好?

回答: 1.能夠處理高維數據,能夠不用進行特徵篩選,很是容易進行分佈式處理,實現起來很是高效

2.可以評估各個特徵在分類問題上的重要性

這個模型的缺點是什麼?什麼條件下它表現不好?

回答: 1.樹越多,隨機森林的表現纔會越穩定。實際應用中樹很少可能致使不穩定。

2.不平衡數據集

根據咱們當前數據集的特色,爲何這個模型適合這個問題。

回答:數據維度較高,處理起來很合適

 

模型3

模型名稱

回答:決策樹

描述一個該模型在真實世界的一個應用場景。(你須要爲此作點研究,並給出你的引用出處)

回答: 鳶尾花分類

參考地址:http://blog.csdn.net/rongrongyaofeiqi/article/details/52872957

這個模型的優點是什麼?他什麼狀況下表現最好?

回答: 1.理解和解釋起來簡單,且決策樹模型能夠想象,可以處理多輸出的問題。

2.可以生成清晰的基於特徵(feature)選擇不一樣預測結果的樹狀結構

這個模型的缺點是什麼?什麼條件下它表現不好?

回答: 1.決策樹的結果多是不穩定

2.人爲的改變一些特徵,使分類器錯誤

根據咱們當前數據集的特色,爲何這個模型適合這個問題。

回答:

1.數據量不是很大 2.能夠選擇特徵條件進行分類

 

練習 - 建立一個訓練和預測的流水線

爲了正確評估你選擇的每個模型的性能,建立一個可以幫助你快速有效地使用不一樣大小的訓練集並在驗證集上作預測的訓練和驗證的流水線是十分重要的。 你在這裏實現的功能將會在接下來的部分中被用到。在下面的代碼單元中,你將實現如下功能:

  • sklearn.metrics中導入fbeta_scoreaccuracy_score
  • 用訓練集擬合學習器,並記錄訓練時間。
  • 對訓練集的前300個數據點和驗證集進行預測並記錄預測時間。
  • 計算預測訓練集的前300個數據點的準確率和F-score。
  • 計算預測驗證集的準確率和F-score。
In [23]:
# TODO:從sklearn中導入兩個評價指標 - fbeta_score和accuracy_score
from sklearn.metrics import fbeta_score, accuracy_score

def train_predict(learner, sample_size, X_train, y_train, X_val, y_val): 
    '''
    inputs:
       - learner: the learning algorithm to be trained and predicted on
       - sample_size: the size of samples (number) to be drawn from training set
       - X_train: features training set
       - y_train: income training set
       - X_val: features validation set
       - y_val: income validation set
    '''
    
    results = {}
    
    # TODO:使用sample_size大小的訓練數據來擬合學習器
    # TODO: Fit the learner to the training data using slicing with 'sample_size'
    start = time() # 得到程序開始時間
    learner = learner.fit(X_train[:sample_size],y_train[:sample_size])
    end = time() # 得到程序結束時間
    
    # TODO:計算訓練時間
    results['train_time'] = end - start
    
    # TODO: 獲得在驗證集上的預測值
    #       而後獲得對前300個訓練數據的預測結果
    start = time() # 得到程序開始時間
    predictions_val = learner.predict(X_val)
    predictions_train = learner.predict(X_train[:300])
    end = time() # 得到程序結束時間
    
    # TODO:計算預測用時
    results['pred_time'] = end - start
            
    # TODO:計算在最前面的300個訓練數據的準確率
    results['acc_train'] = accuracy_score(y_train[:300],predictions_train)
        
    # TODO:計算在驗證上的準確率
    results['acc_val'] = accuracy_score(y_val,predictions_val)
    
    # TODO:計算在最前面300個訓練數據上的F-score
    results['f_train'] = fbeta_score(y_train[:300],predictions_train, beta=0.5)
        
    # TODO:計算驗證集上的F-score
    results['f_val'] = fbeta_score(y_val,predictions_val, beta=0.5)
       
    # 成功
    print "{} trained on {} samples.".format(learner.__class__.__name__, sample_size)
        
    # 返回結果
    return results
 

練習:初始模型的評估

在下面的代碼單元中,您將須要實現如下功能:

  • 導入你在前面討論的三個監督學習模型。
  • 初始化三個模型並存儲在'clf_A''clf_B''clf_C'中。
    • 使用模型的默認參數值,在接下來的部分中你將須要對某一個模型的參數進行調整。
    • 設置random_state (若是有這個參數)。
  • 計算1%, 10%, 100%的訓練數據分別對應多少個數據點,並將這些值存儲在'samples_1', 'samples_10', 'samples_100'

注意:取決於你選擇的算法,下面實現的代碼可能須要一些時間來運行!

In [51]:
# TODO:從sklearn中導入三個監督學習模型
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
#from sklearn.svm import SVC
#from sklearn.naive_bayes import GaussianNB
from sklearn import tree
#from sklearn import linear_model
#from sklearn.linear_model import LogisticRegression
#from sklearn.ensemble import BaggingClassifier

# TODO:初始化三個模型
clf_A = KNeighborsClassifier(n_neighbors=3)
clf_B = RandomForestClassifier(random_state=2)
clf_C = tree.DecisionTreeClassifier()
#clf_C = GaussianNB()
#clf_C = SVC(kernel='linear')
#clf_C = linear_model.SGDClassifier()


# TODO:計算1%, 10%, 100%的訓練數據分別對應多少點
samples_1 = int( len(X_train)*0.01 )
samples_10 = int( len(X_train)*0.1 )
samples_100 = len(X_train)

# 收集學習器的結果
results = {}
for clf in [clf_A, clf_B, clf_C]:
    clf_name = clf.__class__.__name__
    results[clf_name] = {}
    for i, samples in enumerate([samples_1, samples_10, samples_100]):
        results[clf_name][i] = train_predict(clf, samples, X_train, y_train, X_val, y_val)

# 對選擇的三個模型獲得的評價結果進行可視化
vs.evaluate(results, accuracy, fscore)
 
KNeighborsClassifier trained on 289 samples.
KNeighborsClassifier trained on 2894 samples.
KNeighborsClassifier trained on 28941 samples.
RandomForestClassifier trained on 289 samples.
RandomForestClassifier trained on 2894 samples.
RandomForestClassifier trained on 28941 samples.
DecisionTreeClassifier trained on 289 samples.
DecisionTreeClassifier trained on 2894 samples.
DecisionTreeClassifier trained on 28941 samples.
 
 

提升效果

在這最後一節中,您將從三個有監督的學習模型中選擇 最好的 模型來使用學生數據。你將在整個訓練集(X_trainy_train)上使用網格搜索優化至少調節一個參數以得到一個比沒有調節以前更好的 F-score。

 

問題 3 - 選擇最佳的模型

基於你前面作的評價,用一到兩段話向 CharityML 解釋這三個模型中哪個對於判斷被調查者的年收入大於 \$50,000 是最合適的。
提示:你的答案應該包括評價指標,預測/訓練時間,以及該算法是否適合這裏的數據。

 

回答:

1.從準確度上上看,DecisionTree在1%和100%訓練集上表現最好,DecisionTree和RandomForest在10%訓練集上表現同樣好,RandomForest在全部的驗證集表現最好

2.從F-score上看,RandomForest在1%訓練集上和全部的驗證集表現最好,DecisionTree和RandomForest在10%訓練集上表現同樣好

3.從訓練時間上來看,KNeighbors最多,RandomForest中間,DecisionTree最少

4.從預測時間上來看,KNeighbors明顯多與其餘兩種算法

5.綜上所述RandomForest綜合表現較好,所需時間少分類準,雖然DecisionTree在訓練集上表現好,可是驗證集上表現差,說明有過擬合。因此RandomForest最合適。

 

問題 4 - 用通俗的話解釋模型

用一到兩段話,向 CharityML 用外行也聽得懂的話來解釋最終模型是如何工做的。你須要解釋所選模型的主要特色。例如,這個模型是怎樣被訓練的,它又是如何作出預測的。避免使用高級的數學或技術術語,不要使用公式或特定的算法名詞。

 

回答: 1.訓練:對全部數據找到最大程度區分當前數據的特徵,而後按照此特徵的條件進行數據分割,對分割的數據重複此步驟,直到全部特徵判斷完。這樣的判斷構成決策樹。

2.因爲單個決策樹,依賴分類參數選擇嚴重,因此重複1對樣本進行隨機有放回的抽樣產生多個決策樹,這些決策樹合併起來就是隨機森林

 

練習:模型調優

調節選擇的模型的參數。使用網格搜索(GridSearchCV)來至少調整模型的重要參數(至少調整一個),這個參數至少需嘗試3個不一樣的值。你要使用整個訓練集來完成這個過程。在接下來的代碼單元中,你須要實現如下功能:

  • 導入sklearn.model_selection.GridSearchCVsklearn.metrics.make_scorer.
  • 初始化你選擇的分類器,並將其存儲在clf中。
    • 設置random_state (若是有這個參數)。
  • 建立一個對於這個模型你但願調整參數的字典。
    • 例如: parameters = {'parameter' : [list of values]}。
    • 注意: 若是你的學習器有 max_features 參數,請不要調節它!
  • 使用make_scorer來建立一個fbeta_score評分對象(設置$\beta = 0.5$)。
  • 在分類器clf上用'scorer'做爲評價函數運行網格搜索,並將結果存儲在grid_obj中。
  • 用訓練集(X_train, y_train)訓練grid search object,並將結果存儲在grid_fit中。

注意: 取決於你選擇的參數列表,下面實現的代碼可能須要花一些時間運行!

In [35]:
# TODO:導入'GridSearchCV', 'make_scorer'和其餘一些須要的庫
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import fbeta_score,make_scorer
# TODO:初始化分類器
clf = RandomForestClassifier(random_state=2)

# TODO:建立你但願調節的參數列表
parameters = {'n_estimators':[1,12,55,100]}

# TODO:建立一個fbeta_score打分對象
scorer = make_scorer(fbeta_score, beta=0.5)

# TODO:在分類器上使用網格搜索,使用'scorer'做爲評價函數
grid_obj = GridSearchCV(clf, parameters, scorer)

# TODO:用訓練數據擬合網格搜索對象並找到最佳參數
grid_obj = grid_obj.fit(X_train, y_train)

# 獲得estimator
best_clf = grid_obj.best_estimator_

# 使用沒有調優的模型作預測
predictions = (clf.fit(X_train, y_train)).predict(X_val)
# 使用調優的模型作預測
best_predictions = best_clf.predict(X_val)

# 彙報調參前和調參後的分數
print "Unoptimized model\n------"
print "Accuracy score on validation data: {:.4f}".format(accuracy_score(y_val, predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, predictions, beta = 0.5))
print "\nOptimized Model\n------"
print "Final accuracy score on the validation data: {:.4f}".format(accuracy_score(y_val, best_predictions))
print "Final F-score on the validation data: {:.4f}".format(fbeta_score(y_val, best_predictions, beta = 0.5))
 
Unoptimized model
------
Accuracy score on validation data: 0.8401
F-score on validation data: 0.6844

Optimized Model
------
Final accuracy score on the validation data: 0.8467
Final F-score on the validation data: 0.6967
 

問題 5 - 最終模型評估

你的最優模型在測試數據上的準確率和 F-score 是多少?這些分數比沒有優化的模型好仍是差?你優化的結果相比於你在問題 1中獲得的天真預測器怎麼樣?
注意:請在下面的表格中填寫你的結果,而後在答案框中提供討論。

 

結果:

評價指標 天真預測器 未優化的模型 優化的模型
準確率 0.2478 0.8401 0.8467
F-score 0.2917 0.6844 0.6967
 

回答: 1.未優化的模型和優化的模型都比天真預測器好不少。 2.優化的模型比未優化的模型表現好。

 

特徵的重要性

在數據上(好比咱們這裏使用的人口普查的數據)使用監督學習算法的一個重要的任務是決定哪些特徵可以提供最強的預測能力。專一於少許的有效特徵和標籤之間的關係,咱們可以更加簡單地理解這些現象,這在不少狀況下都是十分有用的。在這個項目的情境下這表示咱們但願選擇一小部分特徵,這些特徵可以在預測被調查者是否年收入大於\$50,000這個問題上有很強的預測能力。

選擇一個有 'feature_importance_' 屬性的scikit學習分類器(例如 AdaBoost,隨機森林)。'feature_importance_' 屬性是對特徵的重要性排序的函數。在下一個代碼單元中用這個分類器擬合訓練集數據並使用這個屬性來決定人口普查數據中最重要的5個特徵。

 

問題 6 - 觀察特徵相關性

探索數據的時候,它顯示在這我的口普查數據集中每一條記錄咱們有十三個可用的特徵。
在這十三個記錄中,你認爲哪五個特徵對於預測是最重要的,選擇每一個特徵的理由是什麼?你會怎樣對他們排序?

 

回答:

  • 特徵1:age,年齡越大,積累越高,收入越高
  • 特徵2:education_level,教育程度越高理論上收入越高
  • 特徵3:occupation,職業領域,不一樣的職業領域,收入水平不同
  • 特徵4:relationship,家庭狀況,家庭總數入也有影響
  • 特徵5:workclass,勞動類型,不一樣的類型對輸入也不一樣

age>workclass>occupation>education_level>relationship

 

練習 - 提取特徵重要性

選擇一個scikit-learn中有feature_importance_屬性的監督學習分類器,這個屬性是一個在作預測的時候根據所選擇的算法來對特徵重要性進行排序的功能。

在下面的代碼單元中,你將要實現如下功能:

  • 若是這個模型和你前面使用的三個模型不同的話從sklearn中導入一個監督學習模型。
  • 在整個訓練集上訓練一個監督學習模型。
  • 使用模型中的 'feature_importances_'提取特徵的重要性。
In [36]:
# TODO:導入一個有'feature_importances_'的監督學習模型

# TODO:在訓練集上訓練一個監督學習模型
model = best_clf

# TODO: 提取特徵重要性
importances = model.feature_importances_

# 繪圖
vs.feature_plot(importances, X_train, y_train)
 
 

問題 7 - 提取特徵重要性

觀察上面建立的展現五個用於預測被調查者年收入是否大於\$50,000最相關的特徵的可視化圖像。

這五個特徵的權重加起來是否超過了0.5?
這五個特徵和你在問題 6中討論的特徵比較怎麼樣?
若是說你的答案和這裏的相近,那麼這個可視化怎樣佐證了你的想法?
若是你的選擇不相近,那麼爲何你以爲這些特徵更加相關?

 

回答:

1.權重之和超過了0.5

2.不一致

3.因爲github上對這些特徵沒有解釋,hours-per-week,capital-gain,marital-status,因此未考慮到。

 

特徵選擇

若是咱們只是用可用特徵的一個子集的話模型表現會怎麼樣?經過使用更少的特徵來訓練,在評價指標的角度來看咱們的指望是訓練和預測的時間會更少。從上面的可視化來看,咱們能夠看到前五個最重要的特徵貢獻了數據中全部特徵中超過一半的重要性。這提示咱們能夠嘗試去減少特徵空間,簡化模型須要學習的信息。下面代碼單元將使用你前面發現的優化模型,並只使用五個最重要的特徵在相同的訓練集上訓練模型。

In [37]:
# 導入克隆模型的功能
from sklearn.base import clone

# 減少特徵空間
X_train_reduced = X_train[X_train.columns.values[(np.argsort(importances)[::-1])[:5]]]
X_val_reduced = X_val[X_val.columns.values[(np.argsort(importances)[::-1])[:5]]]

# 在前面的網格搜索的基礎上訓練一個「最好的」模型
clf_on_reduced = (clone(best_clf)).fit(X_train_reduced, y_train)

# 作一個新的預測
reduced_predictions = clf_on_reduced.predict(X_val_reduced)

# 對於每個版本的數據彙報最終模型的分數
print "Final Model trained on full data\n------"
print "Accuracy on validation data: {:.4f}".format(accuracy_score(y_val, best_predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, best_predictions, beta = 0.5))
print "\nFinal Model trained on reduced data\n------"
print "Accuracy on validation data: {:.4f}".format(accuracy_score(y_val, reduced_predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, reduced_predictions, beta = 0.5))
 
Final Model trained on full data
------
Accuracy on validation data: 0.8467
F-score on validation data: 0.6967

Final Model trained on reduced data
------
Accuracy on validation data: 0.8307
F-score on validation data: 0.6619
 

問題 8 - 特徵選擇的影響

最終模型在只是用五個特徵的數據上和使用全部的特徵數據上的 F-score 和準確率相比怎麼樣?
若是訓練時間是一個要考慮的因素,你會考慮使用部分特徵的數據做爲你的訓練集嗎?

 

回答:

1.部分特徵比全部特徵F-score和準確率低。

2.會,若數據量比較大,特徵比較多,從訓練時間上考慮會選擇部分特徵訓練

 

問題 9 - 在測試集上測試你的模型

終於到了測試的時候,記住,測試集只能用一次。

使用你最有信心的模型,在測試集上測試,計算出準確率和 F-score。 簡述你選擇這個模型的緣由,並分析測試結果

In [40]:
#TODO test your model on testing data and report accuracy and F score
res = best_clf.predict(X_test)
from sklearn.metrics import fbeta_score,accuracy_score
print accuracy_score(y_true=y_test,y_pred=res)
print fbeta_score(y_true=y_test,y_pred=res,beta=0.5)
 
0.840132669983
0.682483889865
 

1.隨機森林模型主要在於訓練時間短,準確率較高,不容易過擬合

2.預測結果還有很大提高空間

 

歡迎掃碼關注,或搜索大數據與知識圖譜,按期分享大數據與知識圖譜相關知識點:

相關文章
相關標籤/搜索