目录
[实验名称] 线性回归实验
[实验目的]
- 熟悉和掌握单变量线性回归算法
- 熟悉和掌握批处理梯度下降算法
- 熟悉和掌握多变量线性回归算法
[实验要求]
- 采用Python、Matlab等高级语言进行编程,推荐优先选用Python语言
- 核心模型和算法需自主编程实现,不得直接调用Scikit-learn、PyTorch等成熟框架的第三方实现
- 代码可读性强:变量、函数、类等命名可读性强,包含必要的注释
本实验所使用的数据集下载地址为:
链接:https://pan.baidu.com/s/1pNmQbPfeFOyRHMdyed4KIQ?pwd=ron1
提取码:ron1
[实验原理]
- 构建线性模型,以最小平方误差为目标函数,使用梯度下降法不断更新参数。
- 而计算梯度时,梯度
[实验内容]
一. 单变量线性回归
1.采用数据集 “data/regress_data1.csv”进行单变量线性回归实验
2.借助matplotlib 画出原始数据分布的散点图(x=“人口”,y=”收益”)
3.以最小平方误差为目标函数,构造模型的损失(误差)计算函数:
其中,
4.实现批量梯度下降算法(Batch Gradient Decent)用于优化线性回归模型:
其中,
其中,为参数向量,
为样本量。
提示:
- 批量梯度下降算法可以参考第5章神经网络的优化算法
- 线性回归模型的偏置b可吸收进参数向量w, 从而采用向量形式
5.采用上述批量梯度下降法,优化单变量线性回归模型。其中,迭代轮数epoch设定为1000轮,学习率设定为 0.01,参数初始化为0。
代码输出:
- 优化结束时的损失值和模型参数
- 将模型拟合的直线和原始数据散点图画到同一张图中
二. 多变量线性回归
- 采用数据集 “data/regress_data2.csv”进行多变量线性回归实验,通过房子的大小和房间数量两个变量 回归房子的价格。
-
对数据进行特征归一化:
- 采用上述批量梯度下降法,优化多变量线性回归模型。其中,迭代轮数epoch设定为1000轮,学习率设定为 0.01,参数初始化为0。
代码输出:
- 优化结束时的损失值和模型参数
- 画图输出训练误差(损失)随着迭代轮数epoch 的变化曲线
[实验代码和结果]
一.单变量线性回归
1. 实验代码
import pandas as pd #导入pandas库
import numpy as np #导入numpy库
import matplotlib.pyplot as plt #导入matplotlib.pyplot库
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
data=pd.read_csv(r"E:\机器学习\regress_data1.csv") #读取数据
data.plot(kind="scatter",x="人口",y="收益") #绘制散点图
plt.xlabel("人口",fontsize=10) #横坐标
plt.ylabel("收益",fontsize=10) #纵坐标
plt.title("人口与收益之间的关系") #标题
plt.show() #画图
data.insert(0,"ones",1) #插入列,便于后面计算
col_num=data.shape[1] #训练特征个数
m=data.shape[0] #训练标签个数
X=data.iloc[:,:col_num-1].values #训练集的特征
y=data.iloc[:,col_num-1].values #训练集的标签
y=y.reshape((m,1))
def h(X,w):
return X@w
def cost(X,y,w):
return np.sum(np.power(h(X,w)-y,2))/(2*m)
def gradient_descent(X,y,w,n,a):
t=w
cost_lst=[]
for i in range(n):
error=h(X,w)-y
for j in range(col_num-1):
t[j][0]=w[j][0]-((a/m)*np.sum(error.ravel()*X[:,j].ravel()))
w=t
cost_lst.append(cost(X,y,w))
return w,cost_lst
def least_square(X,y):
w=np.linalg.inv(X.T@X)@X.T@y
return w
n=1000 #迭代次数越多越好
a=0.01 #学习率适中,不能太大,也不能太小
w=np.zeros((col_num-1,1)) #初始化权重向量
w,cost_lst=gradient_descent(X,y,w,n,a) #调用梯度下降函数
plt.plot(range(n),cost_lst,"r-+")
plt.xlabel("迭代次数")
plt.ylabel("误差")
plt.show()
x=np.linspace(data["人口"].min(),data["人口"].max(),50) #预测特征
y1=w[0,0]*1+w[1,0]*x #预测标签
plt.scatter(data["人口"],data["收益"], label='训练数据') #训练集
plt.plot(x,y1,"r-+",label="预测线") #预测集
plt.xlabel("人口",fontsize=10)
plt.ylabel("收益",fontsize=10)
plt.title("人口与收益之间的关系")
plt.show()
print(w)
print(cost_lst)
2. 结果
(1)优化结束时的损失值和模型参数
模型参数:
优化结束后的损失值:
大概为4.5左右
(2)将模型拟合的直线和原始数据散点图画到同一张图中
二.多变量线性回归
1. 实验代码
import pandas as pd #导入pandas库
import numpy as np #导入numpy库
import matplotlib.pyplot as plt #导入matplotlib.pyplot库
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
datas=pd.read_csv(r"E:\机器学习\regress_data2.csv") #读取数据
datas=(datas-datas.mean())/datas.std() #正则化
datas.insert(0,'ones',1) #插入列
col_num=datas.shape[1] #训练特征个数
m=datas.shape[0] #训练标签
X=datas.iloc[:,:col_num-1].values #训练特征
y=datas.iloc[:,col_num-1].values #训练标签
y=y.reshape((m,1))
def h(X,w):
return X@w
def cost(X,y,w):
return np.sum(np.power(h(X,w)-y,2))/(2*m)
def gradient_descent(X,y,w,n,a):
t=w
cost_lst=[]
for i in range(n):
error=h(X,w)-y
for j in range(col_num-1):
t[j,0]=w[j,0]-((a/m)*np.sum(error.ravel()*X[:,j].ravel()))
w=t
cost_lst.append(cost(X,y,w))
return w,cost_lst
n=1000 #迭代次数
a=0.01 #学习率
w=np.zeros((col_num-1,1)) #初始化特征向量w
w,cost_lst=gradient_descent(X,y,w,n,a)
plt.plot(range(n),cost_lst,'r+-')
plt.xlabel("迭代次数")
plt.ylabel("误差")
plt.show()
print(w)
print(cost_lst)
2. 结果
(1)优化结束时的损失值和模型参数
模型参数:
损失值:
大概为0.13左右
(2)画图输出训练误差(损失)随着迭代轮数epoch 的变化曲线
[小结或讨论]
(1)线性回归三大要素
- 假设函数 h(X,w)
- 损失函数 cost(X,y,w)
- 梯度下降/最小二乘函数(求解权重向量w的函数)
(2)单变量线性回归
1.导入必要的库
2.读取数据
3.绘制散点图
4.划分数据
5.定义模型函数
6.定义损失函数
7.求权重向量w
7.1 梯度下降函数
8.训练模型
9.绘制预测曲线
(3)多变量线性回归
1.导入库
2.读取数据
3.划分数据
4.定义假设函数
5.定义损失函数
6.定义梯度下降函数
7.训练模型