1. 程式人生 > >使用機器學習預測天氣(第二部分)

使用機器學習預測天氣(第二部分)

概述

  這篇文章我們接著前一篇文章,使用Weather Underground網站獲取到的資料,來繼續探討用機器學習的方法預測內布拉斯加州林肯市的天氣
  上一篇文章我們已經探討了如何收集、整理、清洗資料。這篇文章我們將使用上一篇文章處理好的資料,建立線性迴歸模型來預測天氣。為了建立線性迴歸模型,我要用到python裡非常重要的兩個機器學習相關的庫:Scikit-Learn和StatsModels 。
  第三篇文章我們將使用google TensorFlow來建立神經網路模型,並把預測的結果和線性迴歸模型的結果做比較。
  這篇文章中會有很多數學概念和名詞,如果你理解起來比較費勁,建議你先google相關資料概念,有個基礎的瞭解。

獲取資料

  在這個Github倉庫,有個名為Underground API.ipynb的 Jupyter Notebook檔案,這個檔案記錄了我們這篇文章和下一篇文章要用到的資料的獲取、整理步驟。你還會發現一個名為end-part1_df.pkl的檔案,如果你自己沒有處理好資料,可以直接用這個檔案,然後使用下面的程式碼來把資料轉成Pandas DataFrame型別。

import pickle  
with open('end-part1_df.pkl', 'rb') as fp:  
    df = pickle.load(fp)

如果執行上面的程式碼遇到錯誤:No module named 'pandas.indexes'

,那麼說明你用的pandas庫的版本和我的(v0.18.1)不一致,為了避免這樣的錯誤發生,我還準備了個csv檔案,你可以從上述的Github倉庫獲取,然後使用下面的程式碼讀入資料。

import pandas as pd  
df = pd.read_csv('end-part2_df.csv').set_index('date')

線性迴歸演算法

  線性迴歸模型的目標是使用一系列線性相關的資料和數字技術來根據預測因素X(自變數)來預測可能的結果Y(因變數),最終建立一個模型(數學公式)來預測給定任意的預測因素X來計算對應的結果Y。
  線性迴歸的一般公式為:

ŷ = β0
+ β1 * x1 + β2 * x2 + ... + β(p-n) x(p-n) + Ε

為模型選取特徵資料

  線性迴歸技術要求的關鍵假設是,因變數和每個自變數之間有一個線性關係。針對我們的資料,就是溫度和其他變數,然後計算Pearson相關係數。Pearson相關係數(r)是輸出範圍為-1到1的值的等長陣列之間的線性相關量的量度。範圍從0到1的相關值表示越來越強的正相關性。 這意味著當一個數據序列中的值與另一個序列中的值同時增加時,兩個資料序列呈正相關,並且由於它們兩者的上升幅度越來越相等,Pearson相關值將接近1。從0到-1的相關值被認為是相反或負相關的,因為當一個系列的值增加相反系列減小的相應值時,但是當系列之間的幅度變化相等(相反的方向)時, 相關值將接近-1。 緊密地跨越零的Pearson相關值暗示著具有弱的線性關係,隨著值趨近於零而變弱。
  關於相關係數的強度界定,統計學家和統計書籍中的觀點各不相同。 但是,我發現一個普遍接受的關聯強度分類集合如下:

為了評估這個資料中的相關性,我將呼叫Pandas DataFrame物件的corr()方法。通過corr()函式的呼叫,我可以選擇我感興趣的資料(meantempm),然後再對返回的結果(Pandas Series object)呼叫sort_values()函式,這將輸出從最負相關到最正相關的相關值。

df.corr()[['meantempm']].sort_values('meantempm')  



  在選擇包括在這個線性迴歸模型中的特徵時,我想在包含具有中等或較低相關係數的變數時略微寬容一些。 所以我將刪除相關值的絕對值小於0.6的特徵。 此外,由於“mintempm”和“maxtempm”變數與預測變數“meantempm”同一天,我也將刪除這些(即,如果我已經知道最高和最低溫度,那麼我已經有了我的答案)。有了這些資訊,我現在可以建立一個新的DataFrame,它只包含我感興趣的變數。

predictors = ['meantempm_1',  'meantempm_2',  'meantempm_3',  
              'mintempm_1',   'mintempm_2',   'mintempm_3',
              'meandewptm_1', 'meandewptm_2', 'meandewptm_3',
              'maxdewptm_1',  'maxdewptm_2',  'maxdewptm_3',
              'mindewptm_1',  'mindewptm_2',  'mindewptm_3',
              'maxtempm_1',   'maxtempm_2',   'maxtempm_3']
df2 = df[['meantempm'] + predictors]  

視覺化展示資料關係

