線性回歸
線性回歸是最基礎的機器學習算法,它是用一條直線去擬合數據,適用於線性數據。
線性回歸包括一元線性回歸和多元線性回歸,一元的是只有一個x和一個y。多元的是指有多個x和一個y。
(一元)
(多元)
我們希望這些點盡量離這條直線近一點。即去找每個點和直線的距離 最小的那條線,為了簡單起見,將絕對值轉化為平方,那么誤差可以表示為
,這里i表示第i個數據,N表示總的樣本個數。一般我們還會把Loss求和平均,來當作最終的損失,
即
下面是利用廣告數據進行線性回歸模型的應用:
如果市場的運營部門給了你一份數據,數據包含了不同廣告渠道的成本及對應的產品銷售量。現在的問題是:
- 哪些渠道的廣告真正影響了銷售量?
- 根據已知的渠道預算,如何實現銷售量的預測?
- 模型預測的好壞,該如何評估?
利用Python建模
哪些渠道的廣告真正影響了銷售量?對於這個問題的回答,其實就是在構建多元線性回歸模型后,需要對偏回歸系數進行顯著性檢驗,把那些顯著的變量保留下來,即可以認為這些變量對銷售量是存在影響的。關於線性回歸模型的落地,我們這里推薦使用statsmodels模塊,因為該模塊相比於sklearn,可以得到更多關於模型的詳細信息
廣告數據下載地址:https://pan.baidu.com/s/1qYNsP0w 密碼: 2g3f
數據導入和描述統計:
import os import codecs import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.formula.api as smf from sklearn.cross_validation import train_test_split from sklearn.metrics import mean_squared_error os.getcwd() os.chdir("C:/Users/admin/Desktop/ml-100k") f=codecs.open('Advertising.csv', 'r') #print (f.read()) #header = ['tv', 'radio', 'newspaper','sales'] sales=pd.read_csv('Advertising.csv',sep=',') print(sales) sales.describe()
通過數據的描述性統計分析,我們可以得到這些數值變量的基本統計值,如均值、最小值、最大值、下四分位、上四分位、標准差,而這些統計值有助於你對數據的理解和分布的解讀。接下來需要根據讀取進來的數據構造回歸模型,但建模之前,我們一般需要將數據集拆分成訓練集(用於建模)和測試集(用於模型的評估)兩個部分。
Train,Test = train_test_split(sales, train_size = 0.8, random_state= 1234)
# 建模
fit = smf.ols( ‘sales~TV+radio+newspaper’, data = Train).fit()
#模型信息反饋
fit2.summary()
# 第一個模型的預測結果
pred = fit.predict(exog = Test)
通過模型反饋的結果我們可知,模型是通過顯著性檢驗的,即F統計量所對應的P值是遠遠小於0.05這個閾值的,說明需要拒絕原假設(即認為模型的所有回歸系數都不全為0)。
去掉newspaper,重新建模
fit2 = smf.ols( ‘sales~TV+radio’, data = Train.drop( ‘newspaper’, axis = 1)).fit()
# 模型信息反饋
fit2.summary()
附代碼
#構造訓練集和測試集 Train,Test = train_test_split(sales, train_size = 0.8, random_state= 1234) #建模 fit = smf.ols('sales~TV+radio+newspaper', data = Train).fit() #重新建模 fit2=smf.ols('sales~TV+radio',data=Train.drop(columns='newspaper',axis=1)).fit() #模型信息反饋 fit2.summary()
通過第二次建模(模型中剔除了newspaper這個變量),結果非常明朗,一方面模型通過了顯著性檢驗,另一方面,所有的變量也通過了顯著性檢驗。那問題來了,難道你剔除了newspaper這個變量后,模型效果確實變好了嗎?驗證一個模型好不好,只需要將預測值和真實值做一個對比即可,如果模型越優秀,那預測出來的結果應該會更接近與現實數據。接下來,我們就基於fit和fit2這兩個模型,分別在Test數據集上做預測:
# 第一個模型的預測結果 pred = fit.predict(exog = Test) # 第二個模型的預測結果 pred2 = fit2.predict(exog = Test.drop(columns='newspaper', axis = 1)) #模型效果對比 RMSE = np.sqrt(mean_squared_error(Test.sales, pred)) RMSE2 = np.sqrt(mean_squared_error(Test.sales, pred2)) print( '第一個模型的預測效果:RMES=%.4f\n'%RMSE) print( '第二個模型的預測效果:RMES=%.4f\n'%RMSE2)
對於連續變量預測效果的好壞,我們可以借助於RMSE(均方根誤差,即真實值與預測值的均方根)來衡量,如果這個值越小,就說明模型越優秀,即預測出來的值會越接近於真實值。很明顯,模型2的RMSE相比於模型1會小一些,模型會更符合實際。最后,我們再利用可視化的方法來刻畫真實的觀測點與擬合線之間的關系:
# 真實值與預測值的關系# 設置繪圖風格 plt.style.use( 'ggplot') # 設置中文編碼和負號的正常顯示 plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' # 散點圖 plt.scatter(Test.sales, pred, label = '觀測點') # 回歸線 plt.plot([Test.sales.min(),Test.sales.max()],[pred.min(),pred.max()],'r-',lw= 2,label = '擬合線') # 添加軸標簽和標題 plt.title('真實值VS.預測值') plt.xlabel('真實值') plt.ylabel('預測值') #去除圖邊框的頂部刻度和右邊刻度 plt.tick_params(top = 'off', right = 'off') # 添加圖例 plt.legend(loc = 'upper left') # 圖形展現 plt.show()
從上面的關系圖來看,模型確實擬合的還是蠻不錯的,這些真實點基本上都在擬合線附近,並沒有產生太大的差異。
原文地址:http://www.ppvke.com/Blog/archives/53081