# 线性回归--梯度下降【理论+案例演示】

## 代码演示

### 导入jar包读取数据集

``````import numpy as np
import pandas as pd

# 显示数据详细信息
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)

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)

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-")
``````