1. 程式人生 > >30分鐘學會用scikit-learn的基本回歸方法(線性、決策樹、SVM、KNN)和整合方法(隨機森林,Adaboost和GBRT)

30分鐘學會用scikit-learn的基本回歸方法(線性、決策樹、SVM、KNN)和整合方法(隨機森林,Adaboost和GBRT)

注:本教程是本人嘗試使用scikit-learn的一些經驗,scikit-learn真的超級容易上手,簡單實用。30分鐘學會用呼叫基本的迴歸方法和整合方法應該是夠了。
本文主要參考了scikit-learn的官方網站
前言:本教程主要使用了numpy的最最基本的功能,用於生成資料,matplotlib用於繪圖,scikit-learn用於呼叫機器學習方法。如果你不熟悉他們(我也不熟悉),沒關係,看看numpy和matplotlib最簡單的教程就夠了。我們這個教程的程式不超過50行

1. 資料準備

為了實驗用,我自己寫了一個二元函式,y=0.5*np.sin(x1)+ 0.5*np.cos(x2)+0.1*x1+3。其中x1的取值範圍是0~50,x2的取值範圍是-10~10,x1和x2的訓練集一共有500個,測試集有100個。其中,在訓練集的上加了一個-0.5~0.5的噪聲。生成函式的程式碼如下:
def f(x1, x2):
    y = 0.5 * np.sin(x1) + 0.5 * np.cos(x2)  + 0.1 * x1 + 3 
    return y

def load_data():
    x1_train = np.linspace(0,50,500)
    x2_train = np.linspace(-10,10,500)
    data_train = np.array([[x1,x2,f(x1,x2) + (np.random.random(1)-0.5)] for x1,x2 in zip(x1_train, x2_train)])
    x1_test = np.linspace(0
,50,100)+ 0.5 * np.random.random(100) x2_test = np.linspace(-10,10,100) + 0.02 * np.random.random(100) data_test = np.array([[x1,x2,f(x1,x2)] for x1,x2 in zip(x1_test, x2_test)]) return data_train, data_test

其中訓練集(y上加有-0.5~0.5的隨機噪聲)和測試集(沒有噪聲)的影象如下:
訓練集和測試集

2. scikit-learn最簡單的介紹。

scikit-learn非常簡單,只需例項化一個演算法物件,然後呼叫fit()函式就可以了,fit之後,就可以使用predict()函式來預測了,然後可以使用score()函式來評估預測值和真實值的差異,函式返回一個得分。例如呼叫決策樹的方法如下

In [6]: from sklearn.tree import DecisionTreeRegressor

In [7]: clf = DecisionTreeRegressor()

In [8]: clf.fit(x_train,y_train)
Out[11]:
DecisionTreeRegressor(criterion='mse', max_depth=None, max_features=None,
           max_leaf_nodes=None, min_samples_leaf=1, min_samples_split=2,
           min_weight_fraction_leaf=0.0, presort=False, random_state=None,
           splitter='best')
In [15]: result = clf.predict(x_test)

In [16]: clf.score(x_test,y_test)
Out[16]: 0.96352052312508396

