預測演算法之多元線性迴歸

哥不是小蘿莉發表於2021-03-28

1.概述

在機器學習裡面,常見的預測演算法有以下幾種:

  • 簡易平均法:包括幾何平均法、算數平均法及加權平均法;
  • 移動平均法:包括簡單移動平均法和加權移動平均法;
  • 指數平滑法:包括一次指數平滑法和二次指數平滑法,以及三次指數平滑法;
  • 線性迴歸法:包括一元線性迴歸和二元線性迴歸。

本篇部落格,筆者將為大家主要介紹多元線性迴歸的相關內容。

2.內容

線性迴歸是基礎且廣泛使用的預測分析演算法,它允許在數字輸入和輸出值之間建立關係(不能用於分類資料)。簡而言之,我們的目標是將複雜形式顯示的實際值顯示為如下圖中的單線。

 

2.1 一元線性迴歸 

具有一個因變數和一個自變數的迴歸方程的最簡單形式由如下公式組成:

y = ax + b

y=因變數,a=係數,x=自變數,c=常數

誤差量是真實值中的點與直線之間的距離。

例如,下面我們通過一個案例,讀取一個包含按月銷售額的檔案,將進行線性迴歸月銷售額的預測,程式碼如下所示:

# 讀取csv檔案
import pandas as pd
# 建立2D圖形
import matplotlib.pyplot as plt

# 已讀取csv檔案
data = pd.read_csv('/Users/dengjie/Desktop/python/predicted/satislar.csv')

# 將名為月份的列分配給變數
Aylar = data[['Aylar']]

# 將名為Sales的列分配給變數
Satislar = data[['Satislar']]

# 使用#sklearn庫,我們匯入了將資料分為測試和訓練的函式
from sklearn.model_selection import train_test_split

# 我們將資料集分為測試和訓練
# test_size = 0.33 資料
# x_train,y_train = 月和銷售的訓練集
# x_test, y_test = 月和Satislar的測試集
# test_size = 訓練的資料集的2/3 1/3將保留用於測試(0.33)

x_train, x_test, y_train, y_test = train_test_split(Aylar,Satislar,test_size=0.33,random_state=0)

# 我們使用#sklearn庫包含LinearRegression類
from sklearn.linear_model import LinearRegression
# 我們從類中建立一個物件
lr = LinearRegression()

# 我們通過提供訓練資料集來訓練機器
lr.fit(x_train,y_train)

# 通過提供測試集,我們使Aylar可以預測Satislar
tahmin = lr.predict(x_test)

# 我們按索引號對資料進行排序,以在圖表上定期顯示它們
x_train = x_train.sort_index()
y_train = y_train.sort_index()

# 我們以圖形形式列印螢幕
plt.plot(x_train,y_train)
plt.plot(x_test,tahmin)
plt.show()

執行上述程式碼,結果顯示如下:

 

2.2 多元線性迴歸

多元線性迴歸是使用最廣發的線性迴歸分析。在一元線性迴歸中,它使用了一個因變數和一個自變數。在多元線性迴歸中可以與多個獨立變數一起使用。

y = b0 + ax1 +bx2 + cax3 + d

例如,線上性迴歸中,我們按月預測銷售量。在多元線性迴歸中,我們可以根據體重、年齡和身高資料估算鞋子的大小。因此,此時體重、年齡和身高是自變數。

2.2.1 虛擬變數

年齡 身高 體重 性別
20 175 82 m
35 182 65

f

45 168 73 f
32 176 42 m

虛擬變數可以定義為表示變數的另一個變數,比如上面性別列使用OneHotEncoder從類別資料轉換為數值資料。如下所示:

m f
1 0
0 1
0 1
1 0

轉換之後,我們將列數從4列增加到了6列。OneHotEncoder結果包含在m和f列中,但是,如果我們將此資料集直接提供給機器學習演算法,則我們的結果可能是錯誤的,因為這6列中的3列(性別、m、f)本質是相同的,也就是說,其中一個的更改會影響另一個列值。

為了避免這種情況,我們必須減去3列中的兩列(性別、m、f),並將資料集提供給機器學習演算法。裁剪後的資料列表如下所示:

年齡 身高 體重 體重 m f
20 175 82 m 1 0
35 182 65 f 0 1
45 168 73 f 0 1
32 176 42 m 1 0

