Python機器學習 - 多元線性迴歸 - 一步一步詳解 - 代碼實現

目錄

數據導入

單變量線性迴歸

繪製散點圖

相關係數R

拆分訓練集和測試集

多變量線性迴歸

數據檢驗(判斷是否可以做線性迴歸)

訓練線性迴歸模型


先甩幾個典型的線性迴歸的模型,幫助大家撿起那些年被忘記的數學。

單變量線性迴歸: h(x)=theta0 + theta1* x 1
多變量線性迴歸: h(x)=theta0 + theta1* x 1 + theta2* x 2 + theta3* x 3
多項式迴歸:        h(x)=theta0 + theta1* x 1 + theta2* (x2^2) + theta3* (x3^3) 

多項式迴歸始終還是線性迴歸,你可以令x2=x2^2,x3=x3^3,簡單的數據處理一下就好了,這樣上述多項式迴歸的模型就變成多變量線性迴歸的模型了。

數據導入

下面我們要開始用數據說話了,先來看看數據源是什麼樣子吧。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame,Series
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression

#讀取文件
datafile = u'E:\\pythondata\\dhdhdh.xlsx'#文件所在位置,u爲防止路徑中有中文名稱,此處沒有,可以省略
data = pd.read_excel(datafile)#datafile是excel文件,所以用read_excel,如果是csv文件則用read_csv
examDf = DataFrame(data)
examDf.head()

運行結果:

     Call   Connect    Return
0  2.1335  1.267760  1.176615
1  2.5534  1.352941  1.978967
2  3.3361  1.872093  2.249511
3  3.3861  1.826667  2.986597
4  3.9682  1.875000  2.798570

 


單變量線性迴歸

 

繪製散點圖

先將上述數據中的Connect(接通量)和Return(回款量)做一個單變量的線性迴歸,先繪製一個散點圖,大致看一下分佈情況。

#繪製散點圖,examDf.jt爲X軸,examDf.hk爲Y軸
plt.scatter(examDf.Connect,examDf.Return,color = 'darkgreen',label = "Exam Data")
 
#添加圖的標籤(x軸,y軸)
plt.xlabel("The Connection amount of the average account")#設置X軸標籤
plt.ylabel("The ratio of average return amount")#設置Y軸標籤
plt.show()#顯示圖像

運行結果:  

看來商業中的實際數據總是和課本上的完美數據不一樣,看這零零散散的分佈,線性關係很是勉強,但是大致還是有一個線性相關的樣子的,那麼就看看相關係數有多少吧。

相關係數R

rDf = examDf.corr()#查看數據間的相關係數
print(rDf)

運行結果: 

             Call   Connect    Return
Call     1.000000  0.445870  0.441673
Connect  0.445870  1.000000  0.745338
Return   0.441673  0.745338  1.000000

Connect(接通量)和Return(回款量)的相關係數爲0.745338,還不錯。

相關係數是用以反映變量之間相關關係密切程度的統計指標,對於相關性強度來說,我們一般認爲:

0~0.3 弱相關

0.3~0.6  中等程度相關

0.6~1  強相關

在數學中,相關係數的計算一般是這樣的,給數學狂人看:

R(相關係數) = X和Y的協方差 / (X的標準差 * Y的標準差) == cov(X,Y)/ σX * σY (即person係數)

拆分訓練集和測試集

Connect(接通量)和Return(回款量)屬於強相關,可以進行線性迴歸訓練,那麼我們先來拆分訓練集和測試集吧。

#拆分訓練集和測試集(train_test_split是存在與sklearn中的函數)
X_train,X_test,Y_train,Y_test = train_test_split(examDf.Connect,examDf.Return,train_size=0.8)
#train爲訓練數據,test爲測試數據,examDf爲源數據,train_size 規定了訓練數據的佔比
 
print("自變量---源數據:",examDf.Connect.shape, ";  訓練集:",X_train.shape, ";  測試集:",X_test.shape)
print("因變量---源數據:",examDf.Return.shape, ";  訓練集:",Y_train.shape, ";  測試集:",Y_test.shape)
 
#散點圖
plt.scatter(X_train, Y_train, color="darkgreen", label="train data")#訓練集爲深綠色點
plt.scatter(X_test, Y_test, color="red", label="test data")#測試集爲紅色點
 
#添加標籤
plt.legend(loc=2)#圖標位於左上角,即第2象限,類似的,1爲右上角,3爲左下角,4爲右下角
plt.xlabel("The Connection amount of the average account")#添加 X 軸名稱
plt.ylabel("The ratio of average return amount")#添加 Y 軸名稱
plt.show()#顯示散點圖

運行結果:  

自變量---源數據: (14,) ;  訓練集: (11,) ;  測試集: (3,)
因變量---源數據: (14,) ;  訓練集: (11,) ;  測試集: (3,)

迴歸模型訓練

#線性迴歸訓練
model.fit(X_train,Y_train)#調用線性迴歸包

a  = model.intercept_#截距
b = model.coef_#迴歸係數

#訓練數據的預測值
y_train_pred = model.predict(X_train)
#繪製最佳擬合線:標籤用的是訓練數據的預測值y_train_pred
plt.plot(X_train, y_train_pred, color='blue', linewidth=2, label="best line")

#測試數據散點圖
plt.scatter(X_train, Y_train, color='darkgreen', label="train data")
plt.scatter(X_test, Y_test, color='red', label="test data")
 
#添加圖標標籤
plt.legend(loc=2)#圖標位於左上角,即第2象限,類似的,1爲右上角,3爲左下角,4爲右下角
plt.xlabel("The Connection amount of the average account")#添加 X 軸名稱
plt.ylabel("The ratio of average return amount")#添加 Y 軸名稱
plt.show()#顯示圖像

