线性回归(Linear Regression)模型的构建和实现

        神经网络的基础概念非常重要,是后期深度学习的基石,对于初学神经网络的伙伴们来说,一般最好是从了解熟知感知机开始 :感知机(与门、与非门、或门、异或门)的实现

        这节说的线性回归属于单层神经网络,将会学到什么是模型,怎么训练模型,怎么预测模型等,比如预测房价,其中影响房价的因素有很多,我们选取面积为x1、房龄为x2、真实售价为y,来预测房价,其中面积和房龄叫做房子(样本)的特征,真实价格叫做标签,我们从感知机可以写出它们的数学表达式

\LARGE y=x_{1}w_{1}+x_{2}w_{2}+b

        其中w1,w2是权重,b是偏差,它们是这个线性回归模型的参数,这样计算(预测)的价格的表达式就是模型
        那为什么说是单层的神经网络呢?因为这个模型的输入层是没有涉及计算,所以层数是1,另外输出层的神经元和输入层的各个神经元完全连接,因此这里的输出层叫做全连接层或者叫做稠密层(Dense Layer)。这些涉及到的术语要很清楚指的是什么,不然后期多了,会有点糊涂。
        模型设计好了,我们就开始进行训练,在本例中训练模型是为了更好的预测房价是吧,那换一种说法就是预测的房价尽可能的接近真实的房价,也就是让它们之间的误差尽可能的小,这样预测其他房子价格的时候,精度就会高,更接近真实的房价。
        那如何来训练?首先我们需要大量的真实数据,通过这些真实数据(训练数据集或叫训练集)去做迭代,训练出泛化能力强的精度高的模型出来,在训练数据集的时候,我们会引用一个损失函数,这个损失函数的作用就是衡量误差的,一般来说,我们取训练集所有样本的误差的平均来衡量模型预测的质量。

        对于怎么找到一组最优(近似最优)的模型参数呢?一般使用的最多最广泛的是随机梯度下降法(SGD),更完整详细的说明可以参看:
Python随机梯度下降法(一)

 Python随机梯度下降法(二)

 Python随机梯度下降法(三)

Python随机梯度下降法(四)【完结篇】

        当学习出最优模型参数之后,就可以使用上面的线性回归模型来预测房价(除开训练集的其他数据集,或叫测试集)

线性回归模型的构建

from mxnet import autograd,nd

#生成一个训练数据集
num_samples=1000 #样本个数
num_features=2   #特征个数
true_w=[5,-7.4]  #真实权重
true_b=8.8       #真实偏差
features=nd.random.normal(scale=1,shape=(num_samples,num_features)) #根据批量样本和特征生成一个标准差为1,均值为0的正态分布的数据集
labels=features[:,0]*true_w[0] + features[:,1]*true_w[1] + true_b #标签
labels+=nd.random.normal(scale=0.01,shape=(labels.shape))#加一个噪声(数据集里的一些干扰信息)

#读取数据集,每次返回batch_size个随机样本的特征和标签
def data_iter(batch_size,features,labels):
    num_samples=len(features)
    indices=list(range(num_samples))
    random.shuffle(indices)
    for i in range(0,num_samples,batch_size):
        j=nd.array(indices[i : min(i+batch_size,num_samples)])
        yield features.take(j),labels.take(j) #take根据索引返回对应元素

batch_size=10
for X,y in data_iter(batch_size,features,labels):
    print(X,y)
    break

#下面开始进行对参数的梯度迭代更新
w=nd.random.normal(scale=0.01,shape=(num_features,1))
b=nd.zeros(shape=(1,))
w.attach_grad()
b.attach_grad()

#定义模型(在d2lzh包已定义)
def linreg(X,w,b):
    return nd.dot(X,w)+b

#平方损失函数(在d2lzh包已定义)
def squared_loss(y_hat,y):
    return (y_hat-y.reshape(y_hat.shape))**2/2

#随机梯度下降法(在d2lzh包已定义)
def sgd(params,lr,batch_size):
    for param in params:  #不直接使用-=,而使用for循环是MXNet不支持in-place
        param[:]=param-lr*param.grad/batch_size
    
lr=0.03 #学习率(超参数)
num_epochs=5 #迭代周期
net=linreg
loss=squared_loss
for epoch in range(num_epochs):
    for X,y in data_iter(batch_size,features,labels):
        with autograd.record():
            l=loss(net(X,w,b),y) #小批量X和y的损失
        l.backward() #小批量损失对模型参数求梯度
        sgd([w,b],lr,batch_size)
    train_l=loss(net(features,w,b),labels)
    print('epoch %d,loss %f' % (epoch+1,train_l.mean().asnumpy()))
