1.概述
前面一篇博客給大家介紹了多元線性回歸的一些概念和對應的方程式的代碼實現。今天筆者再為大家介紹線性回歸的實戰演練。比如,通過空氣濕度、氣壓、風速等來預測當天的溫度。
2.內容
線性回歸是對標量因變量和一個或者多個自變量之前的線性關系的建模的最簡單,且非常強大的方法。線性回歸方程公式如下:
接着,我們導入天氣數據,打印天氣數據前三行,實現代碼如下:
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt weather_data = pd.read_csv("/data/weatherHistory.csv") print(weather_data.head(3))
預覽截圖如下:
查看數據信息:
weather_data.info()
結果如下:
查看數據集中的分類變量:
print(weather_data.describe(include='all'))
預覽結果如下:
print(weather_data.describe(include=['O']))
預覽截圖如下:
要預測溫度,所以需要找出數據集中不同變量之間的相關性,代碼如下:
print(weather_data.corr())
預覽截圖如下:
相關性在-1到1之間變化,1表示強相關,相關系數-1表示完全負相關,相關系數為0表示變量之間不存在關系。從上圖可知,我們看到溫度與表觀溫度、濕度之間有很強的關系,也許我們還可以包括能見度。接着,我們將所有相關屬性放入一個新的數據集中並再次檢查相關性。
具體實現代碼如下所示:
data_set=weather_data.iloc[:,[0,3,4,5,8]] print(data_set.corr())
預覽截圖如下:
現在,讓我們可視化溫度和其他因變量之間的數據,繪制溫度和濕度之間的散點圖。實現代碼如下:
# 指定繪圖對象的寬度和高度 plt.figure(figsize=(14,4)) plt.xlabel('Temperature (C)') plt.ylabel('Humidity') # 繪制溫度和濕度散點圖 sns.regplot(x=data_set["Temperature (C)"], y=data_set["Humidity"],data=data_set) plt.show()
預覽截圖:
圖中,濕度和溫度之間存在負相關,我們也看到了一些異常值。我們可以嘗試找到這些異常值,並將這些異常值進行刪除。在統計中了解到,異常值會極大的影響線性回歸。下面,我們通過編寫一個函數來幫助我們識別數據集中濕度變量的異常值。它發現異常值的方式是基於標准差大於3。實現代碼如下所示:
outliers=[] def detect_outlier(data_1): threshold=3 mean_1 = np.mean(data_1) std_1 =np.std(data_1) for y in data_1: z_score= (y - mean_1)/std_1 if np.abs(z_score) > threshold: outliers.append(y) return outliers outlier_data = detect_outlier(data_set["Humidity"]) print (outlier_data)
預覽結果如下:
接着,我們從數據集中刪除這些行以獲得用於回歸的干凈數據集。因此,我們在data_set中搜索所有值大於0.15的濕度值並創建一個新的數據集data_set_clean。實現代碼如下:
data_set_clean = data_set[data_set["Humidity"]>0.15]
然后,我們再來再次繪制溫度和濕度之間的數據以檢查是否還有異常值。實現代碼如下:
# 繪制干凈數據的溫度和濕度的散點圖 sns.regplot(x=data_set_clean["Temperature (C)"], y=data_set_clean["Humidity"]) plt.show()
預覽截圖如下:
現在,讓我們在溫度和表觀溫度之間再畫一個散點圖,實現代碼如下:
# 溫度與表觀溫度的散點圖 sns.regplot(x=data_set["Temperature (C)"], y=data_set["Apparent Temperature (C)"]) plt.show()
預覽截圖:
從上圖看起來溫度和表觀溫度之間存在很強的正相關性,這也很明顯。下面,我們再繪制溫度和能見度之間的散點圖,實現代碼如下:
# 溫度與能見度散點圖 sns.regplot(x=data_set["Temperature (C)"], y=data_set["Visibility (km)"]) plt.show()
預覽截圖:
從圖中,我們沒有看到溫度和能見度之間有很強的關系,所以我們可以降低能見度。這里X是我們與濕度和表觀溫度的自變量,Y是我們試圖首先學習然后計划預測的溫度因變量。代碼如下:
# 過濾數據集 data_set_clean = data_set[data_set["Humidity"]>0.15] y= data_set_clean.iloc[:,[1]] X= data_set_clean.iloc[:,[2,3]] print(data_set_clean[data_set_clean["Humidity"]<=0.15])
預覽截圖:
打印一行X以查看我們的自變量,代碼如下:
print(X.head(1))
預覽截圖:
通過,80:20的比例將數據集拆分為訓練集和測試集,代碼如下:
# 80:20 進行拆分 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0) # 訓練集 from sklearn.linear_model import LinearRegression regressor =LinearRegression() regressor.fit(X_train, y_train)
我們使用sklearn庫的linear_models來擬合多元線性回歸的訓練數據,然后,從sklearn.linear_models導入庫線性回歸,並創建一個回歸對象,然后嘗試擬合訓練數據。
接着,我們打印回歸量的不同值並了解它們的含義。代碼如下:
print(regressor.coef_)
結果如下:
記住線性回歸方程式,公式如下:
- 0.857是b1,其中x1是表觀溫度
- -2.648是b2,其中x2是濕度
接着,我們找b0,代碼如下:
print(regressor.intercept_)
截圖如下:
現在,讓我們把這些數字帶入公式內進行計算,公式如下:
溫度 = 4.58 + (表觀溫度 * 0.857) + (-2.648 * 濕度)
我們現在可以預測測試數據集的溫度,代碼如下:
# 預測測試集結果 y_pred = regressor.predict(X_test)
那我們如何知道衡量模型的適用性呢?一個好的擬合模型是這樣一種模型,其中實際值或觀察值與基於模型的預測值之間的差異很小且無偏。所以,如果一些統計數據告訴我們實際值和預測值之間的R2可以衡量模型或回歸線對實際結果的復制程度,這是基於模型解釋的預測的總變化。
R2始終介於0和1之間或者0%到100%之間。值1表示該模型解釋了預測變量圍繞其均值的所有變化。
- SSE = 實際值 - 預測值,表示與實際值相比,預測的值有多遠;
- SST = 實際值 - 平均值,表示實際值與平均值相比有多遠;
- SSR = 預測值 - 平均值
如果預測誤差較低,則SSE將較低且R2將接近1。這里需要注意的是,當我們添加更多的自變量時,R2會獲得更高的值,R2值隨着更多的自變量的加入而不斷增加,即使它們可能不會真正對預測產生重大影響。為了解決這個問題,我們對R2進行了調整,調整后R2會在每次添加一個無關緊要的自變量時修正該模型。
print(regressor.score(X,y))
結果如下:
當R2接近1的值表示擬合良好。
另外,我們還可以計算均方根誤差,也稱RMSE。
RMSE顯示預測值和實際值之間的變化,由於預測值和實際值之間的差異可以是正值也可以是負值,為了抵消這種差異,我們取預測值和實際值之間的差異的平方。
- 找出每個觀測值的預測值和實際值之間的差異,然后將值的平方並累加:sum(預測值-實際值)2
- 總和除以觀察次數:sum(預測值-實際值)2/觀察次數
- 取第2步中的值的平方根
實現代碼如下:
from sklearn import metrics import math print(math.sqrt(metrics.mean_squared_error(y_test, y_pred)))
預覽截圖:
接着,我們可以使用另一個庫statsmodel,代碼如下:
import statsmodels.api as sm ones_1 =[1] * X.count() X["b0"]=ones_1
現在,我們使用OLS普通最小二乘法來找到最佳擬合回歸線,代碼如下:
model = sm.OLS(y_pred,X_test).fit() print(model.summary())
預覽結果如下:
從上圖運行結果可以看出,我們從之前的0.987值得到了一個更加好的0.997平方根值。
3.總結
整個實例的運行代碼,如下所示:

