用美元預測房價?Scikit-Learn庫實現線性迴歸教程


迴歸和分類是兩種監督機器學習算法,前者預測連續值輸出,而後者預測離散輸出。例如,用美元預測房屋的價格是迴歸問題,而預測腫瘤是惡性的還是良性的則是分類問題。

在本文中,我們將簡要研究線性迴歸是什麼,以及如何使用Scikit-Learn(最流行的Python機器學習庫之一)在兩個變量和多個變量的情況下實現線性迴歸。

用美元預測房價?Scikit-Learn庫實現線性迴歸教程

線性迴歸理論


代數學中,術語“線性”是指兩個或多個變量之間的線性關係。如果在二維空間中繪製兩個變量之間的關係,可以得到一條直線。

線性迴歸可以根據給定的自變量(x)預測因變量值(y),而這種迴歸技術可以確定x(輸入)和y(輸出)之間的線性關係,因此稱之為線性迴歸。如果在x軸上繪製自變量(x),又在y軸上繪製因變量(y),線性迴歸給出了一條最符合數據點的直線,如下圖所示。

得出線性方程大概是:

用美元預測房價?Scikit-Learn庫實現線性迴歸教程

上述等式應為:Y= mx + b


其中b是截距,m是直線的斜率。線性迴歸算法大體上提供了截距和斜率的最優值。因為x和y是數據特徵,因此這兩個變量保持不變。可以控制的值是截距(b)和斜率(m)。根據截距和斜率的值,圖上可以有多條直線。線性迴歸算法的可以找到符合數據點的多條線,並確認導致最小誤差的其中一條線。

兩個以上的變量的情況也適合使用線性迴歸,這可稱為多元線性迴歸。比方說,假設這樣一個場景,你必須根據房屋面積、臥室數量、住房人口的平均收入、屋齡等來預測房屋的價格。在這種情況下,因變量(目標變量)取決於幾個不同的獨立變量。而這種涉及多個變量的迴歸模型可表示為:

y = b0 + m1b1 +m2b2 + m3b3 + ... mnbn

這是超平面的等式。請牢記,二維線性迴歸模型是一條直線; 而三維線性迴歸模型則是一個平面,並且三維以上是超平面。

本節內容將介紹Python中用於機器學習的Scikit-Learn庫如何實現迴歸函數。我們將從涉及兩個變量的簡單線性迴歸開始,然後逐步轉向涉及多個變量的線性迴歸。

用美元預測房價?Scikit-Learn庫實現線性迴歸教程

簡單線性迴歸

用美元預測房價?Scikit-Learn庫實現線性迴歸教程

線性迴歸


在查看第二次世界大戰數據集中空中轟炸行動的記錄時,我發現惡劣天氣幾乎要推遲當時的諾曼底登陸,下載了當時的天氣報告,以便與轟炸行動數據集的任務進行比較。

該數據集包含世界各地氣象站每天記錄的天氣狀況信息,內容包括降水、降雪、氣溫和風速,同時也記錄了當天是否出現雷暴或其他惡劣天氣情況。

將這些輸入特徵值看成是最低溫度,從而以預測最高溫。

開始編碼

導入所需的庫:

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import seaborn as seabornInstance
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
%matplotlib inline


以下命令使用pandas導入CSV數據集:

dataset =pd.read_csv('/Users/nageshsinghchauhan/Documents/projects/ML/ML_BLOG_LInearRegression/Weather.csv')


通過檢查數據集內的行數和列數,大概對數據有了一點認識。

dataset.shape


如果輸出值寫著 (119040, 31),這意味著這個數據集含有119040行和31列。

可以使用describe()以查看數據集的統計詳細信息:

dataset.describe()
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

數據集的統計視圖


最後,在二維圖上繪製我們的數據點並觀察我們的數據集,看看是否可以使用以下腳本手動查找數據之間的關係:

dataset.plot(x='MinTemp', y='MaxTemp', style='o') 
plt.title('MinTemp vs MaxTemp')
plt.xlabel('MinTemp')
plt.ylabel('MaxTemp')
plt.show()


我們採用了MinTemp和MaxTemp進行分析。下面是MinTemp和MaxTemp之間的二維圖。

用美元預測房價?Scikit-Learn庫實現線性迴歸教程


查找一下平均最高溫度——二維圖繪製完成後,可以觀察到平均最高溫度在25(攝氏度)和35(攝氏度)之間。

plt.figure(figsize=(15,10))
plt.tight_layout()
seabornInstance.distplot(dataset['MaxTemp'])
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

平均最高溫在20到35之間


下一步,把這些數據分為“屬性”和“標籤”兩類。