2.2.2 P值

 

 P值即概率,反應某一時間發生的可能性大小。統計學根據顯著性檢驗方法所得到的P值,一般以P小於0.05為顯著,P小於0.01為非常顯著,其含義是樣本間的差異由抽樣誤差所致的概率小於0.05或者0.01。線上性迴歸中,P小於0.01(或者0.05)表示兩個變數非常顯著線性相關。

下面,我們通過執行示例程式碼,通過獲取年齡、國家、性別和體重資料,並嘗試預測人的身高。程式碼如下所示:

# 讀取csv檔案
import pandas as pd

# 已讀取csv檔案資料
data = pd.read_csv('/Users/dengjie/Desktop/python/predicted/veriler.csv')

# 要應用多元線性迴歸,我們將列分配給變數,以將分類資料轉換為數值
cinsiyet = data.iloc[:,-1:].values

# 要應用多元線性迴歸,我們將列分配給變數,以將分類資料轉換為數值
ulkeler = data.iloc[:,0:1].values

# 我們將要猜測的列的值分配給一個變數
boy = data.iloc[:,1:2].values

# 匯入LabelEncoder類
from sklearn.preprocessing import LabelEncoder

# 我們從LabelEncoder類派生了一個物件
lb = LabelEncoder()

# 我們執行了編碼過程。現在,性別和國家/地區列為數字值
cinsiyet[:,0] = lb.fit_transform(cinsiyet[:,0])
ulkeler[:,0] = lb.fit_transform(ulkeler[:,0])

# 我們匯入了OneHotEncoder類
from sklearn.preprocessing import OneHotEncoder

# 我們從#OneHotEncoder類派生了一個物件
ohe = OneHotEncoder()

# 使用#OneHotEncoder,我們將數字列分為1和0組成的列
cinsiyet = ohe.fit_transform(cinsiyet.reshape(-1,1)).toarray()
ulkeler = ohe.fit_transform(ulkeler.reshape(-1,1)).toarray()

# 我們建立了DataFrame來重組資料
dfCinsiyet = pd.DataFrame(data=cinsiyet[:,:1],index=range(len(cinsiyet)),columns=['cinsiyet',])
dfUlkeler = pd.DataFrame(data=ulkeler,index=range(len(ulkeler)),columns=['fr','tr','us'])


# 我們合併了資料
preData = pd.concat([dfUlkeler,data.iloc[:,2:4],dfCinsiyet],axis=1)

# 我們將資料集分為測試和訓練
# x_train,y_train = 訓練集
# x_test, y_test = 測試集
# test_size = 訓練的資料集的2/3 1/3將保留用於測試(0.33)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(preData,boy,test_size=0.33,random_state=0)

# 我們使用#sklearn庫包含LinearRegression類
from sklearn.linear_model import LinearRegression

# 我們從#LinearRegression類建立一個物件
lr = LinearRegression()

# 我們通過提供訓練資料集來訓練機器
lr.fit(x_train,y_train)

# 通過提供#測試集,我們使我們訓練的機器能夠生成估計值
result = lr.predict(x_test)
print(result)

執行結果如下:

 

 2.2.3 向後淘汰

每個變數都會系統產生影響,有些變數對系統有很大影響,而有些則較少。消除對系統影響很小的自變數,使我們可以構建更好的模型。我們可以使用向後淘汰方法建立更好的模型。

  • 選擇P值(通常此值為0.05)
  • 建立一個包含所有引數的模型
  • 檢查每個自變數的P值,如果P值大於為模型指定的值,則將從模型中刪除此自變數,然後再次執行
  • 如果所有P值都小於我們確定的值,那麼我們的模型基本算準備就緒了

執行如下程式碼:

# 讀取csv檔案
import pandas as pd

# 已讀取csv檔案資料
data = pd.read_csv('/Users/dengjie/Desktop/python/predicted/veriler.csv')

# 要應用多元線性迴歸,我們將列分配給變數,以將分類資料轉換為數值
cinsiyet = data.iloc[:,-1:].values

# 要應用多元線性迴歸,我們將列分配給變數,以將分類資料轉換為數值
ulkeler = data.iloc[:,0:1].values

# 我們將要猜測的列的值分配給一個變數
boy = data.iloc[:,1:2].values

# 匯入LabelEncoder類
from sklearn.preprocessing import LabelEncoder

# 我們從LabelEncoder類派生了一個物件
lb = LabelEncoder()

# 我們執行了編碼過程。現在,性別和國家/地區列為數字值
cinsiyet[:,0] = lb.fit_transform(cinsiyet[:,0])
ulkeler[:,0] = lb.fit_transform(ulkeler[:,0])