print(w,b)

[[ 0.86046714  0.06655062]
 [-1.0263956  -1.4340156 ]
 [-0.7464799  -1.1734369 ]
 [-0.5986544  -1.7862475 ]
 [ 0.5516758   0.2614431 ]
 [ 1.9585181   0.25282365]
 [ 1.1280887   1.2971296 ]
 [-0.5502624   0.6829922 ]
 [ 0.8451316  -1.2080427 ]
 [-0.819514   -1.2183683 ]]
<NDArray 10x2 @cpu(0)> 
[12.610863  14.274499  13.760691  19.042149   9.634927  16.73366
  4.8353267  0.984106  21.94241   13.718784 ]
<NDArray 10 @cpu(0)>
epoch 1,loss 0.196607
epoch 2,loss 0.000572
epoch 3,loss 0.000053
epoch 4,loss 0.000052
epoch 5,loss 0.000051

[[ 4.9999046]
 [-7.4004917]]
<NDArray 2x1 @cpu(0)> 
[8.799186]
<NDArray 1 @cpu(0)>
从结果我们可以看出,训练出来的权重参数和预测的标签值与真实的权重和标签值非常接近

线性回归模型的简洁实现
        实践当中我们一般都使用MXNet提供的Gluon接口来更方便地实现线性回归模型的训练操作。Gluon为我们提供了大量的预定义层,比如里面的nn模块,已经定义了大量的神经网络的层。其中导入模块一般写在最上面,这里为了更好的体现使用了Gluon接口来简洁的实现,所以就写在了需要的代码中间地方

from mxnet import autograd,nd

#生成一个训练数据集
num_samples=1000 #样本个数
num_features=2   #特征个数
true_w=[5,-7.4]  #真实权重
true_b=8.8       #真实偏差
features=nd.random.normal(scale=1,shape=(num_samples,num_features)) #根据批量样本和特征生成一个标准差为1,均值为0的正态分布的数据集
labels=features[:,0]*true_w[0] + features[:,1]*true_w[1] + true_b #标签
labels+=nd.random.normal(scale=0.01,shape=(labels.shape))#加一个噪声(数据集里的一些干扰信息)

#读取数据集,使用gluon接口的data模块,由于data很多作为变量,所以别名为gdata
from mxnet.gluon import data as gdata

batch_size=10
dataset=gdata.ArrayDataset(features,labels)#将训练集的特征和标签组合
data_iter=gdata.DataLoader(dataset,batch_size,shuffle=True)#随机读取小批量
for X,y in data_iter:
    print(X,y)
    break

#定义模型
from mxnet.gluon import nn
net=nn.Sequential()#当作是串联各个层的一个容器
net.add(nn.Dense(1))#Dense全连接层(稠密层),输出个数为1

#初始化模型参数
from mxnet import init
net.initialize(init.Normal(sigma=0.01))#指定权重参数每个元素初始化为均值为0,标准差为0.01的正态分布,偏差参数默认为0

#定义损失函数
from mxnet.gluon import loss as gloss
loss=gloss.L2Loss()#平方损失(L2范数损失)

#指定训练算法并训练模型
from mxnet import gluon
trainer=gluon.Trainer(net.collect_params(),'sgd',{'learning_rate':0.03})
num_epochs=5
for epoch in range(1,num_epochs+1):
    for X,y in data_iter:
        with autograd.record():
            l=loss(net(X),y)
        l.backward()
        trainer.step(batch_size)#迭代模型参数
    l=loss(net(features),labels)
    print('epoch %d,loss:%f' % (epoch,l.mean().asnumpy()))

dense=net[0]#Dense(2 -> 1, linear)
print(dense.weight.data(),dense.bias.data())

[[-0.52707773 -0.3183773 ]
 [-0.8742927  -0.4267638 ]
 [ 0.67303514 -0.49647954]
 [ 0.0672691   0.5915836 ]
 [ 0.10801227  0.5210501 ]
 [-1.0340341   0.32417756]
 [ 1.3193419  -0.7513297 ]
 [ 0.34880197 -0.3986237 ]
 [ 0.37714773 -2.389378  ]
 [-0.18407269 -0.02723058]]
<NDArray 10x2 @cpu(0)> 
[ 8.544108   7.5977607 15.855234   4.7529902  5.484421   1.2227746
 20.962944  13.484395  28.347012   8.074814 ]
<NDArray 10 @cpu(0)>
epoch 1,loss:0.144768
epoch 2,loss:0.000310
epoch 3,loss:0.000054
epoch 4,loss:0.000053
epoch 5,loss:0.000053