print("擬合參數:截距",a,",迴歸係數:",b)
print("最佳擬合線: Y = ",round(a,2),"+",round(b[0],2),"* X")#顯示線性方程,並限制參數的小數位爲兩位

運行結果:  

擬合參數:截距 -0.7291766860887745 ,迴歸係數: [1.71584366]
最佳擬合線: Y =  -0.73 + 1.72 * X

 



多變量線性迴歸

在單變量線性迴歸中,我們將每一步都講解的極其詳細,所以在多變量線性迴歸中,我們不會重複講那些簡單的部分了,但是爲了防止python小白迷失自己,所以在這部分該有的代碼還是會甩出來,該有的備註也都有,只不過不會一點一點分步驟來了。

上面我們提到多變量線性迴歸的模型爲h(x)=theta0 + theta1* x 1 + theta2* x 2 + theta3* x 3,下面,我們還是使用單變量線性迴歸中的數據,單變量線性迴歸中,我們只用到了Connect(接通量)和Return(回款量),既然是多變量回歸模型,那麼我們就多加一個變量Call(撥打量)。

 

數據檢驗(判斷是否可以做線性迴歸)

#-*- coding:utf-8 -*- 

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from pandas import DataFrame,Series
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression

#讀取文件
datafile = u'E:\\pythondata\\dhdhdh.xlsx'#文件所在位置,u爲防止路徑中有中文名稱,此處沒有,可以省略
data = pd.read_excel(datafile)#datafile是excel文件,所以用read_excel,如果是csv文件則用read_csv
examDf = DataFrame(data)

#數據清洗,比如第一列有可能是日期,這樣的話我們就只需要從第二列開始的數據,
#這個情況下,把下面中括號中的0改爲1就好,要哪些列取哪些列
new_examDf = examDf.ix[:,0:]

#檢驗數據
print(new_examDf.describe())#數據描述,會顯示最值,平均數等信息,可以簡單判斷數據中是否有異常值
print(new_examDf[new_examDf.isnull()==True].count())#檢驗缺失值,若輸出爲0,說明該列沒有缺失值

#輸出相關係數,判斷是否值得做線性迴歸模型
print(new_examDf.corr())#0-0.3弱相關;0.3-0.6中相關;0.6-1強相關;

#通過seaborn添加一條最佳擬合直線和95%的置信帶,直觀判斷相關關係
sns.pairplot(data, x_vars=['Call','Connect'], y_vars='Return', size=7, aspect=0.8, kind='reg')  
plt.show()

運行結果:

            Call    Connect     Return
count  99.000000  99.000000  99.000000
mean    3.153649   1.967779   2.591121
std     1.027607   0.470364   0.790172
min     1.280100   1.014208   0.941292
25%     2.373528   1.596610   2.044147
50%     3.040000   1.913472   2.476091
75%     3.835980   2.253994   3.035603
max     5.851181   3.234977   5.160840
Call       0
Connect    0
Return     0
dtype: int64
             Call   Connect    Return
Call     1.000000  0.837052  0.744792
Connect  0.837052  1.000000  0.844640
Return   0.744792  0.844640  1.000000

判斷是否可以做線性迴歸

  • 異常值:通過最值或者平均數或者中位數等判斷,或者直接通過查看是否有遊離在大部隊之外的點來判斷是否有異常值;
  • 空值:這個沒辦法,你必須看運行結果的10-12行是否等於0,是0則無空值,如果不是0,就要看看是刪掉空值呢?還是用其他值代替呢?不同情況不同對待;
  • 相關性:要麼通過相關係數的大小判斷,要麼看散點圖中的最佳擬合直線和95%的置信帶,直觀判斷相關關係;

 

訓練線性迴歸模型

#拆分訓練集和測試集
X_train,X_test,Y_train,Y_test = train_test_split(new_examDf.ix[:,:2],new_examDf.Return,train_size=0.8)
#new_examDf.ix[:,:2]取了數據中的前兩列爲自變量,此處與單變量的不同
 
print("自變量---源數據:",new_examDf.ix[:,:2].shape, ";  訓練集:",X_train.shape, ";  測試集:",X_test.shape)
print("因變量---源數據:",examDf.Return.shape, ";  訓練集:",Y_train.shape, ";  測試集:",Y_test.shape)

#調用線性規劃包
model = LinearRegression()

model.fit(X_train,Y_train)#線性迴歸訓練

a  = model.intercept_#截距
b = model.coef_#迴歸係數
print("擬合參數:截距",a,",迴歸係數:",b)

#顯示線性方程,並限制參數的小數位爲兩位
print("最佳擬合線: Y = ",round(a,2),"+",round(b[0],2),"* X1 + ",round(b[1],2),"* X2")

Y_pred = model.predict(X_test)#對測試集數據,用predict函數預測

plt.plot(range(len(Y_pred)),Y_pred,'red', linewidth=2.5,label="predict data")
plt.plot(range(len(Y_test)),Y_test,'green',label="test data")
plt.legend(loc=2)
plt.show()#顯示預測值與測試值曲線

運行結果:

自變量---源數據: (99, 2) ;  訓練集: (79, 2) ;  測試集: (20, 2)
因變量---源數據: (99,) ;  訓練集: (79,) ;  測試集: (20,)
擬合參數:截距 -0.006540954521370601 ,迴歸係數: [0.08624344 1.19029593]
最佳擬合線: Y =  -0.01 + 0.09 * X1 +  1.19 * X2

效果勉強滿意,畢竟才用了80個數訓練的模型,要求高的話多用一些數據就好。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章