一、線性回歸的概念1.1、定義
線性回歸通過一個或者多個自變量與因變量之間之間進行建模的回歸分析。其中特點為一個或多個稱為回歸系數的模型參數的線性組合。
優點:結果易于理解,計算不複雜。
缺點:對非線性的數據拟合不好。
适用數據類型:數值型和标稱型。
1.2、分類一元線性回歸:涉及到的變量隻有一個。
多元線性回歸:涉及到的變量兩個或兩個以上。
1.3、公式
image.png
其中,為矩陣:
,為矩陣
二、線性回歸的實例2.1、單變量實例房子價格與房子面積
單變量實例
2.2、多變量實例期末成績:0.7×考試成績 0.3×平時成績西瓜好壞:0.2×色澤 0.5×根蒂 0.3×敲聲
多變量實例
三、損失函數損失函數是一個貫穿整個機器學習重要的一個概念,大部分機器學習算法都會有誤差,我們得通過顯性的公式來描述這個誤差,并且将這個誤差優化到最小值。
3.1、損失原因預測結果與真實值是有一定的誤差。
3.2、損失函數定義
損失函數代表了誤差的大小,用公式表示如下:
又稱最小二乘法。
對于線性回歸模型,将模型與數據點之間的距離差之和做為衡量匹配好壞的标準,誤差越小,匹配程度越大。我們要找的模型就是需要将f(x)和我們的真實值之間最相似的狀态。
損失函數由W決定,那麼如何去求模型當中的W,使得損失最小?(目的是找到最小損失對應的W值)
3.3、減小損失函數的2種方式方式一:最小二乘法之正規方程
求解:
為特征值矩陣,為目标值矩陣。
缺點:當特征過于複雜,求解速度太慢。對于複雜的算法,不能使用正規方程求解(邏輯回歸等)
方式二:最小二乘法之梯度下降
為學習速率,需要手動指定,其中
表示方向理解:沿着這個函數下降的方向找,最後就能找到山谷的最低點,然後更新W值
最小二乘法之梯度下降
3.4、兩種方式對比:四、線性回歸API4.1、普通最小二乘法線性回歸
sklearn.linear_model.LinearRegression()coef_:回歸系數
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
# 方法
reg.fit(X,y,sample_weight = None) #使用X作為訓練數據拟合模型,y作為X的類别值。X,y為數組或者矩陣
reg.predict([[X,y]]) # 預測提供的數據對應的結果
#屬性
reg.coef_ #表示回歸系數w=(w1,w2....)
sklearn.linear_model.SGDRegressor( )coef_:回歸系數
4.3、帶有正則化的線性回歸sklearn.linear_model.Ridge具有l2正則化的線性最小二乘法alpha:正則化力度coef_:回歸系數
五、實現案例波士頓房價數據分析流程:5.1、數據獲取
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, classification_report
from sklearn.externals import joblib
import pandas as pd
import numpy as np
# 獲取數據
lb = load_boston()
# 分割數據集到訓練集和測試集
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
# 特征值和目标值是都必須進行标準化處理, 實例化兩個标準化API
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)
# 目标值
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train)
y_test = std_y.transform(y_test)
# 正規方程求解方式預測結果
lr = LinearRegression()
lr.fit(x_train, y_train)
print(lr.coef_)
保存訓練好的模型
joblib.dump(lr, "test.pkl")
# 預測測試集的房子價格
y_lr_predict = std_y.inverse_transform(lr.predict(x_test))
print("正規方程測試集裡面每個房子的預測價格:", y_lr_predict)
print("正規方程的均方誤差:", mean_squared_error(std_y.inverse_transform(y_test), y_lr_predict))
# 梯度下降進行房價預測
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print(sgd.coef_)
# 預測測試集的房子價格
y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test))
print("梯度下降測試集裡面每個房子的預測價格:", y_sgd_predict)
print("梯度下降的均方誤差:", mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))
# 嶺回歸進行房價預測
rd = Ridge(alpha=1.0)
rd.fit(x_train, y_train)
print(rd.coef_)
# 預測測試集的房子價格
y_rd_predict = std_y.inverse_transform(rd.predict(x_test))
print("梯度下降測試集裡面每個房子的預測價格:", y_rd_predict)
print("梯度下降的均方誤差:", mean_squared_error(std_y.inverse_transform(y_test), y_rd_predict))
注:^為預測值,¯為真實值。
6.2、回歸評估API:
sklearn.metrics.mean_squared_error
mean_squared_error(y_true, y_pred)
均方誤差回歸損失
y_true:真實值
y_pred:預測值
return:浮點數結果
注:真實值,預測值為标準化之前的值。
七、線性回歸的可能問題訓練數據訓練的很好啊,誤差也不大,為什麼在測試集上面有問題呢?機器學習可能存在過拟合和欠拟合的問題。如下圖:
過拟合和欠拟合
過拟合和欠拟合
7.1、過拟合一個假設在訓練數據上能夠獲得比其他假設更好的拟合, 但是在訓練數據外的數據集上卻不能很好地拟合數據,此時認為這個假設出現了過拟合的現象。(模型過于複雜),如下圖:
過拟合
産生原因:原始特征過多,存在一些嘈雜特征, 模型過于複雜是因為模型嘗試去兼顧各個測試數據點。
解決辦法:一個假設在訓練數據上不能獲得更好的拟合, 但是在訓練數據外的數據集上也不能很好地拟合數據,此時認為這個假設出現了欠拟合的現象。(模型過于簡單)。如下圖:
欠拟合
産生原因:學習到數據的特征過少。
解決辦法:增加數據的特征數量。
1、問題引入在統計學中,線性回歸是利用稱為線性回歸方程的最小二乘函數對一個或多個自變量和因變量之間關系進行建模的一種回歸分析。這種函數是一個或多個稱為回歸系數的模型參數的線性組合。一個帶有一個自變量的線性回歸方程代表一條直線。我們需要對線性回歸結果進行統計分析。
例如,假設我們已知一些學生年紀和遊戲時間的數據,可以建立一個回歸方程,輸入一個新的年紀時,預測該學生的遊戲時間。自變量為學生年紀,因變量為遊戲時間。當隻有一個因變量時,我們稱該類問題為簡單線性回歸。當遊戲時間與學生年紀和學生性别有關,因變量有多個時,我們稱該類問題為多元線性回歸。
2、常見的統計量在研究該問題之前,首先了解下編程中用到的常見的統計量:
序号 |
概念 |
公式 |
算法 |
說明 |
1 |
均值 |
|
整體的均值 | |
2 |
中位數 |
排序後取中間值 | ||
3 |
衆數 |
出現次數最多的數 |
出現頻率 | |
4 |
方差 |
|
數據的離散程度 | |
5 |
标準差 |
|
s |
方差的開方 |
研究一個自變量(X)和一個因變量(y)的關系
簡單線性回歸模型定義:
簡單線性回歸方程:
其中:
為回歸線的截距
為回歸線的斜率
通過訓練數據,求取出估計參數建立的直線方程:
實際編程時,主要是根據已知訓練數據,估計出
和
的值
和
以下面實例為例,第一列表示每月投放廣告的次數,第二列表示汽車向量,通過Python編程求取線性回歸方程:
投放廣告數 |
汽車銷量 |
1 |
14 |
3 |
24 |
2 |
18 |
1 |
17 |
3 |
27 |
編程關鍵在于如何求取b0和b1的值,我們引入一個方程(sum of square):
當上述方程的值最小時,我們認為求取到線程回歸方程參數的值,對該方程求最小值可以進一步轉化為求導和求極值的問題,求導過程省略,最後結論如下:
實際代碼:
import numpy as np
from matplotlib import pylab as pl
# 定義訓練數據
x = np.array([1,3,2,1,3])
y = np.array([14,24,18,17,27])
# 回歸方程求取函數
def fit(x,y):
if len(x) != len(y):
return
numerator = 0.0
denominator = 0.0
x_mean = np.mean(x)
y_mean = np.mean(y)
for i in range(len(x)):
numerator = (x[i]-x_mean)*(y[i]-y_mean)
denominator = np.square((x[i]-x_mean))
print('numerator:',numerator,'denominator:',denominator)
b0 = numerator/denominator
b1 = y_mean - b0*x_mean
return b0,b1
# 定義預測函數
def predit(x,b0,b1):
return b0*x b1
# 求取回歸方程
b0,b1 = fit(x,y)
print('Line is:y = %2.0fx %2.0f'%(b0,b1))
# 預測
x_test = np.array([0.5,1.5,2.5,3,4])
y_test = np.zeros((1,len(x_test)))
for i in range(len(x_test)):
y_test[0][i] = predit(x_test[i],b0,b1)
# 繪制圖像
xx = np.linspace(0, 5)
yy = b0*xx b1
pl.plot(xx,yy,'k-')
pl.scatter(x,y,cmap=pl.cm.Paired)
pl.scatter(x_test,y_test[0],cmap=pl.cm.Paired)
pl.show()
執行結果:
C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=51452
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
numerator: 20.0 denominator: 4.0
Line is:y = 5x 10
藍色表示測試數據,橙色表示預測數據。
3、多元線性回歸實例及編程實現多元線性回歸方程和簡單線性回歸方程類似,不同的是由于因變量個數的增加,求取參數的個數也相應增加,推導和求取過程也不一樣。
y=β0+β1x1 β2x2 ... βpxp ε
對于b0、b1、…、bn的推導和求取過程,引用一個第三方庫進行計算。以如下數據為例,對運輸裡程、運輸次數與運輸總時間的關系,建立多元線性回歸模型:
運輸裡程 |
運輸次數 |
運輸總時間 |
100 |
4 |
9.3 |
50 |
3 |
4.8 |
100 |
4 |
8.9 |
100 |
2 |
6.5 |
50 |
2 |
4.2 |
80 |
2 |
6.2 |
75 |
3 |
7.4 |
65 |
4 |
6.0 |
90 |
3 |
7.6 |
90 |
2 |
6.1 |
代碼如下:
import numpy as np
from sklearn import datasets,linear_model
# 定義訓練數據
x = np.array([[100,4,9.3],[50,3,4.8],[100,4,8.9],
[100,2,6.5],[50,2,4.2],[80,2,6.2],
[75,3,7.4],[65,4,6],[90,3,7.6],[90,2,6.1]])
print(x)
X = x[:,:-1]
Y = x[:,-1]
print(X,Y)
# 訓練數據
regr = linear_model.LinearRegression()
regr.fit(X,Y)
print('coefficients(b1,b2...):',regr.coef_)
print('intercept(b0):',regr.intercept_)
# 預測
x_test = np.array([[102,6],[100,4]])
y_test = regr.predict(x_test)
print(y_test)
執行結果:
C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=51529
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
[[100. 4. 9.3]
[ 50. 3. 4.8]
[100. 4. 8.9]
[100. 2. 6.5]
[ 50. 2. 4.2]
[ 80. 2. 6.2]
[ 75. 3. 7.4]
[ 65. 4. 6. ]
[ 90. 3. 7.6]
[ 90. 2. 6.1]]
[[100. 4.]
[ 50. 3.]
[100. 4.]
[100. 2.]
[ 50. 2.]
[ 80. 2.]
[ 75. 3.]
[ 65. 4.]
[ 90. 3.]
[ 90. 2.]] [9.3 4.8 8.9 6.5 4.2 6.2 7.4 6. 7.6 6.1]
coefficients(b1,b2...): [0.0611346 0.92342537]
intercept(b0): -0.868701466781709
[10.90757981 8.93845988]
如果特征向量中存在分類型變量,例如車型,我們需要進行特殊處理:
運輸裡程 |
輸出次數 |
車型 |
隐式轉換 |
運輸總時間 |
100 |
4 |
1 |
010 |
9.3 |
50 |
3 |
0 |
100 |
4.8 |
100 |
4 |
1 |
010 |
8.9 |
100 |
2 |
2 |
001 |
6.5 |
50 |
2 |
2 |
001 |
4.2 |
80 |
2 |
1 |
010 |
6.2 |
75 |
3 |
1 |
010 |
7.4 |
65 |
4 |
0 |
100 |
6.0 |
90 |
3 |
0 |
100 |
7.6 |
100 |
4 |
1 |
010 |
9.3 |
50 |
3 |
0 |
100 |
4.8 |
100 |
4 |
1 |
010 |
8.9 |
100 |
2 |
2 |
001 |
6.5 |
代碼實現:
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn import linear_model
# 定義數據集
x = np.array([[100,4,1,9.3],[50,3,0,4.8],[100,4,1,8.9],
[100,2,2,6.5],[50,2,2,4.2],[80,2,1,6.2],
[75,3,1,7.4],[65,4,0,6],[90,3,0,7.6],
[100,4,1,9.3],[50,3,0,4.8],[100,4,1,8.9],[100,2,2,6.5]])
x_trans = []
for i in range(len(x)):
x_trans.append({'x1':str(x[i][2])})
vec = DictVectorizer()
dummyX = vec.fit_transform(x_trans).toarray()
x = np.concatenate((x[:,:-2],dummyX[:,:],x[:,-1].reshape(len(x),1)),axis=1)
x = x.astype(float)
X = x[:,:-1]
Y = x[:,-1]
print(x,X,Y)
# 訓練數據
regr = linear_model.LinearRegression()
regr.fit(X,Y)
print('coefficients(b1,b2...):',regr.coef_)
print('intercept(b0):',regr.intercept_)
執行結果:
C:\Anaconda3\python.exe "C:\Program Files\JetBrains\PyCharm 2019.1.1\helpers\pydev\pydevconsole.py" --mode=client --port=51576
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\app\\PycharmProjects', 'C:/app/PycharmProjects'])
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.12.0
Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] on win32
runfile('C:/app/PycharmProjects/ArtificialIntelligence/test.py', wdir='C:/app/PycharmProjects/ArtificialIntelligence')
[[100. 4. 0. 1. 0. 9.3]
[ 50. 3. 1. 0. 0. 4.8]
[100. 4. 0. 1. 0. 8.9]
[100. 2. 0. 0. 1. 6.5]
[ 50. 2. 0. 0. 1. 4.2]
[ 80. 2. 0. 1. 0. 6.2]
[ 75. 3. 0. 1. 0. 7.4]
[ 65. 4. 1. 0. 0. 6. ]
[ 90. 3. 1. 0. 0. 7.6]
[100. 4. 0. 1. 0. 9.3]
[ 50. 3. 1. 0. 0. 4.8]
[100. 4. 0. 1. 0. 8.9]
[100. 2. 0. 0. 1. 6.5]] [[100. 4. 0. 1. 0.]
[ 50. 3. 1. 0. 0.]
[100. 4. 0. 1. 0.]
[100. 2. 0. 0. 1.]
[ 50. 2. 0. 0. 1.]
[ 80. 2. 0. 1. 0.]
[ 75. 3. 0. 1. 0.]
[ 65. 4. 1. 0. 0.]
[ 90. 3. 1. 0. 0.]
[100. 4. 0. 1. 0.]
[ 50. 3. 1. 0. 0.]
[100. 4. 0. 1. 0.]
[100. 2. 0. 0. 1.]] [9.3 4.8 8.9 6.5 4.2 6.2 7.4 6. 7.6 9.3 4.8 8.9 6.5]
coefficients(b1,b2...): [ 0.05452507 0.70930079 -0.18019642 0.60821607 -0.42801964]
intercept(b0): 0.1989958956317821
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!