因為大多數人,包括我自己在內,都更習慣於用視覺來評估和驗證模式,所以我將繪製每個選定的預測因子來證明資料的線性關係。 要做到這一點,我將利用matplotlib的pyplot模組。
對於這個圖,我希望將因變數“meantempm”作為沿所有18個預測變數圖的一致y軸。 一種方法是建立一個的網格。 Pandas的確有一個有用的繪圖函式叫做scatter_plot(),但是通常只有當大約只有5個變數時才使用它,因為它將繪圖變成一個N×N的矩陣(在我們的例子中是18×18) 變得難以看到資料中的細節。 相反,我將建立一個六行三列的網格結構,以避免犧牲圖表的清晰度。

import matplotlib  
import matplotlib.pyplot as plt  
import numpy as np
# manually set the parameters of the figure to and appropriate size
plt.rcParams['figure.figsize'] = [16, 22]
# call subplots specifying the grid structure we desire and that 
# the y axes should be shared
fig, axes = plt.subplots(nrows=6, ncols=3, sharey=True)

# Since it would be nice to loop through the features in to build this plot
# let us rearrange our data into a 2D array of 6 rows and 3 columns
arr = np.array(predictors).reshape(6, 3)

# use enumerate to loop over the arr 2D array of rows and columns
# and create scatter plots of each meantempm vs each feature
for row, col_arr in enumerate(arr):  
    for col, feature in enumerate(col_arr):
        axes[row, col].scatter(df2[feature], df2['meantempm'])
        if col == 0:
            axes[row, col].set(xlabel=feature, ylabel='meantempm')
        else:
            axes[row, col].set(xlabel=feature)
plt.show()



從上面的圖中可以看出,所有其餘的預測變數與響應變數(“meantempm”)顯示出良好的線性關係。 此外,值得注意的是,這些關係都是均勻隨機分佈的。 我的意思是,在沒有任何扇形或圓錐形狀的情況下,數值的擴散似乎有相對相等的變化。 使用普通最小二乘演算法的線性迴歸的另一個重要假設是沿點的均勻隨機分佈。

使用逐步迴歸建立一個健壯的模型

  一個強大的線性迴歸模型必須選取有意義的、重要的統計指標的指標作為預測指標。 為了選擇統計上顯著的特徵,我將使用Python statsmodels庫。然而,在使用statsmodels庫之前,我想先說明採取這種方法的一些理論意義和目的。
  在分析專案中使用統計方法(如線性迴歸)的一個關鍵方面是建立和測試假設檢驗,以驗證所研究資料假設的重要性。 有很多假設檢驗已經被開發來測試線性迴歸模型對各種假設的穩健性。 一個這樣的假設檢驗是評估每個包含的預測變數的顯著性。
  βj引數意義的假設檢驗的正式定義如下:

  • H0:βj= 0,零假設表明預測變數對結果變數的值沒有影響
  • Ha:βj≠0,可選假設是預測變數對結果變數的值有顯著影響

通過使用概率測試來評估每個βj在選定閾值Α處超過簡單隨機機會的顯著性的可能性,我們可以在選擇更嚴格資料,以保證模型的魯棒性。
  然而在許多資料集中,資料間的相互影響會導致一些簡單的假設檢驗不符合預期。 為了線上性迴歸模型中測試相互作用對任何一個變數的影響,通常應用被稱為逐步迴歸的技術。 通過增加或者刪除變數來評估每個變數的變化,對產生的模型的影響。在本文中,我將使用一種稱為“後向消除”的技術,從一個包含我感興趣資料的模型開始。

  後向消除工作流程如下:

  • 選擇一個重要的階段A,能夠確定一個數據是否能通過建設檢驗。
  • 把預測資料填入模型
  • 評估βj係數的p值和p值最大的p值,如果p值>Α進行到第4步,如果不是,則得到最終模型
  • 刪除步驟3中確定的預測變數
  • 再次安裝模型,但這次沒有刪除變數,然後迴圈回到第3步

  下面我們使用statsmodels按照上面的步驟,來構建我們的模型。

# import the relevant module
import statsmodels.api as sm

# separate our my predictor variables (X) from my outcome variable y
X = df2[predictors]  
y = df2['meantempm']

# Add a constant to the predictor variable set to represent the Bo intercept
X = sm.add_constant(X)  
X.ix[:5, :5]  

# (1) select a significance value
alpha = 0.05

# (2) Fit the model
model = sm.OLS(y, X).fit()

# (3) evaluate the coefficients' p-values
model.summary()  

呼叫summary()函式輸出的資料如下:



  • 好的,我認識到,對summary()的呼叫只是把大量的資訊列印在螢幕上。在這篇文章中,我們只關注2-3個值:

  • P>| T | - 這是我上面提到的p值,我將用它來評估假設檢驗。 這是我們要用來確定是否消除這個逐步反向消除技術的變數的價值。
    R平方 - 一個衡量標準,我們的模型可以解釋結果的整體變化的多少

  • ADJ。 R平方 - 與R平方相同,但是,對於多元線性迴歸,根據包含的變數數來解釋過度擬合水平,該值會受到懲罰。

