【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)

发布时间:2023-11-11 14:00

波士顿房价数据集字段说明

  • crim 房屋所在镇的犯罪率
  • zn 面积大于25000平凡英尺住宅所占比例
  • indus 房屋所在镇非零售区域所占比例
  • chas 房屋是否位于河边 如果在河边,值1
  • nox 一氧化氮的浓度
  • rm 平均房间数量
  • age 1940年前建成房屋所在比例
  • dis 房屋距离波士顿五大就业中心的加权距离
  • rad 距离房屋最近的公路
  • tax 财产税收额度
  • ptratio 房屋所在镇师生比例
  • black 计算公式:1000*(房屋所在镇非美籍人口所在比例 - 0.63)**2
  • lsta 弱势群体人口所占比例
  • medv 房屋平均价格

本文基于波士顿房价数据集实现
数据集:数据集网盘下载
提取码:p2v9

导入相关库

import numpy as np
import pandas as pd

导入波士顿房价数据集

data = pd.read_csv(r\"dataset/boston.csv\")
print(type(data))
data.head()

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第1张图片\"

线性回归–梯度下降实现

class linearRegression:
    \"\"\"python语言实现线性回归算法。(梯度下降实现)\"\"\"
    
    def __init__(self,alpha,times):
        \"\"\"初始化方法
        
        Parameters:
        ----------------------
        alpha:float
               学习率,用来控制步长。(权重调整的幅度)
        times: int
                循环迭代的次数。  
                
        \"\"\"
        self.alpha = alpha
        self.times = times
        
    def fit(self,X,y):
        \"\"\"根据提供的训练数据,对模型进行训练
        
        Parameters:
        -----------------
        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 = w0 + w1*x1 + w2*x2 ...
            y_hat = np.dot(X,self.w_[1:]) + self.w_[0]
            # 计算真实值与预测值之间的差距。
            error = y - y_hat
            # 计算损失值 损失值计算:(预测值 - 真实值)的平方和除以2
            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 * 1)
            self.w_[1:] += self.alpha * np.dot(X.T,error) 
    
    def predict(self,X):
        \"\"\"根据参数传递的样本,对样本数据进行预测
        
        Parameters:
        -----------------
        X:类数组类型。形状:[样本数量,特征数量]
           待测试样本。
        
        Return:
        -----------------
        result:数组类型
               预测的结果。
        \"\"\"
        
        X = np.asarray(X)
        result = np.dot(X,self.w_[1:]) + self.w_[0]
        return result

创建训练集和测试集&查看训练结果

lr = linearRegression(alpha=0.0005,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)
display(np.mean((result - test_y)** 2))
display(lr.w_)
display(lr.loss_)

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第2张图片\"
通过模型参数,我们发现无论模型的权重特别的大,并且损失值随着迭代次数的增加不但没有下降,反而在增加。这很不科学,究竟是为何?
重点来了:观察原始数据集,
\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第3张图片\"
发现这些不同特征的取值不是一个“数量级“。因此需要进行特征列的标准化,即每个特征列都要调整为标准正态分布. Xi~N(0,1)。

标准化

class StandardScaler:
    \"\"\"该类对数据进行标准化处理。每一列变为标准正态分布 X~N(0,1.ipynb_checkpoints\\)\"\"\"
    def fit(self,X):
        \"\"\"根据传递的样本,计算每个特征列的均值与标准差
       
       Parameters:
        X: 类数组类型
           训练数据,用来计算均值与标准差
        \"\"\"
        
        X = np.asarray(X)
        # axis=0 按列
        self.std_ = np.std(X,axis=0)
        self.mean_ = np.mean(X,axis=0)
    
    def transform(self,X):
        \"\"\"对给定的数据X进行标准化处理,将X的每一列都变成标准正态分布的数据。
        
        Parameters:
        X: 类数组类型
           待转换数据。
           
        Return:
        result: 类数组类型
               参数X转换成标准正态分布后的结果。
        \"\"\"
        
        return (X - self.mean_)/self.std_
    
    def fit_transform(self,X):
        \"\"\"对数据进行训练,并转换,返回转换之后的结果
        
        Parameters:
        X: 类数组类型
           待转换数据。
           
        Return:
        result: 类数组类型
               参数X转换成标准正态分布后的结果。
        
        \"\"\"
        self.fit(X)
        return self.transform(X)

标准化后再次训练&预测

# 为了避免每个特征数量级的不同,从而在梯度下降过程中带来的影响。
# 我们现在考虑进行标准化处理。
lr = linearRegression(alpha=0.0005,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)
test_X = s.fit_transform(test_X)

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

# 训练 预测
lr.fit(train_X, train_y)
result = lr.predict(test_X)
display(np.mean((result - test_y)**2))
display(lr.w_)
display(lr.loss_)

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第4张图片\"
发现这一次无论是权重还是损失值处于我们预期的结果了。

可视化

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.values, \"go-\", label=\"真实值\") # pandas读取时serise类型,我们需要转为ndarray
plt.title(\"线性回归预测-梯度下降\")
plt.xlabel(\"样本序号\")
plt.ylabel(\"预测房价\")
plt.legend()
plt.show()

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第5张图片\"

# 绘制累计误差
plt.plot(range(1,lr.times+1),lr.loss_,\"o-\",label=\"累计误差\")
plt.xlabel(\"迭代次数\")
plt.ylabel(\"累计误差\")
plt.legend()
plt.show()

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第6张图片\"

# 因为房价分析涉及多个维度,不方便进行可视化,为了实现可视化,
# 我们只选取其中一个维度(rm),并画出直线,实现拟合。
lr = linearRegression(alpha=0.0005,times=50)
t = data.sample(len(data),random_state=0)
train_X = t.iloc[:400,5:6] # 返回二维dataframe类型 [:400,5]将是一维series
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 = s2.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_)
# 构建方程 y = -3.03757020e-16 + 6.54984608e-01*x
x = np.arange(-5,5,0.1)
y = -3.03757020e-16 + 6.54984608e-01*x
plt.plot(x,y,\"r\", label=\"通过模型系数\")
# 也可以这样做 直接将x套入模型,需要将x变成二维结构
plt.plot(x,lr.predict(x.reshape(-1,1)),\"g\" ,label=\"导入模型\")
plt.legend()
plt.show()
# 两个直线重合

\"【python机器学习】线性回归--梯度下降实现(基于波士顿房价数据集)_第7张图片\"

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号