Python 機(jī)器學(xué)習(xí)——回歸(線性回歸)


1?兒童體表面積預(yù)測(cè)

(本節(jié)介紹如何利用線性回歸模型進(jìn)行預(yù)測(cè)分析)
??下表所示為某醫(yī)院醫(yī)師測(cè)得的10名4歲兒童的身高(cm)、體重(kg)與體表面積(m^2)數(shù)據(jù),下面試用線性回歸方法確定以身高、體重為自變量,以體表面積為因變量的回歸方程:\text{體表面積}=\beta_0+\beta_1\times\text{身高}+\beta_2\times\text{體重}

身高/cm 體重/kg 體表面積/m^2
88 11 5.382
87 11 5.299
88 12 5.358
89 12 5.292
87 13 5.602
89 13 6.014
88 14 5.830
90 14 6.102
90 15 6.075
91 16 6.414
  • 導(dǎo)入數(shù)據(jù)

??首先導(dǎo)入 Numpy 庫(kù):

    import numpy as np

??利用 Python 中的數(shù)組創(chuàng)造一個(gè) Numpy 對(duì)象:

# 分別輸入第1到第10名兒童的兩個(gè)特征:
x_train = np.array([[88,11],
                    [87,11],
                    [88,12],
                    [89,12],
                    [87,13],
                    [89,13],
                    [88,14],
                    [90,14],
                    [90,15]])
# 對(duì)應(yīng)輸入兒童的體表面積
y_train=np.array([5.382,5.299,5.358,5.292,5.602,6.014,5.830,6.102,6.075])
# 輸入測(cè)試集
x_test=np.array([[89,11],
                 [91,16]])
y_test=np.array([5.547,6.414])
  • 構(gòu)建模型

??導(dǎo)入 sklearn 中的 linear_model 模塊,創(chuàng)建一個(gè)學(xué)習(xí)器對(duì)象,載入訓(xùn)練集,該對(duì)象學(xué)習(xí)訓(xùn)練集的數(shù)據(jù)訓(xùn)練模型,調(diào)用 predict 方法對(duì)測(cè)試集進(jìn)行預(yù)測(cè)。

    from sklearn import linear_model
    reg=linear_model.LinearRegression()     # 創(chuàng)建學(xué)習(xí)器對(duì)象
    reg.fit(x_train,y_train)                # 訓(xùn)練模型
    reg.predict(x_test)                     # 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)

??創(chuàng)建學(xué)習(xí)器對(duì)象學(xué)習(xí)訓(xùn)練集,訓(xùn)練模型進(jìn)行預(yù)測(cè),這是 sklearn 庫(kù)中回歸/分類常用的一種模型使用方法。
??由于是線性回歸,可以利用 reg.coef_reg.intercept_ 屬性,其中coef_ 表示 \beta_1,\beta_2intercept_ 代表\beta_0,則:

    reg.predict(x_text)

等價(jià)于:

    weight=reg.coef_.reshape(-1,1)
    reg.intercept_+x_text.dot(weight)      # 利用向量點(diǎn)乘獲得加權(quán)和
  • 結(jié)果分析

??由前面獲得的系數(shù)可知,體表面積與身高、體重的回歸方程為:\text{體表面積}=-2.2249+0.0623\times\text{身高}+0.1855\times\text{體重}??為更加直觀地分析結(jié)果,使用下面的代碼導(dǎo)入 可視化 ,且 加入中文 支持:

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    # 中文支持
    mpl.rcParams['font.sans-serif']=[u'SimHei']    # 其他的字體有:Fangsong/Heiti/KaiTi
    mpl.rcParams['axes.unicode_minus']=False
    # 下面進(jìn)行可視化
    y=reg.predict(x_train)
    x=np.linspace(5.2,6.4,100)
    plt.plot(y,y_train,'ro',x,x,'b--')
    plt.xlabel("預(yù)測(cè)的因變量")
    plt.ylabel("實(shí)際的因變量")
    plt.legend(("預(yù)測(cè)值x,實(shí)際值y","全部吻合的曲線"))
    plt.show()

圖1?線性回歸的可視化結(jié)果