這並不是說在這個輸出中的其他價值是沒有價值的,恰恰相反,它們涉及到線性迴歸的更深奧的特質,我們現在根本沒有時間考慮到。對於他們的完整解釋,我會推遲到高階迴歸教科書,如Kutner的應用線性迴歸模型,第五版。 以及statsmodels檔案。

# (3) cont. - Identify the predictor with the greatest p-value and assess if its > our selected alpha.
#             based off the table it is clear that meandewptm_3 has the greatest p-value and that it is
#             greater than our alpha of 0.05

# (4) - Use pandas drop function to remove this column from X
X = X.drop('meandewptm_3', axis=1)

# (5) Fit the model 
model = sm.OLS(y, X).fit()

model.summary()  



關於您的閱讀時間,為了保持文章的合理長度,我將省略構建每個新模型所需的剩餘消除週期,評估p值並刪除最不重要的值。 相反,我會跳到最後一個週期,併為您提供最終的模型。 畢竟,這裡的主要目標是描述過程和背後的推理。下面你會發現我應用反向消除技術後收斂的最終模型的輸出。 您可以從輸出中看到,所有其餘的預測變數的p值顯著低於我們的0.05。 另外值得注意的是最終輸出中的R平方值。 這裡需要注意兩點:(1)R平方和Adj。 R平方值是相等的,這表明我們的模型被過度擬合的風險最小,(2)0.894的值被解釋為使得我們的最終模型解釋了結果變數中觀察到的變化的大約90% ,“meantempm”。

model = sm.OLS(y, X).fit()  
model.summary() 


使用SciKit-Learn的線性迴歸模組預測天氣

  現在我們已經完成了選擇具有統計意義的預測指標(特徵)的步驟,我們可以使用SciKit-Learn建立預測模型並測試其預測平均溫度的能力。 SciKit-Learn是一個非常完善的機器學習庫,在工業界和學術界廣泛使用。關於SciKit-Learn的一件事非常令人印象深刻的是,它在許多數值技術和演算法中保持了一個非常一致的“適應”,“預測”和“測試”API,使得使用它非常簡單。除了這個一致的API設計,SciKit-Learn還提供了一些有用的工具來處理許多機器學習專案中常見的資料。

  我們將通過使用SciKit-Learn從sklearn.model_selection模組中匯入train_test_split()函式來開始將我們的資料集分割成測試和訓練集。我將把訓練和測試資料集分成80%的訓練和20%的測試,並且分配一個12的random_state,以確保你將得到和我一樣的隨機選擇資料。這個random_state引數對結果的可重複性非常有用。

from sklearn.model_selection import train_test_split  
# first remove the const column because unlike statsmodels, SciKit-Learn will add that in for us
X = X.drop('const', axis=1)

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

接下來的操作是使用訓練資料集建立迴歸模型。 為此,我將從sklearn.linear_model模組匯入並使用LinearRegression類。 正如前面提到的,scikit-learn分數通過通用的fit()和predict()這兩個函式計算得到。

from sklearn.linear_model import LinearRegression  
# instantiate the regressor class
regressor = LinearRegression()

# fit the build the model by fitting the regressor to the training data
regressor.fit(X_train, y_train)

# make a prediction set using the test set
prediction = regressor.predict(X_test)

# Evaluate the prediction accuracy of the model
from sklearn.metrics import mean_absolute_error, median_absolute_error  
print("The Explained Variance: %.2f" % regressor.score(X_test, y_test))  
print("The Mean Absolute Error: %.2f degrees celsius" % mean_absolute_error(y_test, prediction))  
print("The Median Absolute Error: %.2f degrees celsius" % median_absolute_error(y_test, prediction))

The Explained Variance: 0.90  
The Mean Absolute Error: 2.69 degrees celsius  
The Median Absolute Error: 2.17 degrees celsius  

正如你可以在上面幾行程式碼中看到的那樣,使用scikit-learn構建線性迴歸預測模型非常簡單。

為了獲得關於模型有效性的解釋性理解,我使用了迴歸模型的score()函式來確定該模型能夠解釋在結果變數(平均溫度)中觀察到的約90%的方差。 此外,我使用sklearn.metrics模組的mean_absolute_error()和median_absolute_error()來確定平均預測值約為3攝氏度關閉,一半時間關閉約2攝氏度。

總結

在本文中,我演示了基於上一篇文章收集的資料如何使用線性迴歸機器學習演算法來預測未來的平均天氣溫度。在本文中,我演示瞭如何使用線性迴歸機器學習演算法來預測未來的平均天氣溫度,基於上一篇文章收集的資料。 我演示瞭如何使用statsmodels庫來根據合理的統計方法選擇具有統計顯著性的預測指標。 然後,我利用這些資訊來擬合基於Scikit-Learn的LinearRegression類的訓練子集的預測模型。 然後使用這個擬合的模型,我可以根據測試子集的輸入預測預期值,並評估預測的準確性。

相關文章

轉自我的部落格:捕蛇者說