机器学习系列(四) -- 梯度下降实现线性回归(波士顿数据集)

博客主要介绍了使用梯度下降实现线性回归,包含读取数据集、定义线性回归类、进行标准化处理以及可视化等步骤,涉及Python、机器学习和数据分析相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

梯度下降实现现行回归.

读取数据集:

import numpy as np
import pandas as pd

data = pd.read_csv('data.csv')
print(data.head())

线性回归类

class LinearRegression:
    # 使用梯度下降方法实现线性回归

    def __init__(self,alpha,times):
        #  初始化方法
        # 参数: alpha : float 学习率 用来控制步长。(权重调整幅度)
        # times :int 循环迭代的次数
        self.alpha = alpha
        self.times = times


    def fit(self,X,y):
        # 根据训练的参数数据 对模型进行训练
        # 参数: X : 类数组类型 形状:[样本特征,特征数量] 待训练的样本特征属性
        # y : 类数组类型 形状:[样本数量] 目标值(标签信息)

        X = np.asarray(X)
        y = np.asarray(y)

        # 创建权重的向量 初始值为0(或者其他的值) 长度比特征数量多1(截距)
        self.w_ = np.zeros(1+X.shape[1])
        # 创建损失 列表 用来保存每次迭代的损失值 损失值计算 (预测值-真实值)的平方和除以2
        self.loss_ = []

        # 进行循环多次迭代 在每次迭代的过程中 不断调整权值 使得损失值不断减小
        for i in range(self.times):
            y_hat = np.dot(X,self.w_[1:]) + self.w_[0]
            # 计算预测值和真实值之间的差距
            error = y - y_hat
            # 降损失值加入加入到损失列当中
            self.loss_.append(np.sum(error**2)/2)
            # 根据差距调整权值w_ 根据公式: 调整为 权重(j)= 权重(j)+ 学习率*sum(y - y_hat)* x(j)
            self.w_[0] += self.alpha * np.sum(error)
            self.w_[1] += self.alpha * np.dot(X.T,error)

    def predict(self,X):
        # 参数: X : 类数组类型 形状:[样本特征,特征数量] 待测试的样本特征属性
        # return result : 数组类型 预测结果
        X= np.asarray(X)
        result = np.dot(X,self.w_[1:]) + self.w_[0]
        return result

标准化处理

lr = LinearRegression(alpha=0.001,times=20)
t = data.sample(len(data),random_state=0)

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)
print(result)
# display(np.mean((result-test_y)**2))

class StandardScaler:
    # 该类对数据进行标准化处理


    def fit(self,X):
        # 根据传递的样本  计算每个特征的均值与标准差
        # 参数 X ;类数组类型  训练数据 用来计算均值与标准差
        X = np.asarray(X)
        self.std_ = np.std(X,axis=0)
        self.mean = np.mean(X,axis=0)

    def transform(self,X):
        # 对给定的数据X 进行标准化处理
        #  参数: X: 类数组类型 待转换的数据
        # result : 类数组类型 参数X转换成正态分布后的结果
        return (X-self.mean)/self.std_

    def fit_transform(self,X):
        # 对数据进行训练并转换  返回转换之后的结果
        # 参数 :X  : 类数组类型  待转换的的数据
        # result: 类数组类型 参数X转换成标准正态分布后的结果
        self.fit()
        return self.transform(X)
        # 为了避免每个特征数量级的不同  从而在梯度下降的过程中带来影响
# 我们在考虑对每个特征进行标准化处理
lr = LinearRegression(alpha=0.005,times=20)
t = data.sample(len(data),random_state=0)

train_X = t.iloc[:400,:-1]
train_y = t.iloc[:400,-1]
test_X = t.iloc[400:,:-1]
test_y = t.iloc[400:,-1]


# 对数据进行标准化处理
s = StandardScaler()
train_X =  s.fit_transform(train_X)
print(train_X )
test_X = s.transform(test_X)

s2 = StandardScaler()
train_y =  s2.fit_transform(train_y)
test_y = s.transform(test_y)
result = lr.predict(test_X)
# display(np.mean(result-test_y)**2)
# display(lr.w_)
# display(lr.loss_)


可视化

#  可视化
import matplotlib as mpl
import matplotlib.pyplot as plt


# 设置中文显示
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.vaules,'go',label='真实值')
plt.title("线性回归预测-梯度下降")
plt.xlabel("样本序号")
plt.ylabel('房价')
plt.legend()
plt.show()

# 绘制累计误差值
plt.plot(range(1, lr.times+1),lr.loss_,'o-')

# 因为房价分析设计多个维度 不方便进行可视化展示
# 为了实现可视化 我们只选取其中一个维度 并画出直线 实现拟合
lr = LinearRegression(alpha=0.005,times=20)
t = data.sample(len(data),random_state=0)
train_X = t.iloc[:400,5:6]
train_y = t.iloc[:400,-1]
test_X = t.iloc[:400,5:6]
test_y = t.iloc[:400,-1]

# 对数据进行标准化处理
s = StandardScaler()
train_X =  s.fit_transform(train_X)
test_X = s.transform(test_X)

s2 = StandardScaler()
train_y =  s2.fit_transform(train_y)
test_y = s.transform(test_y)

lr.fit(train_X,train_y)
result = lr.predict(test_X)
display(np.mean(result-test_y)**2)

plt.scatter(train_X['RM'],train_y)
# 查看方程系数
display(lr.w_).
# 构建方程
x  = np.arange(-5,5,0.1)
y = -3.03757020e-16+6.54984608e-01*x
plt.plot(x, y,'r')
# 也可以这样做
plt.plot(x,lr.predict(x,'r'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gm0012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值