屬性是自變量,而標籤是因變量,其值有待預測。在我們的數據集中,我們只有兩列數據。我們想根據記錄的MinTemp來預測MaxTemp,因此屬性集將包含存儲在X變量中的“MinTemp”列,而標籤則存儲在y變量中的“MaxTemp”列。

X = dataset['MinTemp'].values.reshape(-1,1)
y = dataset['MaxTemp'].values.reshape(-1,1)


接下來,80%的數據將作為訓練樣本集,而另外的20%則用於測試以下編碼。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=0)


在將數據分成訓練集和測試集後,便開始訓練算法。為此,需要導入LinearRegression類,並將之實例化,並採用fit()方法已驗證這些訓練數據。

regressor = LinearRegression() 
regressor.fit(X_train, y_train) #training the algorithm


我們前面曾討論過,線性迴歸模型可以大致找到截距和斜率的最佳值,從而確定最符合相關數據的線的位置。如要查看線性迴歸算法為我們的數據集計算的截距和斜率的值,請執行以下代碼。

#To retrieve the intercept:
print(regressor.intercept_)
#For retrieving the slope:
print(regressor.coef_)


結果分別約為10.66185201與0.92033997。

這意味著——若最低溫度發生變化,那麼最高溫度有0.92%的可能性也發生變化。

既然已經訓練了這算法,現在是時候進行一些預測了。為需要測試數據,並檢驗算法預測百分比得分的準確程度。要對測試數據進行預測,請執行以下腳本:

y_pred = regressor.predict(X_test)


現在將X_test的實際輸出值與預測值進行比較,請執行以下腳本:

df = pd.DataFrame({'Actual': y_test.flatten(), 'Predicted':y_pred.flatten()})
df
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

實際值與預測值的比較


還可以使用以下腳本,用條形圖的方式展示這些比較:

注意:由於記錄數量龐大,為了更好的展示效果,我們只使用了其中25條記錄。

df1 = df.head(25)
df1.plot(kind='bar',figsize=(16,10))
plt.grid(which='major', linestyle='-', linewidth='0.5', color='green')
plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.show()
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

實際值與預測值比較的條形圖


儘管這個模型不盡準確,但預測的百分比依然接近實際數值。

根據這些測試數據可以畫出一條直線:

plt.scatter(X_test, y_test, color='gray')
plt.plot(X_test, y_pred, color='red', linewidth=2)
plt.show()
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

預測值和測試數據


圖上直線顯示我們的算法無誤。

最後一步是評估算法的性能。此步驟對於比較不同算法在特定數據集上的實現情況尤為重要。對於迴歸算法,通常使用三種評估指標:

1.平均絕對誤差(MAE)指的是誤差絕對值的平均值。計算方法如下:

用美元預測房價?Scikit-Learn庫實現線性迴歸教程


2.均方誤差(MSE)是平方誤差的平均值,計算公式如下:

用美元預測房價?Scikit-Learn庫實現線性迴歸教程


3.均方根誤差 (RMSE)為平方誤差均值的平方根:

用美元預測房價?Scikit-Learn庫實現線性迴歸教程


幸運的是,我們無需手動計算,Scikit-Learn庫的預建功能可以計算這些值。

使用測試數據找到這些指標的值。