??圖中,x軸上的數(shù)值是預(yù)測(cè)值,y軸上的數(shù)值是實(shí)際值,顯然若預(yù)測(cè)值等于實(shí)際值,原點(diǎn)將出現(xiàn)在虛線上。也就是說(shuō),圓點(diǎn)離虛線越近,說(shuō)明這個(gè)點(diǎn)的預(yù)測(cè)效果越理想。由圖可以看出,大部分圓點(diǎn)都在虛線附近,說(shuō)明訓(xùn)練結(jié)果較為理想。
??為了對(duì)訓(xùn)練效果進(jìn)行定量分析,下面利用 sklearn 中的 score() 函數(shù)對(duì)結(jié)果進(jìn)行打分:

    reg.score(x_train,y_train)
    reg.score(x_test,y_test)
  • 若需要對(duì)模型預(yù)測(cè)準(zhǔn)確度進(jìn)行分析,需對(duì)未進(jìn)入訓(xùn)練集的數(shù)據(jù)組成測(cè)試集進(jìn)行評(píng)判。
  • 測(cè)試集的打分一般小于訓(xùn)練集的打分。這里數(shù)據(jù)量較小,因此不具有代表性。

??在該方法中國(guó),使用了 殘差的評(píng)分 概念,公式為1-\frac{\sum\limits_{i=1}^m{(y_i-\hat{y_i})^2}}{\sum\limits_{i=1}^m{(y_i-\overline{y})^2}}??其中,\hat{y_i}是第i個(gè)樣本的預(yù)測(cè)值,\overline{y}是樣本的平均值,y_i是第i個(gè)樣本的實(shí)際值。
??該公式的數(shù)學(xué)意義是,希望預(yù)測(cè)值與實(shí)際值越接近越好,也就是\sum\limits_{i=1}^m{(y_i-\hat{y_i})^2}越小越好,然而這和樣本方差有關(guān),若除以樣本的方差\sum\limits_{i=1}^m{(y_i-\overline{y})^2},就可以 統(tǒng)一量綱,以便在不同樣本上生成的模型進(jìn)行比較。


2?影響房?jī)r(jià)的預(yù)測(cè)及因素分析

(本節(jié)介紹如何利用線性回歸模型依據(jù)回歸系數(shù)量化分析特征的影響力)
??假設(shè)你有一個(gè)美國(guó)華盛頓地區(qū)的朋友向你尋求幫助,要你幫忙挑選房子。你的朋友綜合考慮了許多因素,并試圖對(duì)這些因素進(jìn)行打分,找出房?jī)r(jià)影響最大的因素。
??波士頓房?jī)r(jià)數(shù)據(jù)集來(lái)源于 kaggle 比賽數(shù)據(jù),包括一些房屋及其所在的區(qū)域的信息。建立這些信息與房?jī)r(jià)的回歸方程,并根據(jù)訓(xùn)練得到的方程系數(shù)找到對(duì)房?jī)r(jià)影響最大的那些特征。

  • 導(dǎo)入數(shù)據(jù)

??由于該數(shù)據(jù)集十分經(jīng)典,已被 sklearn 庫(kù)收錄,因此這里采用其中的 datasets 模塊導(dǎo)入數(shù)據(jù)。并查看數(shù)據(jù)的相關(guān)信息:

    from sklearn import datasets

    boston=datasets.load_boston()                              #載入數(shù)據(jù)
    print(boston.data)                                         #數(shù)據(jù)特征
    print(boston.target)                                       #類標(biāo)結(jié)果
    print(u'總行數(shù): ', len(boston.data), len(boston.target))   #數(shù)據(jù)總行數(shù)
    print(u'特征數(shù): ', len(boston.data[0]))                    #每行數(shù)據(jù)集維數(shù)
    print(u'數(shù)據(jù)大小: ', boston.data.shape)                    #數(shù)據(jù)大小
    print(type(boston.data),type(boston.target))               #數(shù)據(jù)集類型

??這里,bostondatasets 的對(duì)象 ,其中的 data 屬性為特征空間,target 屬性為結(jié)果

  • 數(shù)據(jù)處理

??由于各個(gè)特征的取值范圍不一樣,需要將樣本數(shù)據(jù)進(jìn)行歸一化處理(也稱為 無(wú)量綱化 ),這樣才能通過(guò)觀察回歸系數(shù)解釋特征和結(jié)果的相關(guān)性:

    from sklearn import preprocessing

    min_max_scaler=preprocessing.MinMaxScaler()
    boston.data=min_max_scaler.fit_transform(boston.data)

??建立訓(xùn)練集與測(cè)試集

    from sklearn.model_selection import train_test_split

    x_train,x_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=0)
  • 觀察數(shù)據(jù)

??觀察數(shù)據(jù)的最佳方法之一就是將其可視化。其中一種可視化方法就是 散點(diǎn)圖。對(duì)于多個(gè)特征的數(shù)據(jù)集可視化,我們采用繪制 散點(diǎn)圖矩陣 來(lái)進(jìn)行,其中斜對(duì)角線上為每個(gè)特征的直方圖。

    # 創(chuàng)建散點(diǎn)圖矩陣
    import mglearn
    import pandas as pd
    import matplotlib.pyplot as plt

    df=pd.DataFrame(boston.data,columns=boston.feature_names)
    grr=pd.plotting.scatter_matrix(df,c=boston['target'],figsize=(15,15),marker='0',hist_kwds={'bins':20},s=60,alpha=.8,cmap=mglearn.cm3)
    plt.show()
波士頓房?jī)r(jià)數(shù)據(jù)集散點(diǎn)圖矩陣

??由圖我們可以發(fā)現(xiàn),變量之間存在一定的相關(guān)關(guān)系,因此采用線性回歸模型未必能夠獲得很好的預(yù)測(cè)結(jié)果。不過(guò)我們這里主要討論變量的回歸系數(shù)解釋特征和結(jié)果的相關(guān)性強(qiáng)弱關(guān)系,仍具有一定的可行性。

  • 構(gòu)建模型

??創(chuàng)建一個(gè)學(xué)習(xí)器并對(duì)樣本進(jìn)行學(xué)習(xí):

    from sklearn import linear_model

    reg=linear_model.LinearRegression()     # 創(chuàng)建學(xué)習(xí)器對(duì)象
    reg.fit(x_train,y_train)                # 訓(xùn)練模型
    reg.predict(x_test)                     # 對(duì)測(cè)試集進(jìn)行預(yù)測(cè)
  • 結(jié)果分析

??預(yù)測(cè)結(jié)果的可視化分析:

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import numpy as np

    # 中文支持
    mpl.rcParams['font.sans-serif']=[u'SimHei']
    mpl.rcParams['axes.unicode_minus']=False
    # 下面進(jìn)行可視化
    y=reg.predict(x_train)
    x=np.linspace(5.2,6.4,100)
    plt.plot(y,y_train,'ro',x,x,'b--')
    plt.xlabel("預(yù)測(cè)的因變量")
    plt.ylabel("實(shí)際的因變量")
    plt.legend(("預(yù)測(cè)值x,實(shí)際值y","全部吻合的曲線"))
    plt.show()
圖2?線性回歸的可視化結(jié)果

??由圖可以看出,大部分圓點(diǎn)都在虛線附近,說(shuō)明訓(xùn)練結(jié)果較為理想。同時(shí)我們可以發(fā)現(xiàn),模型存在一些異常點(diǎn),這些應(yīng)該進(jìn)行剔除(這里暫不進(jìn)行這一步,大家可以自行思考)。

??利用 sklearn 中的 score() 函數(shù)對(duì)結(jié)果進(jìn)行打分:

    In[29]:  reg.score(x_train, y_train)
    Out[29]:  0.7697699488741149
    In[29]:  reg.score(x_test, y_test)
    Out[30]:  0.6354638433202122

??為了量化每個(gè)特征的影響力,打印每個(gè)特征的回歸系數(shù):

    In[31]:  np.set_printoptions(suppress=True,precision=4)      #設(shè)置打印格式
       ...:  print(reg.coef_)
    Out[31]:  [-10.4749   4.4017  -0.1574   2.3934  -7.5765  19.6702  -0.6831 -15.7801
               5.5219  -5.9198  -9.2641   3.3489 -18.088 ]

??系數(shù)的絕對(duì)值大小,可以說(shuō)明他們對(duì)房?jī)r(jià)影響大小。且系數(shù)為正是正相關(guān),系數(shù)為負(fù)是負(fù)相關(guān)。


3?練習(xí)題

  • 剔除波士頓房?jī)r(jià)數(shù)據(jù)集的異常點(diǎn)并重新建模
  • 提高波士頓房?jī)r(jià)數(shù)據(jù)集線性回歸的 預(yù)測(cè)準(zhǔn)確度
    提示:特征工程(如:主成分分析、因子分析等)
  • 利用線性回歸進(jìn)行糖尿病預(yù)測(cè)
    提示:diabetes = datasets.load_diabetes()

diabetes數(shù)據(jù)集是一個(gè)糖尿病的數(shù)據(jù)集,主要包括442行數(shù)據(jù),10個(gè)屬性值,分別是:Age(年齡)、性別(Sex)、Body mass index(體質(zhì)指數(shù))、Average Blood Pressure(平均血壓)、S1~S6一年后疾病級(jí)數(shù)指標(biāo)。Target為一年后患疾病的定量指標(biāo)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容