如何搞懂機器學習模型線性迴歸(程式碼篇)?資料分析小白也能看懂的模型介紹給你
本篇是結合上一篇關於線性迴歸模型原理的程式碼實踐文章,主要都是程式碼,對最小二乘法的矩陣求解方法和梯度下降求解方法、sklearn實現程式碼、波士頓房價預測案例進行了詳細解釋。如果感興趣的朋友可以結合前一篇一起看。
1.最小二乘法
先把資料讀入python中進行簡單處理,在進行視覺化,資料集很簡單,是模擬生成的,只有一列特徵變數x和一列標籤變數y,儲存為txt格式,大家如果需要資料集可以關注同名公V,私戳我獲取。
#匯入numpy、pandas等計算庫和matplotlib視覺化庫
import numpy as np
import pandas as pd
import matplotlib。pyplot as plt
%matplotlib inline
#讀取檔案資料,資料是以txt格式儲存,分隔符是tab鍵,原資料中沒有列名所以需要新增列名
data=pd。read_table(r“D:\data_line。txt”,sep=‘ ’,names=[‘x1’,‘y’])
data[‘x0’]=1 #新增的x0=1實際是為了便於偏置b好計算
#劃分特徵(feature)和標籤(label),這裡的特徵就是原理篇裡說的自變數x和因變數y
feature=data[[‘x0’,‘x1’]] #對DataFrame進行切片會得到新的DataFrame
label= data[‘y’]
#畫原始資料散點圖看資料的分佈
plt。figure(figsize=(8,4),dpi=80) #設定畫布的大小
plt。scatter(data[‘x1’],label,color=‘black’)#在畫布上畫出原始資料散點圖
plt。title(“original_data”) #設定散點圖名字
plt。show()
現在我們想要對上面這些點找出一個函式關係,即線性迴歸模型來預測新的資料,我們想得到下面這個方程:
把它寫成矩陣的形式就是:
我們採用最小二乘法來求解引數矩陣θ:
經過求導化簡得到:
2.矩陣求解係數
瞭解了資料分佈情況,下面就是透過矩陣求導的方式計算引數矩陣θ,依據的公式就是上面的:
#矩陣求解係數
#用numpy包把資料特徵列轉換成矩陣
feature_matrix=np。mat(data[[‘x0’,‘x1’]])
#用numpy包把資料標籤列轉換成矩陣,並進行轉置
label_matrix=np。mat(data[‘y’])。T
#把求解引數theta的公式用程式碼表示出來
theta = (feature_matrix。T * feature_matrix)。I * feature_matrix。T * label_matrix
# 用得到的引數組成我們要找的線性關係函式;預測值Y等於特徵矩陣(輸入變數、自變數X)乘以引數矩陣
y_predict=feature_matrix * theta
#畫出原資料和擬合曲線
plt。figure(figsize=(8,4),dpi=80)
plt。scatter(data[‘x1’],label,color=‘black’)#原始資料
plt。plot(data[‘x1’],y_predict,color =‘blue’,linewidth=3)#擬合曲線
plt。title(“least_square”) #設定散點圖名字
plt。show()
3。梯度下降法求解
3。1 梯度下降法舉例
#模擬造一批二元一次方程的資料點
x = np。linspace(-5,9) #呼叫生成數列方法生成x
y = x**2-4*x #用x計算y
plt。figure() #設定畫布的大小
plt。plot(x,y) #呼叫plot方法畫曲線圖
plt。grid() #設定顯示網格線
plt。title(‘y=x^2-4x’) #設定曲線圖名字
plt。show()
#梯度下降法求解最小值
#建立計算f(x)的導數的函式
def f_delta(x_old):
return 2 * x_old - 4
#第一步設定x的初始值,給一個小於x_new的值
x_old = 8
#步長,也就是學習速率,控制更新的幅度
alpha = 0。001
#第二步開始迭代,用for迴圈進行控制
#在原理篇中說迭代結束的標誌是誤差小於設定的閾值,但是這裡利用了計算機的窮盡技巧,利用很大的迭代次數來逼近,到了最小值誤差幾乎不會變化
for i in range(10000):
#原理篇中推導的引數迭代公式
x_new = x_old - alpha * f_delta(x_old)
x_old = x_new
print(x_new)
函式最小值時,x_new=2。0000000121217143
3。2 梯度下降法完整實現
這是損失函式:
對於上面的損失函式L(θ)採用求導:
然後得到關於θ的迭代公式:
# y = kx + b,k 是梯度, b 是截距,假設資料只有一列特徵和一列標籤
#誤差函式,對實際值y和預測的值y‘
def compute_error(b, k, points): #定義函式,函式的引數是b, k和資料點(x,y)
totalError = 0 #先初始化總誤差為0
for i in range(0, len(points)):
x = points[i, 0] #將資料點第一列特徵取出
y = points[i, 1] #將資料點第一二列標籤取出
totalError += (y - (k * x + b)) ** 2 #計算誤差的公式為y-y’,而y‘=(k’ * x + b‘)) ** 2
return totalError
#計算梯度函式x_new = x_old - alpha * x_old * (y - ((kx_old + b))
def step_gradient(b_current, k_current, points, learningRate):
b_gradient = 0
k_gradient = 0
for i in range(0, len(points)): #對資料中所有點都迴圈計算
x = points[i, 0]
y = points[i, 1]
k_gradient += - x * (y - ((k_current * x) + b_current)) #計算k的梯度
b_gradient += - (y - ((k_current * x) + b_current)) #計算b的梯度
new_b = b_current - (learningRate * b_gradient) #更新k的梯度
new_k = k_current - (learningRate * k_gradient) #更新b的梯度
return [new_b, new_k]
#第一步設定b、k的初始值,設定學習率a,迭代次數num_iterations
def gradient_descent(points, starting_b, starting_k, learning_rate, num_iterations):
b = starting_b
k = starting_k
error=[]
for i in range(num_iterations): #用迭代次數控制結束
#用上面的梯度函式計算梯度
b, k = step_gradient(b, k, np。array(points), learning_rate)
#用上面的誤差函式計算誤差
error。append(compute_error(b, k, points))
return [b, k,error]
#第一幅圖畫原始資料圖
points = np。array(pd。read_table(“data。csv”, delimiter=“,”,names=[’x1‘,’y‘]))#將資料提取提出來,numpy裡面的
plt。figure(figsize=(8,4),dpi=80)
plt。scatter(points[:,0],points[:,1],color=’black‘)
plt。title(“original_data”)
#梯度下降法迭代
learning_rate = 0。000001 #學習率
initial_b = 0 # initial y-intercept guess
initial_k = 0 # initial slope guess
num_iterations = 10000
[b, k, error] = gradient_descent(points, initial_b, initial_k, learning_rate, num_iterations)
new_points1=range(len(points[:,0]))*k+b
#第二幅圖畫出梯度下降法擬合的曲線
plt。figure(figsize=(8,4),dpi=80)
plt。scatter(points[:,0],points[:,1],color=’black‘)
plt。plot(range(len(points[:,0])),new_points1,color=’blue‘)
plt。title(“GradientDescent”)
#第三幅圖畫出迭代次數與誤差的關係圖
plt。figure(figsize=(8,4),dpi=80)
plt。plot(range(num_iterations)[0:100],np。array(error)[0:100],color=’red‘)
plt。xlabel(“iteration number”) #新增x軸的名稱
plt。ylabel(“error”) #新增y軸的名稱
4。Sk-learn中的線性迴歸
#標準線性迴歸
#從sklearn包中呼叫linear_model方法
from sklearn import linear_model
#例項化一個線性迴歸模型物件
reg = linear_model。LinearRegression()
#將資料點帶入進行擬合訓練
reg。fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])#訓練,擬合
#將新的樣本點帶入預測
reg。predict([[4,4],[3,4]])#預測
# 得到預測結果
array([4。 , 3。5])
reg。coef_ #顯示線性迴歸函式的係數
#得到函式的係數
array([0。5, 0。5])
reg。intercept_ #顯示線性迴歸函式的截距
#得到函式的截距
1。1102230246251565e-16
# 最後組合得到擬合數據點的函式關係
y = 0。5 * x_0 + 0。5 * x_1 + 1。11
5。波士頓房價預測實戰
from sklearn。linear_model import LinearRegression #線性迴歸庫
from sklearn。preprocessing import StandardScaler #對變數標準化的庫
from sklearn。datasets import load_boston #載入內建資料集練習
from sklearn。model_selection import train_test_split #對資料集進行劃分
from sklearn。metrics import mean_squared_error,classification_report #對最後得到的模型進行評估的庫
import matplotlib。pyplot as plt
# 1。載入資料集
ld = load_boston()
# 2。劃分資料集,訓練集的比例是75%,測試集的比例是25%
x_train,x_test,y_train,y_test = train_test_split(ld。data,ld。target,test_size=0。25)
# 3。標準化處理
# 特徵變數標準化處理
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。reshape(-1,1))
y_test = std_y。transform(y_test。reshape(-1,1))
# 4。構建模型
# LinearRegression
lr = LinearRegression()
lr。fit(x_train,y_train)
# 5。預測新值
y_lr_predict = lr。predict(x_test)
y_lr_predict = std_y。inverse_transform(y_lr_predict)
# 6。用均方根誤差公式來評估模型預測新的值和新的實際值之間的誤差
print(“線性迴歸模型均方誤差為:”,mean_squared_error(std_y。inverse_transform(y_test),y_lr_predict))
# 7。把資料點和擬合直線都畫出來,視覺化展示
plt。figure(figsize=(8,4),dpi=80)
plt。title(“LinearRegressor”)
plt。plot(y_lr_predict, std_y。inverse_transform(y_test), ’rx‘) # y = ωX
plt。plot([y_lr_predict。min(), y_lr_predict。max()], [y_lr_predict。min(), y_lr_predict。max()], ’b-。‘, lw=4) # f(x)=x
plt。ylabel(“Predieted Price”)
plt。xlabel(“Real Price”)
plt。show()
線性迴歸模型均方誤差為:24。253400767313174
好了,今天的文字不多,主要是程式碼解釋,這些程式碼配合資料集是可以直接執行的。應該還是比較清楚明白的,如果需要交流請私戳我。
最後歡迎大家關注我,我是拾陸,關注同名"二八Data",更多幹貨持續為你奉獻。