import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt weather_data = pd.read_csv("/data/weatherHistory.csv") # print(weather_data.head(3)) # weather_data.info() # print(weather_data.describe(include='all')) # print(weather_data.describe(include=['O'])) # print(weather_data.corr()) data_set=weather_data.iloc[:,[0,3,4,5,8]] # print(data_set.corr()) # 指定繪圖對象的寬度和高度 plt.figure(figsize=(14,4)) plt.xlabel('Temperature (C)') plt.ylabel('Humidity') # 繪制溫度和濕度散點圖 # sns.regplot(x=data_set["Temperature (C)"], y=data_set["Humidity"],data=data_set) # plt.show() outliers=[] def detect_outlier(data_1): threshold=3 mean_1 = np.mean(data_1) std_1 =np.std(data_1) for y in data_1: z_score= (y - mean_1)/std_1 if np.abs(z_score) > threshold: outliers.append(y) return outliers outlier_data = detect_outlier(data_set["Humidity"]) # print (outlier_data) data_set_clean = data_set[data_set["Humidity"]>0.15] # 繪制干凈數據的溫度和濕度的散點圖 # sns.regplot(x=data_set_clean["Temperature (C)"], y=data_set_clean["Humidity"]) # plt.show() # 溫度與表觀溫度的散點圖 # sns.regplot(x=data_set["Temperature (C)"], y=data_set["Apparent Temperature (C)"]) # plt.show() # 溫度與能見度散點圖 # sns.regplot(x=data_set["Temperature (C)"], y=data_set["Visibility (km)"]) # plt.show() # 過濾數據集 data_set_clean = data_set[data_set["Humidity"]>0.15] y= data_set_clean.iloc[:,[1]] X= data_set_clean.iloc[:,[2,3]] # print(data_set_clean[data_set_clean["Humidity"]<=0.15]) # print(X.head(1)) # 80:20 進行拆分 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0) # 訓練集 from sklearn.linear_model import LinearRegression regressor =LinearRegression() regressor.fit(X_train, y_train) # print(regressor.coef_) # print(regressor.intercept_) # 預測測試集結果 y_pred = regressor.predict(X_test) # print(regressor.score(X,y)) from sklearn import metrics import math # print(math.sqrt(metrics.mean_squared_error(y_test, y_pred))) import statsmodels.api as sm ones_1 =[1] * X.count() X["b0"]=ones_1 model = sm.OLS(y_pred,X_test).fit() print(model.summary())
4.結束語
這篇博客就和大家分享到這里,如果大家在研究學習的過程當中有什么問題,可以加群進行討論或發送郵件給我,我會盡我所能為您解答,與君共勉!
另外,博主出書了《Kafka並不難學》和《Hadoop大數據挖掘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那里點擊購買鏈接購買博主的書進行學習,在此感謝大家的支持。關注下面公眾號,根據提示,可免費獲取書籍的教學視頻。