[[ 5.0000153 -7.4002795]]
<NDArray 1x2 @cpu(0)> 
[8.799638]
<NDArray 1 @cpu(0)>
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 线性回归是一种统计学方法,可用于预测数值型变量之间的关系,如房价和房屋尺寸之间的关系。在这个场景下,我们考虑通过线性回归来建立一种模型,在已知的房屋尺寸的基础上,预测相应的房价。 假设我们有一个包含有房价和房屋尺寸的数据集,我们可以使用数据探索的工具,如散点图,来初步探索两个变量之间的关系。然后,我们可以使用线性回归模型来拟合这些数据点,并且预测新的房屋尺寸的房价。 接下来,我们将绘制一个图形来展示我们的线性回归模型如何拟合数据点和预测房价。在这张图中,我们将在横轴上表示房屋尺寸,纵轴上表示房价,并绘制出我们的线性回归模型所拟合的直线。这张图将使我们更容易地理解房价和房屋尺寸之间的关系,并且可以用于后续的数据分析以及预测。 在绘制完这张图后,我们可以检查线性回归模型的拟合精度。如果线性回归模型在数据集中存在显著的偏差,就需要重新考虑预测模型,或者增加更多的特征变量,这样可以使预测的结果更准确。此外,在应用线性回归模型之前,我们还应该注意一些其他的影响因素,如噪声或异常值,这样可以避免模型的偏差以及其他的预测错误。 ### 回答2: 线性回归是一种常用的机器学习算法,可以用于预测房价等连续值的问题。具体地说,线性回归就是通过找到一条直线(或者超平面,在高维空间中)来尽可能地拟合已知数据,然后利用这条直线进行预测。 在房价预测的问题中,我们可以使用线性回归算法来构建一个模型。首先,我们需要收集一些房价相关的数据,例如房屋面积、地理位置、年龄等等。然后,我们可以使用这些数据来训练线性回归模型,找到一个最优的线性函数,使得它最好地拟合已有的数据。 训练模型之后,我们就可以利用这个模型来进行预测。比如,我们输入某个房屋的面积、位置等信息,就可以利用模型预测这个房屋的价格了。 为了更加直观地理解线性回归算法,我们可以绘制出数据点和拟合直线的图像。在这个图像中,我们可以看到每一个数据点的位置,以及拟合直线的位置,这样可以更加方便地理解线性回归算法的表现。 总之,线性回归是一种非常实用的机器学习算法,它可以帮助我们解决很多连续值预测的问题,例如房价预测等。同时,在理解线性回归算法的时候,我们可以通过绘制图像来更好地理解模型的表现。 ### 回答3: 线性回归是一种广泛用于预测连续数值的统计学方法,常用于房价预测。我们可以通过已知的房屋面积、房龄等特征,拟合出一个数学函数,进而计算出未知房屋的价格。下面我将简单介绍如何使用Python中的scikit-learn库进行线性回归分析,以及如何绘制预测结果的图像。 首先,我们需要加载数据并探索数据的基本特征。数据可以从Kaggle等网站下载得到。以Boston House Price数据集为例,我们可以通过Pandas库读入数据并查看前几行数据的情况: ``` import pandas as pd df = pd.read_csv('train.csv') print(df.head()) ``` 接下来,我们需要针对数据的特征选择适当的模型进行拟合。这里我们选取最简单的线性回归模型。通过scikit-learn库中的LinearRegression模块,可以方便地进行模型训练。 ``` from sklearn.linear_model import LinearRegression X = df[['RM', 'LSTAT', 'PTRATIO']] # 我们选择房间数量、低收入人群比例以及学生与教师之比三个特征来预测房价 y = df['MEDV'] lr = LinearRegression() lr.fit(X, y) # 模型拟合 ``` 至此,我们已经拟合出了一个模型,可以使用测试数据集进行预测并计算模型的评估指标,例如均方误差(Mean Squared Error,MSE)等。同时,我们还可以通过matplotlib库绘制出预测结果的图像: ``` import matplotlib.pyplot as plt import numpy as np import seaborn as sns sns.set(style='whitegrid', context='notebook') pred_y = lr.predict(X) plt.scatter(y, pred_y) plt.plot([0, 50], [0, 50], '--k') plt.xlabel('True value') plt.ylabel('Predicted value') ``` 在图像中,横坐标代表真实房价,纵坐标代表预测房价。可以看到,预测结果与真实情况的差异较小,说明模型的拟合效果较好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寅恪光潜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值