In [17]: result
Out[17]:
array([ 2.44996735,  2.79065744,  3.21866981,  3.20188779,  3.04219101,
        2.60239551,  3.35783805,  2.40556647,  3.12082094,  2.79870458,
        2.79049667,  3.62826131,  3.66788213,  4.07241195,  4.27444808,
        4.75036169,  4.3854911 ,  4.52663074,  4.19299748,  4.42235821,
        4.48263415,  4.16192621,  4.40477767,  3.76067775,  4.35353213,
        4.6554961 ,  4.99228199,  4.29504731,  4.55211437,  5.08229167,

接下來,我們可以根據預測值和真值來畫出一個影象。畫圖的程式碼如下:

    plt.figure()
    plt.plot(np.arange(len(result)), y_test,'go-',label='true value')
    plt.plot(np.arange(len(result)),result,'ro-',label='predict value')
    plt.title('score: %f'%score)
    plt.legend()
    plt.show()

然後影象會顯示如下:
決策樹

3. 開始試驗各種不同的迴歸方法

為了加快測試, 這裡寫了一個函式,函式接收不同的迴歸類的物件,然後它就會畫出影象,並且給出得分.
函式基本如下:

def try_different_method(clf):
    clf.fit(x_train,y_train)
    score = clf.score(x_test, y_test)
    result = clf.predict(x_test)
    plt.figure()
    plt.plot(np.arange(len(result)), y_test,'go-',label='true value')
    plt.plot(np.arange(len(result)),result,'ro-',label='predict value')
    plt.title('score: %f'%score)
    plt.legend()
    plt.show()
train, test = load_data()
x_train, y_train = train[:,:2], train[:,2] #資料前兩列是x1,x2 第三列是y,這裡的y有隨機噪聲
x_test ,y_test = test[:,:2], test[:,2] # 同上,不過這裡的y沒有噪聲

3.1 常規迴歸方法

常規的迴歸方法有線性迴歸,決策樹迴歸,SVM和k近鄰(KNN)

3.1.1 線性迴歸

In [4]: from sklearn import linear_model

In [5]: linear_reg = linear_model.LinearRegression()

In [6]: try_different_method(linar_reg)

線性迴歸

3.1.2數迴歸

from sklearn import tree
tree_reg = tree.DecisionTreeRegressor()
try_different_method(tree_reg)

然後決策樹迴歸的影象就會顯示出來:
樹迴歸

3.1.3 SVM迴歸

In [7]: from sklearn import svm

In [8]: svr = svm.SVR()

In [9]: try_different_method(svr)

結果影象如下:
SVM

3.1.4 KNN

In [11]: from sklearn import neighbors

In [12]: knn = neighbors.KNeighborsRegressor()

In [13]: try_different_method(knn)

竟然KNN這個計算效能最差的演算法效果最好
knn

3.2 整合方法(隨機森林,adaboost, GBRT)

3.2.1隨機森林

In [14]: from sklearn import ensemble

In [16]: rf =ensemble.RandomForestRegressor(n_estimators=20)#這裡使用20個決策樹

In [17]: try_different_method(rf)

隨機森林

3.2.2 Adaboost

In [18]: ada = ensemble.AdaBoostRegressor(n_estimators=50)

In [19]: try_different_method(ada)

影象如下:
這裡寫圖片描述

3.2.3 GBRT

In [20]: gbrt = ensemble.GradientBoostingRegressor(n_estimators=100)

In [21]: try_different_method(gbrt)

影象如下
這裡寫圖片描述

4. scikit-learn還有很多其他的方法,可以參考使用者手冊自行試驗.

5.完整程式碼

我這裡在pycharm寫的程式碼,但是在pycharm裡面不顯示圖形,所以可以把程式碼複製到ipython中,使用%paste方法複製程式碼片.
然後參照上面的各個方法匯入演算法,使用try_different_mothod()函式畫圖.
完整程式碼如下:

import numpy as np
import matplotlib.pyplot as plt

def f(x1, x2):
    y = 0.5 * np.sin(x1) + 0.5 * np.cos(x2) + 3 + 0.1 * x1 
    return y

def load_data():
    x1_train = np.linspace(0,50,500)
    x2_train = np.linspace(-10,10,500)
    data_train = np.array([[x1,x2,f(x1,x2) + (np.random.random(1)-0.5)] for x1,x2 in zip(x1_train, x2_train)])
    x1_test = np.linspace(0,50,100)+ 0.5 * np.random.random(100)
    x2_test = np.linspace(-10,10,100) + 0.02 * np.random.random(100)
    data_test = np.array([[x1,x2,f(x1,x2)] for x1,x2 in zip(x1_test, x2_test)])
    return data_train, data_test

train, test = load_data()
x_train, y_train = train[:,:2], train[:,2] #資料前兩列是x1,x2 第三列是y,這裡的y有隨機噪聲
x_test ,y_test = test[:,:2], test[:,2] # 同上,不過這裡的y沒有噪聲

def try_different_method(clf):
    clf.fit(x_train,y_train)
    score = clf.score(x_test, y_test)
    result = clf.predict(x_test)
    plt.figure()
    plt.plot(np.arange(len(result)), y_test,'go-',label='true value')
    plt.plot(np.arange(len(result)),result,'ro-',label='predict value')
    plt.title('score: %f'%score)
    plt.legend()
    plt.show()