# 我們匯入了OneHotEncoder類
from sklearn.preprocessing import OneHotEncoder

# 我們從#OneHotEncoder類派生了一個物件
ohe = OneHotEncoder()

# 使用#OneHotEncoder,我們將數字列分為1和0組成的列
cinsiyet = ohe.fit_transform(cinsiyet.reshape(-1,1)).toarray()
ulkeler = ohe.fit_transform(ulkeler.reshape(-1,1)).toarray()

# 我們建立了DataFrame來重組資料
dfCinsiyet = pd.DataFrame(data=cinsiyet[:,:1],index=range(len(cinsiyet)),columns=['cinsiyet',])
dfUlkeler = pd.DataFrame(data=ulkeler,index=range(len(ulkeler)),columns=['fr','tr','us'])


# 我們合併了資料
preData = pd.concat([dfUlkeler,data.iloc[:,2:4],dfCinsiyet],axis=1)

# 我們將資料集分為測試和訓練
# x_train,y_train = 訓練集
# x_test, y_test = 測試集
# test_size = 訓練的資料集的2/3 1/3將保留用於測試(0.33)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(preData,boy,test_size=0.33,random_state=0)

# 我們使用#sklearn庫包含LinearRegression類
from sklearn.linear_model import LinearRegression

# 我們從#LinearRegression類建立一個物件
lr = LinearRegression()

# 我們通過提供訓練資料集來訓練機器
lr.fit(x_train,y_train)

# 通過提供#測試集,我們使我們訓練的機器能夠生成估計值
result = lr.predict(x_test)
print(result)

# 我們匯入了必要的庫
import statsmodels.api as sm
import numpy as np

# 我們在預處理資料中建立了一個列,並將1分配給所有值
X = np.append(arr=np.ones((len(preData),1)).astype(int),values=preData,axis=1)

# 我們處理了每一列。通過玩這部分,我們可以開發出最佳模型
X_l = preData.iloc[:,[0,1,2,3,4,5]].values

# endog = 預測的部分
# exog = 因變數
r = sm.OLS(endog=boy,exog=X_l).fit()

# 輸出
print(r.summary())

輸出結果如下所示:

 

 在圖中,P > | t | 這一列是我們的P值,在x5對應的列高於我們確定的P值(0.05),接下來,將刪除此列,然後再次執行該程式,這個過程一直持續到 P > | t | 這列中所有值都小於P值為止。

2.3 非線性下的多項式迴歸

資料有時是非線性的,在這種情況下,將使用多項式迴歸。

 

 在上圖公式中,h是多項式的次數。它被稱為h的二次方、三次方、四次方。

程式碼如下所示:

# 讀取csv檔案
import pandas as pd
# 繪製圖形
import matplotlib.pyplot as plt

# 載入資料
data = pd.read_csv('/Users/dengjie/Desktop/python/predicted/maaslar.csv')

# 將訓練列的值分配給一個變數
egitim = data.iloc[:, 1:2].values

# 將maas列的值分配給一個變數
maas = data.iloc[:, -1:].values


# 匯入了LinearRegression和PolynomialFeatures類
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures

# 從LinearRegression類生成了一個物件
lr = LinearRegression()

# 我們從#PolynomialFeatures類建立了一個物件
# 這裡的度數引數是多項式的度數
# 如果我們給#度部分加1,將會畫一條直線
# 度增加得越多,我們得到的結果就越準確
poly = PolynomialFeatures(degree=4)

# 在訓練機器之前,我們使用PolynomialFeatures轉換訓練列中的值
egitim_poly = poly.fit_transform(egitim)

# 開始訓練
lr.fit(egitim_poly, maas)

# 在訓練機器後做出預測
predict = lr.predict(egitim_poly)

# 以圖形形式列印螢幕
plt.scatter(egitim, maas, color='red')
plt.plot(egitim, predict, color='blue')
plt.show()

輸出結果如下:

 

 更改不同的度數引數後的結果如下所示:

 

3.總結

需要注意的是,在非線性迴歸中,不可以用P值檢驗相關顯著性,因為在非線性迴歸中,殘差均值平方不再是誤差方差的無偏估計,因為不能使用線性模型的檢驗方法來檢驗非線性模型,從而並不能用F統計量及其P值進行檢驗。

4.結束語

這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!

另外,博主出書了《Kafka並不難學》和《Hadoop大資料探勘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那裡點選購買連結購買博主的書進行學習,在此感謝大家的支援。關注下面公眾號,根據提示,可免費獲取書籍的教學視訊。

相關文章