1.1.1 線性迴歸(Linear Regression)

線性迴歸(Linear Regression)

1.什麼是線性迴歸

我們首先用弄清楚什麼是線性,什麼是非線性。

  • 線性:兩個變量之間的關係一次函數關係的——圖象是直線,叫做線性。

    注意:題目的線性是指廣義的線性,也就是數據與數據之間的關係。

  • 非線性:兩個變量之間的關係不是一次函數關係的——圖象不是直線,叫做非線性。

相信通過以上兩個概念大家已經很清楚了,其次我們經常說的迴歸到底是什麼意思呢。

  • 迴歸:人們在測量事物的時候因爲客觀條件所限,求得的都是測量值,而不是事物真實的值,爲了能夠得到真實值,無限次的進行測量,最後通過這些測量數據計算迴歸到真實值,這就是迴歸的由來。

通俗的說就是用一個函數去逼近這個真實值,那又有人問了,線性迴歸不是用來做預測嗎?是的,通過大量的數據我們是可以預測到真實值的。

2.線性迴歸要解決什麼問題

對大量的觀測數據進行處理,從而得到比較符合事物內部規律的數學表達式。也就是說尋找到數據與數據之間的規律所在,從而就可以模擬出結果,也就是對結果進行預測。解決的就是通過已知的數據得到未知的結果。例如:對房價的預測、判斷信用評價、電影票房預估等。

3.線性迴歸的一般模型 

image

大家看上面圖片,圖片上有很多個小點點,通過這些小點點我們很難預測當x值=某個值時,y的值是多少,我們無法得知,所以,數學家是很聰明的,是否能夠找到一條直線來描述這些點的趨勢或者分佈呢?答案是肯定的。相信大家在學校的時候都學過這樣的直線,只是當時不知道這個方程在現實中是可以用來預測很多事物的。

那麼問題來了,什麼是模型呢?先來看看下面這幅圖。

image

假設數據就是x,結果是y,那中間的模型其實就是一個方程,這是一種片面的解釋,但有助於我們去理解模型到底是個什麼東西。以前在學校的時候總是不理解數學建模比賽到底在做些什麼,現在理解了,是從題目給的數據中找到數據與數據之間的關係,建立數學方程模型,得到結果解決現實問題。其實是和機器學習中的模型是一樣的意思。那麼線性迴歸的一般模型是什麼呢?

image

模型神祕的面紗已經被我們揭開了,就是以上這個公式,不要被公式嚇到,只要知道模型長什麼樣就行了。假設i=0,表示的是一元一次方程,是穿過座標系中原點的一條直線,以此類推。

4.如何使用模型

我們知道x是已知條件,通過公式求出y。已知條件其實就是我們的數據,以預測房價的案例來說明:

image

上圖給出的是某個地區房價的一些相關信息,有日期、房間數、建築面積、房屋評分等特徵,表裏頭的數據就是我們要的x1、x2、x3…….... 自然的表中的price列就是房屋的價格,也就是y。現在需要求的就是theta的值了,後續步驟都需要依賴計算機來訓練求解。

5.模型計算

當然,這些計算雖然複雜,但python庫中有現成的函數直接調用就可以求解。我們爲了理解內部的計算原理,就需要一步一步的來剖析計算過程。

爲了容易理解模型,假設該模型是一元一次函數,我們把一組數據x和y帶入模型中,會得到如下圖所示線段。

image

是不是覺得這條直線擬合得不夠好?顯然最好的效果應該是這條直線穿過所有的點纔是,需要對模型進行優化,這裏我們要引入一個概念。

  • 損失函數:是用來估量你模型的預測值 f(x)與真實值 YY 的不一致程度,損失函數越小,模型的效果就越好。

image

不要看公式很複雜,其實就是一句話,(預測值-真實值)的平法和的平均值,換句話說就是點到直線距離和最小。用一幅圖來表示:

image

解釋:一開始損失函數是比較大的,但隨着直線的不斷變化(模型不斷訓練),損失函數會越來越小,從而達到極小值點,也就是我們要得到的最終模型。

這種方法我們統稱爲梯度下降法。隨着模型的不斷訓練,損失函數的梯度越來越平,直至極小值點,點到直線的距離和最小,所以這條直線就會經過所有的點,這就是我們要求的模型(函數)。

以此類推,高維的線性迴歸模型也是一樣的,利用梯度下降法優化模型,尋找極值點,這就是模型訓練的過程。

6.過擬合與欠擬合(underfitting and overfitting)

在機器學習模型訓練當中,模型的泛化能力越強,就越能說明這個模型表現很好。什麼是模型的泛化能力?

  • 模型的泛化能力:機器學習模型學習到的概念在它處於學習的過程中時模型沒有遇見過的樣本時候的表現。

模型的泛化能力直接導致了模型會過擬合與欠擬合的情況。讓我們來看看一下情況:

image

我們的目標是要實現點到直線的平方和最小,那通過以上圖示顯然可以看出中間那幅圖的擬合程度很好,最左邊的情況屬於欠擬合,最右邊的情況屬於過擬合。

  • 欠擬合:訓練集的預測值,與訓練集的真實值有不少的誤差,稱之爲欠擬合。

  • 過擬合:訓練集的預測值,完全貼合訓練集的真實值,稱之爲過擬合。

欠擬合已經很明白了,就是誤差比較大,而過擬合呢是訓練集上表現得很好,換一批數據進行預測結果就很不理想了,泛化泛化說的就是一個通用性。

解決方法

使用正則化項,也就是給梯度下降公式加上一個參數,即:

image

加入這個正則化項好處:

  • 控制參數幅度,不讓模型“無法無天”。

  • 限制參數搜索空間

  • 解決欠擬合與過擬合的問題。

看到這裏是不是覺得很麻煩,我之前說過現在是解釋線性迴歸模型的原理與優化,但是到了真正使用上這些方法是一句話的事,因爲這些計算庫別人已經準備好了,感謝開源吧!

7.Python實現代碼

1.題目:

        從給定的房屋基本信息以及房屋銷售信息等,建立一個迴歸模型預測房屋的銷售價格。 數據下載請點擊:下載,密碼:mfqy。

  • 數據說明: 數據主要包括2014年5月至2015年5月美國King County的房屋銷售價格以及房屋的基本信息。 數據分爲訓練數據和測試數據,分別保存在kc_train.csv和kc_test.csv兩個文件中。 其中訓練數據主要包括10000條記錄,14個字段,主要字段說明如下: 第一列“銷售日期”:2014年5月到2015年5月房屋出售時的日期 第二列“銷售價格”:房屋交易價格,單位爲美元,是目標預測值 第三列“臥室數”:房屋中的臥室數目 第四列“浴室數”:房屋中的浴室數目 第五列“房屋面積”:房屋裏的生活面積 第六列“停車面積”:停車坪的面積 第七列“樓層數”:房屋的樓層數 第八列“房屋評分”:King County房屋評分系統對房屋的總體評分 第九列“建築面積”:除了地下室之外的房屋建築面積 第十列“地下室面積”:地下室的面積 第十一列“建築年份”:房屋建成的年份 第十二列“修復年份”:房屋上次修復的年份 第十三列"緯度":房屋所在緯度 第十四列“經度”:房屋所在經度

        測試數據主要包括3000條記錄,13個字段,跟訓練數據的不同是測試數據並不包括房屋銷售價格,學員需要通過由訓練數據所建立的模型以及所給的測試數據,得出測試數據相應的房屋銷售價格預測值。

2.步驟

  • 1.選擇合適的模型,對模型的好壞進行評估和選擇。
  • 2.對缺失的值進行補齊操作,可以使用均值的方式補齊數據,使得準確度更高。
  • 3.數據的取值一般跟屬性有關係,但世界萬物的屬性是很多的,有些值小,但不代表不重要,所有爲了提高預測的準確度,統一數據維度進行計算,方法有特徵縮放和歸一法等。
  • 4.數據處理好之後就可以進行調用模型庫進行訓練了。
  • 5.使用測試數據進行目標函數預測輸出,觀察結果是否符合預期。或者通過畫出對比函數進行結果線條對比。

3.模型選擇

這裏我們選擇多元線性迴歸模型。公式如下:選擇多元線性迴歸模型。 

y表示我們要求的銷售價格,x表示特徵值。需要調用sklearn庫來進行訓練。

4.環境配置

  • python3.5
  • numpy庫
  • pandas庫
  • matplotlib庫進行畫圖
  • seaborn庫
  • sklearn庫

5.csv數據處理

下載的是兩個數據文件,一個是真實數據,一個是測試數據,打開kc_train.csv,能夠看到第二列是銷售價格,而我們要預測的就是銷售價格,所以在訓練過程中是不需要銷售價格的,把第二列刪除掉,新建一個csv文件存放銷售價格這一列,作爲後面的結果對比。

6.數據處理

首先先讀取數據,查看數據是否存在缺失值,然後進行特徵縮放統一數據維度。代碼如下:(注:最後會給出完整代碼)

