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大數據挖掘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那里點擊購買鏈接購買博主的書進行學習,在此感謝大家的支持。關注下面公眾號,根據提示,可免費獲取書籍的教學視頻。