线性回归(regression)
簡介
回歸分析只涉及到兩個變量的,稱一元回歸分析。一元回歸的主要任務是從兩個相關變量中的一個變量去估計另一個變量,被估計的變量,稱因變量,可設為Y;估計出的變量,稱自變量,設為X。
回歸分析就是要找出一個數(shù)學模型Y=f(X),使得從X估計Y可以用一個函數(shù)式去計算。
當Y=f(X)的形式是一個直線方程時,稱為一元線性回歸。這個方程一般可表示為Y=A+BX。根據(jù)最小平方法或其他方法,可以從樣本數(shù)據(jù)確定常數(shù)項A與回歸系數(shù)B的值。
線性回歸方程
Target:嘗試預測的變量,即目標變量
Input:輸入
Slope:斜率
Intercept:截距
舉例,有一個公司,每月的廣告費用和銷售額,如下表所示:
如果把廣告費和銷售額畫在二維坐標內(nèi),就能夠得到一個散點圖,如果想探索廣告費和銷售額的關系,就可以利用一元線性回歸做出一條擬合直線:
有了這條擬合線,就可以根據(jù)這條線大致的估算出投入任意廣告費獲得的銷售額是多少。
評價回歸線擬合程度的好壞
我們畫出的擬合直線只是一個近似,因為肯定很多的點都沒有落在直線上,那么我們的直線擬合的程度如何,換句話說,是否能準確的代表離散的點?在統(tǒng)計學中有一個術語叫做R^2(coefficient ofdetermination,中文叫判定系數(shù)、擬合優(yōu)度,決定系數(shù)),用來判斷回歸方程的擬合程度。
要計算R^2首先需要了解這些:
總偏差平方和(又稱總平方和,SST,Sum of Squaresfor Total):是每個因變量的實際值(給定點的所有Y)與因變量平均值(給定點的所有Y的平均)的差的平方和,即,反映了因變量取值的總體波動情況。如下:
回歸平方和(SSR,Sum of Squares forRegression):因變量的回歸值(直線上的Y值)與其均值(給定點的Y值平均)的差的平方和,即,它是由于自變量x的變化引起的y的變化,反映了y的總偏差中由于x與y之間的線性關系引起的y的變化部分,是可以由回歸直線來解釋的。
殘差平方和(又稱誤差平方和,SSE,Sum of Squaresfor Error):因變量的各實際觀測值(給定點的Y值)與回歸值(回歸直線上的Y值)的差的平方和,它是除了x對y的線性影響之外的其他因素對y變化的作用,是不能由回歸直線來解釋的。
SST(總偏差)=SSR(回歸線可以解釋的偏差)+SSE(回歸線不能解釋的偏差)
所畫回歸直線的擬合程度的好壞,其實就是看看這條直線(及X和Y的這個線性關系)能夠多大程度上反映(或者說解釋)Y值的變化,定義
R^2=SSR/SST 或 R^2=1-SSE/SST
R^2的取值在0,1之間,越接近1說明擬合程度越好
代碼實現(xiàn)
環(huán)境:MacOS mojave 10.14.3
Python 3.7.0
使用庫:scikit-learn 0.19.2
sklearn.linear_model.LinearRegression官方庫:https://scikit-learn.org/stable/modules/linear_model.html
>>> from sklearn import linear_model
>>> reg = linear_model.LinearRegression()
>>> reg.fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])#以(x,y)形式訓練
...
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
normalize=False)
>>> reg.coef_
array([0.5, 0.5]) #第一個是斜率,第二個是截距
舉例,以年齡與資產(chǎn)凈值為例
圖中藍點是訓練數(shù)據(jù),用于計算得出擬合曲線;紅點是測試數(shù)據(jù),用于計算擬合曲線的擬合程度
均屬于樣本,僅僅是隨機分離出來。
Main.py 主程序以及畫圖
import numpy
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
from studentRegression import studentReg
from class_vis import prettyPicture
from ages_net_worths import ageNetWorthData
ages_train, ages_test, net_worths_train, net_worths_test = ageNetWorthData()
reg = studentReg(ages_train, net_worths_train)
plt.clf()
plt.scatter(ages_train, net_worths_train, color="b", label="train data")
plt.scatter(ages_test, net_worths_test, color="r", label="test data")
plt.plot(ages_test, reg.predict(ages_test), color="black")
plt.legend(loc=2)
plt.xlabel("ages")
plt.ylabel("net worths")
print ("katie's net worth prediction: ", reg.predict(27)) #預測結(jié)果
print ("r-squared score:",reg.score(ages_test,net_worths_test))
print ("slope:", reg.coef_) #獲取斜率
print ("intercept:" ,reg.intercept_) #獲取截距
plt.savefig("test.png")
print ("
######## stats on test dataset ########
")
print ("r-squared score: ",reg.score(ages_test,net_worths_test)) #通過使用測試集,可以察覺到過擬合等情況
print ("
######## stats on training dataset ########
")
print ("r-squared score: ",reg.score(ages_train,net_worths_train))
plt.scatter(ages_train,net_worths_train)
plt.plot(ages_train,reg.predict(ages_train),color='blue',linewidth=3)
plt.xlabel('ages_train')
plt.ylabel('net_worths_train')
plt.show()
class_vis.py 繪圖與保存圖像
import numpy as np
import matplotlib.pyplot as plt
import pylab as pl
def prettyPicture(clf, X_test, y_test):
x_min = 0.0; x_max = 1.0
y_min = 0.0; y_max = 1.0
# Plot the decision boundary. For that, we will assign a color to each
# point in the mesh [x_min, m_max]x[y_min, y_max].
h = .01 # step size in the mesh
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.pcolormesh(xx, yy, Z, cmap=pl.cm.seismic)
# Plot also the test points
grade_sig = [X_test[ii][0] for ii in range(0, len(X_test)) if y_test[ii]==0]
bumpy_sig = [X_test[ii][1] for ii in range(0, len(X_test)) if y_test[ii]==0]
grade_bkg = [X_test[ii][0] for ii in range(0, len(X_test)) if y_test[ii]==1]
bumpy_bkg = [X_test[ii][1] for ii in range(0, len(X_test)) if y_test[ii]==1]
plt.scatter(grade_sig, bumpy_sig, color = "b", )
plt.scatter(grade_bkg, bumpy_bkg, color = "r",)
plt.legend()
plt.xlabel("bumpiness")
plt.ylabel("grade")
plt.savefig("test.png")
ages_net_worths.py 樣本點數(shù)據(jù)
import numpy
import random
def ageNetWorthData():
random.seed(42)
numpy.random.seed(42)
ages = []
for ii in range(100):
ages.append( random.randint(20,65) )
net_worths = [ii * 6.25 + numpy.random.normal(scale=40.) for ii in ages]
### need massage list into a 2d numpy array to get it to work in LinearRegression
ages = numpy.reshape( numpy.array(ages), (len(ages), 1))
net_worths = numpy.reshape( numpy.array(net_worths), (len(net_worths), 1))
from sklearn.cross_validation import train_test_split
ages_train, ages_test, net_worths_train, net_worths_test = train_test_split(ages, net_worths)
return ages_train, ages_test, net_worths_train, net_worths_test
studentRegression.py 線性回歸
def studentReg(ages_train, net_worths_train):
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit(ages_train, net_worths_train)
return reg
得到結(jié)果:
同時得到:
R^2: 0.7889037259170789
slope: [[6.30945055]]
intercept: [-7.44716216]
擬合程度約為0.79,還算可以
總結(jié)
以上是生活随笔為你收集整理的线性回归(regression)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「重点」平底锅需要开锅吗
- 下一篇: 如何用路由器桥接手机热点如何通过手机热点