#讀取數據
housing = pd.read_csv('kc_train.csv')
target=pd.read_csv('kc_train2.csv')  #銷售價格
t=pd.read_csv('kc_test.csv')         #測試數據

#數據預處理
housing.info()    #查看是否有缺失值

#特徵縮放
from sklearn.preprocessing import MinMaxScaler
minmax_scaler=MinMaxScaler()
minmax_scaler.fit(housing)   #進行內部擬合,內部參數會發生變化
scaler_housing=minmax_scaler.transform(housing)
scaler_housing=pd.DataFrame(scaler_housing,columns=housing.columns)

7.模型訓練

使用sklearn庫的線性迴歸函數進行調用訓練。梯度下降法獲得誤差最小值。最後使用均方誤差法來評價模型的好壞程度,並畫圖進行比較。

#選擇基於梯度下降的線性迴歸模型
from sklearn.linear_model import LinearRegression
LR_reg=LinearRegression()
#進行擬合
LR_reg.fit(scaler_housing,target)


#使用均方誤差用於評價模型好壞
from sklearn.metrics import mean_squared_error
preds=LR_reg.predict(scaler_housing)   #輸入數據進行預測得到結果
mse=mean_squared_error(preds,target)   #使用均方誤差來評價模型好壞,可以輸出mse進行查看評價值

#繪圖進行比較
plot.figure(figsize=(10,7))       #畫布大小
num=100
x=np.arange(1,num+1)              #取100個點進行比較
plot.plot(x,target[:num],label='target')      #目標取值
plot.plot(x,preds[:num],label='preds')        #預測取值
plot.legend(loc='upper right')  #線條顯示位置
plot.show()

最後輸出的圖是這樣的:  從這張結果對比圖中就可以看出模型是否得到精確的目標函數,是否能夠精確預測房價。

  • 如果想要預測test文件裏的數據,那就把test文件裏的數據進行讀取,並且進行特徵縮放,調用: LR_reg.predict(test) 就可以得到預測結果,並進行輸出操作。
  • 到這裏可以看到機器學習也不是不能夠學會,只要深入研究和總結,就能夠找到學習的方法,重要的是總結,最後就是調用一些機器學習的方法庫就行了,當然這只是入門級的,我覺得入門級的寫到這已經足夠了,很多人都能夠看得懂,代碼量不多。但要理解線性迴歸的概念性東西還是要多看資料。
# 兼容 pythone2,3
from __future__ import print_function

# 導入相關python庫
import os
import numpy as np
import pandas as pd

#設定隨機數種子
np.random.seed(36)

#使用matplotlib庫畫圖
import matplotlib
import seaborn
import matplotlib.pyplot as plot

from sklearn import datasets


#讀取數據
housing = pd.read_csv('kc_train.csv')
target=pd.read_csv('kc_train2.csv')  #銷售價格
t=pd.read_csv('kc_test.csv')         #測試數據

#數據預處理
housing.info()    #查看是否有缺失值

#特徵縮放
from sklearn.preprocessing import MinMaxScaler
minmax_scaler=MinMaxScaler()
minmax_scaler.fit(housing)   #進行內部擬合,內部參數會發生變化
scaler_housing=minmax_scaler.transform(housing)
scaler_housing=pd.DataFrame(scaler_housing,columns=housing.columns)

mm=MinMaxScaler()
mm.fit(t)
scaler_t=mm.transform(t)
scaler_t=pd.DataFrame(scaler_t,columns=t.columns)



#選擇基於梯度下降的線性迴歸模型
from sklearn.linear_model import LinearRegression
LR_reg=LinearRegression()
#進行擬合
LR_reg.fit(scaler_housing,target)


#使用均方誤差用於評價模型好壞
from sklearn.metrics import mean_squared_error
preds=LR_reg.predict(scaler_housing)   #輸入數據進行預測得到結果
mse=mean_squared_error(preds,target)   #使用均方誤差來評價模型好壞,可以輸出mse進行查看評價值

#繪圖進行比較
plot.figure(figsize=(10,7))       #畫布大小
num=100
x=np.arange(1,num+1)              #取100個點進行比較
plot.plot(x,target[:num],label='target')      #目標取值
plot.plot(x,preds[:num],label='preds')        #預測取值
plot.legend(loc='upper right')  #線條顯示位置
plot.show()


#輸出測試數據
result=LR_reg.predict(scaler_t)
df_result=pd.DataFrame(result)
df_result.to_csv("result.csv")

 

參考:https://github.com/mantchs/machine_learning_model

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章