print('MeanAbsolute Error:', metrics.mean_absolute_error(y_test, y_pred)) 
print('MeanSquared Error:', metrics.mean_squared_error(y_test, y_pred))
print('RootMean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred))


你會得到這樣的輸出結果(結果可能略有不同):

('MeanAbsolute Error:', 3.19932917837853)
('MeanSquared Error:', 17.631568097568447)
('RootMean Squared Error:', 4.198996082109204)


由上可見,均方根誤差的值是4.19,這個數值超過了所有溫度百分比平均值的10%,即22.41。這意味著我們的算法不是很準確,但預測能力良好。

用美元預測房價?Scikit-Learn庫實現線性迴歸教程

多元線性迴歸


用美元預測房價?Scikit-Learn庫實現線性迴歸教程

來源


上面部分主要針對兩個變量進行線性迴歸,但你遇到的所有實際問題中變量可不止兩個。涉及多個變量的線性迴歸則稱為“多元線性迴歸”。執行多元線性迴歸的步驟與簡單線性迴歸的步驟相似。不同之處在於評估過程。利用多元線性迴歸可以找出哪個因素對預測輸出的影響最大,以及不同變量之間的相互關係。

在本節中,我們下載了紅葡萄酒質量數據集,該數據集與葡萄牙的“Vinho Verde”(綠酒)葡萄酒的紅色變體有關。由於隱私和後勤問題,我們只掌握物理化學(輸入)變量和感官(輸出)變量的數據(例如,關於葡萄類型,葡萄酒品牌,葡萄酒銷售價格等的數據暫缺)。

將考慮各種輸入特徵,如固定酸度,揮發性酸度,檸檬酸,殘糖,氯化物,遊離二氧化硫,總二氧化硫,密度,pH,硫酸鹽,酒精。我們將利用這些特徵來預測葡萄酒的質量。

開始編碼

輸入所需的庫:

importpandas as pd 
importnumpy as np
importmatplotlib.pyplot as plt
importseaborn as seabornInstance
fromsklearn.model_selection import train_test_split
fromsklearn.linear_model import LinearRegression
fromsklearn import metrics
%matplotlibinline


以下指令將通過上面的鏈接從下載的文件中導入數據集:

dataset =pd.read_csv('/Users/nageshsinghchauhan/Documents/projects/ML/ML_BLOG_LInearRegression/winequality.csv')


通過檢查數據集內的行數和列數,我們大概對以上數據有了一點認識。

dataset.shape


若輸出值為(1599,12),則表明數據集中行數為1599,列數為12.

我們可以使用describe()以查看數據集的統計詳細信息:

dataset.describe()


用美元預測房價?Scikit-Learn庫實現線性迴歸教程


我們還需對數據進行篩選,首先查找哪些列含有NaN值:

dataset.isnull().any()


執行上面的代碼後,所有列都會顯示最後的結果False,如果有一列出現了True,則使用下面的代碼從該列中刪除所有空值。

dataset= dataset.fillna(method='ffill')


下一步是將數據劃分為“屬性”和“標籤”。X變量包含所有屬性/特徵,y變量包含標籤。

X = dataset[['fixed acidity', 'volatileacidity', 'citric acid', 'residual sugar', 'chlorides', 'free sulfur dioxide','total sulfur dioxide', 'density', 'pH', 'sulphates','alcohol']].values
y = dataset['quality'].values


計算“質量”一行的平均值。

plt.figure(figsize=(15,10))
plt.tight_layout()
seabornInstance.distplot(dataset['quality'])
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

葡萄酒質量的平均值


從上圖可得,大部分葡萄酒的質量平均值為5或6。

接下來,80%的數據將作為訓練樣本集,而另外的20%則用於測試以下編碼。

X_train,X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)


現在開始測試模型。

regressor= LinearRegression() 
regressor.fit(X_train,y_train)


如前所述,在多變量線性迴歸中,迴歸模型必須找到所有屬性的最佳係數。如要查看該回歸模型選擇了哪些係數,請執行以下腳本:

coeff_df= pd.DataFrame(regressor.coef_, X.columns, columns=['Coefficient']) 
coeff_df


最後的輸出值大致如下:

用美元預測房價?Scikit-Learn庫實現線性迴歸教程


這意味著,隨著“密度”的單位增加,葡萄酒的質量減少了31.51個單位。同理,“氯化物”的單位的減少也會使得葡萄酒質量增加1.87個單位。同時我們還可以可以看到其餘的特徵對葡萄酒的質量影響很小。

現在對測試數據進行預測。

y_pred= regressor.predict(X_test)


檢驗實際值和預測值之間的差異。

df =pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df1= df.head(25)
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

實際值與預測值的對比


對實際值和預測值之間對比進行描點:

df1.plot(kind='bar',figsize=(10,8))
plt.grid(which='major',linestyle='-', linewidth='0.5', color='green')
plt.grid(which='minor',linestyle=':', linewidth='0.5', color='black')
plt.show()
用美元預測房價?Scikit-Learn庫實現線性迴歸教程

以上條形圖可用於展示預測值和實際值之間的差異


可以看到,這個模型的預測結果比較準確。

最後一步是評估算法的性能。我們將通過計算MAE,MSE和RMSE的值來完成此操作。請執行以下腳本:

print('MeanAbsolute Error:', metrics.mean_absolute_error(y_test, y_pred))
print('MeanSquared Error:', metrics.mean_squared_error(y_test, y_pred))
print('RootMean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))


輸出值為:

('MeanAbsolute Error:', 0.46963309286611077)
('MeanSquared Error:', 0.38447119782012446)
('RootMean Squared Error:', 0.6200574149384268)


可以看到,均方根誤差值為0.62,略大於所有狀態下的氣體消耗平均值的10%,即5.63。這意味著算法還不夠精準,但其預測能力依然讓人認同。

導致這種不準確的有多種因素,如:

  • 數據量不足:需要大量數據才能獲得最準確的預測。
  • 假設失誤:假設這些數據具有線性關係,但實際可能並非如此。可以將數據可視化來確定結果。
  • 屬性關聯度低:參與計算的屬性與我們的預測值關聯度不大。
用美元預測房價?Scikit-Learn庫實現線性迴歸教程


分享到:


相關文章: