线性回归梯度下降理论概述
在之前KNN算法中我们涉及到了权重的问题,在线性回归梯度下降的算法中,就是通过先规定0的权重,带入式子中,计算出损失值,通过公式计算出新的权重,如此反复迭代,找出最适合的步长,得出最接近真实值得权重,从而进行预测。
数据准备
链接:练习数据
提取码:lyq6
代码演示
导入jar包读取数据集
import numpy as np
import pandas as pd
data = pd.read_csv("boston.csv")
# 显示数据详细信息
data.info()
定义线性回归梯度下降算法类
class LinearRegression:
"""使用梯度下降 实现线性回归算法"""
def __init__(self,alpha,times):
"""
alpha 调控步长
times 迭代计算的次数
"""
self.alpha = alpha
self.times = times
def fit(self,X,y):
X = np.asarray(X)
y = np.asarray(y)
# x.shape (100,3) 100行,3列
# 设置初始化权重为0,w_ 行数为 X数组的列数 +1
self.w_ = np.zeros(X.shape[1]+1)
#定义损失列表
self.loss_ = []
# 循环迭代 times次, 计算出最终的w_ 的值
for i in range(self.times):
# dot 点乘
# 将w_ 带入公式 y = w1*x1 + w2*x2 +... + wn*xn + w0
y_hat = np.dot(X,self.w_[1:]) + self.w_[0]
# 计算每一个预测值与真实值之间的误差
error = y - y_hat
# 计算损失值 损失函数为 sum((y - y_hat)**2)/2
self.loss_.append(np.sum(error**2) / 2)
self.w_[0] += self.alpha * np.sum(error)
self.w_[1:] += self.alpha * np.dot(X.T,error)
def predict(self,X):
X = np.asarray(X)
result = self.w_[0]+np.dot(X,self.w_[1:])
return result
在没有正太分布的情况下,测试算法
lr = LinearRegression(0.0005,20)
# data.head()
t = data.sample(len(data),random_state=0)
len(t)
train_X = t.iloc[:400,:-1]
train_y = t.iloc[:400,-1]
test_X = t.iloc[400:,:-1]
test_y = t.iloc[400:,-1]
lr.fit(train_X,train_y)
result = lr.predict(test_X)
np.mean((result - test_y)**2)
display(lr.w_)
display(lr.loss_)
- 会发现差距有点大
用正太分布降低列欲列之间的数据差距
# 标准正太分布类 给定数据集X 求出X中每一列数据的标准正太分布
class StandardScala:
def fit(self,X):
X = np.asarray(X)
self.mean_ = np.mean(X,axis=0)
# std 均方差
self.std_ = np.std(X,axis=0)
def transform(self,X):
return (X - self.mean_) / self.std_
def fit_transform(self,X):
self.fit(X)
return self.transform(X)
再进行算法预测
lr = LinearRegression(0.0005,20)
# data.head()
t = data.sample(len(data),random_state=0)
len(t)
train_X = t.iloc[:400,:-1]
train_y = t.iloc[:400,-1]
test_X = t.iloc[400:,:-1]
test_y = t.iloc[400:,-1]
ss = StandardScala()
train_X = ss.fit_transform(train_X)
test_X = ss.fit_transform(test_X)
ss2 = StandardScala()
train_y = ss2.fit_transform(train_y)
test_y = ss2.fit_transform(test_y)
lr.fit(train_X,train_y)
result = lr.predict(test_X)
np.mean((result - test_y)**2)
display(lr.w_)
display(lr.loss_)
预测与真实数据的差距以图的形式可视化
import matplotlib as mpl
import matplotlib.pyplot as plt
# matplotlib 不支持中文,需要配置一下,设置一个中文字体
mpl.rcParams["font.family"] = "SimHei"
# 能够显示 中文 ,正常显示 "-"
mpl.rcParams["axes.unicode_minus"] = False
plt.figure(figsize=(10,10))
plt.plot(result,"ro-",label="预测值")
plt.plot(test_y.values,"bo--",label="真实值")
plt.xlabel("样本序号")
plt.ylabel("房价")
plt.title("线性回归 梯度下降")
plt.legend()
plt.show()
展示损失值变化
plt.plot(range(1,lr.times+1),lr.loss_,"bo-")