练习一:单变量线性回归,对数据ex1data1.txt进行回归预测
线性回归和梯度下降公式
导入第三方库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
第一步:第一步:提取数据,并对数据的特征和标签进行处理,可视化数据
data =pd.read_csv('ex1data1.txt',names =['人口','盈利'])
data.head()
#提取特征X
X_ =data.iloc[:,:-1]
#提取目标y
y =data.iloc[:,-1]
#对特征X插入第一列1值
ones =pd.DataFrame({'ones':np.ones(len(data))})
X =pd.concat([ones,X_],axis=1)
数据X部分如下:
#数据可视化,输出人口与盈利之间的散点图
plt.rcParams['font.sans-serif']='SimHei'
plt.rcParams['axes.unicode_minus'] =False
plt.figure(figsize =(8,7))
plt.scatter(X["人口"],y,marker ='x',c ='red')
plt.title("人口-盈利散点图")
plt.xlabel("人口数量")
plt.ylabel("盈利")
plt.show()
第二步:定义损失函数(假设函数,损失函数),初始化参数θ为0值,计算损失函数
#定义损失函数
def cost(X,y,theta):
#输入特征值97*2,目标值97*1,参数θ2*1
#输出损失值J
temp =X*theta-y
J =np.sum(np.power(temp,2))/(2*len(X))
return J
#初始化θ零值
theta =np.matrix([[0],[0]])
X =np.matrix(X.values)
y =np.matrix(y.values)
#对y转置
y =y.T
#X.shape,y.shape,theta.shape
#((97, 2), (97, 1), (2, 1))
#type(X),type(y),type(theta)
#(numpy.matrix, numpy.matrix, numpy.matrix)
#cost(X,y,theta)
#32.072733877455676
第三步:定义梯度下降函数,可以先定义梯度函数
#定义损失函数偏导数
def gradient(X,y,theta):
#输入X特征值97*2,y目标值97*1,θ参数2*1
#输出损失函数对参数θ的偏导数2*1 theta0,theta1的偏导
temp =X*theta-y
#temp 97*1 X.T 2*97
#grad_theta 2*1
grad_theta = X.T*temp
#再除以中的数量97
grad_theta =grad_theta/(len(X))
return grad_theta
#gradient(X,y,theta)
#matrix([[ -5.83913505],
[-65.32884975]])
#定义梯度下降函数
def batch_gradient(theta,X,y,alpha,epoch):
#输入:theta 2*1,X 97*2,y 97*1,alpha 步长,epoch 迭代次数
#输出:最终参数θ,迭代损失值cost_iter,一个列表
theta_ =theta
cost_iter =[cost(X,y,theta_)]
for i in range(epoch):
theta_ =theta_-alpha*gradient(X,y,theta_)
cost_iter.append(cost(X,y,theta_))
return theta_,cost_iter
alpha =0.01
epoch =500
cost_=[]
final_theta,cost_ =batch_gradient(theta,X,y,alpha,epoch)
#final_theta,cost_[-1]
#(matrix([[-2.28286727],
[ 1.03099898]]),
4.713809531116866)
第四步:输出结果的可视化,以及损失值的迭代曲线
#结果的可视化,在原数据上添加最终参数θ得到的预测直线
#横坐标人口,纵坐标盈利
#预测直线的横轴数据x和纵轴数据y_predict
x =data["人口"]
#np.arange(x.min(),x.max(),0.1) 第三个数是间隔距离,linspace第三个数是 总个数
x =np.linspace(x.min(),x.max(),50)
y =final_theta[0] +final_theta[1]*x
#可视化
plt.figure(figsize =(8,7))
plt.plot(x,y)
plt.scatter(data["人口"],data["盈利"],marker ='x',c ='red')
plt.title("人口-盈利散点图")
plt.legend(['预测直线','原始数据'])
plt.xlabel("人口数量")
plt.ylabel("盈利")
plt.show()
#可视化损失函数迭代图像
x_iter =[i for i in range(epoch)]
len(cost_),len(x_iter)
#(501, 500)
plt.figure(figsize=(8,7))
plt.plot(x_iter,cost_[1:],'r')
plt.ylabel("损失函数值")
plt.xlabel("迭代次数")
plt.show
练习二:多变量线性回归,对数据ex1data2.txt进行回归
第一步:读取数据,并对数据进行标准化处理
#读取数据
data2 =pd.read_csv('ex1data2.txt',names =['面积','房间数','价格'])
data2.head()
#标准化数据处理
#定义标准差标准化数据
def feature_normalize(data):
return (data-data.mean())/data.std()
data2_normal =feature_normalize(data2)
data2_normal.head()
原始数据 和标准化数据分别如下:
第二步:多变量线性回归,并输出损失函数的迭代过程
#提取特征和目标
data2_X =data2_normal.iloc[:,:-1]
data2_y =data2_normal.iloc[:,-1]
#对特征插入第一列1值
ones =pd.DataFrame({'1值':np.ones(len(data2_X))})
data2_X =pd.concat([ones,data2_X],axis=1)
#初始化参数θ
theta2 =np.zeros(data2_X.shape[1])
#data2_X.shape,data2_y.shape,theta2.shape
#((47, 3), (47,), (3,))
#化为矩阵运算
data2_Xm =np.matrix(data2_X)
data2_ym =np.matrix(data2_y).T
theta2m =np.matrix(theta2).T
#定义损失函数
def cost(X,y,theta):
#输入特征值47*3,目标值47*1,参数θ3*1
#输出损失值J
temp =X*theta-y
J =np.sum(np.power(temp,2))/(2*len(X))
return J
#输出初始化损失值
cost(data2_Xm,data2_ym,theta2m)
#0.48936170212765967
#定义损失函数偏导数
def gradient(X,y,theta):
#输入X特征值47*3,y目标值47*1,θ参数3*1
#输出损失函数对参数θ的偏导数2*1 theta0,theta1的偏导
temp =X*theta-y
#temp 47*1 X.T 3*47
#grad_theta 2*1
grad_theta = X.T*temp
#再除以中的数量47
grad_theta =grad_theta/(len(X))
return grad_theta
#输出最终梯度下降得到参数θ和损失值
alpha =0.01
epoch =500
final_theta2,final_cost2 =batch_gradient(theta2m,data2_Xm,data2_ym,alpha,epoch)
'''
final_theta2,final_cost2[-1]
(matrix([[-1.22691455e-16],
[ 8.30383883e-01],
[ 8.23982853e-04]]),
0.13195133775794732)
'''
#输出损失值的迭代过程图像
x_iter =[i for i in range(epoch)]
plt.figure(figsize=(8,7))
plt.plot(x_iter,final_cost2[1:],'r')
plt.ylabel("损失函数值")
plt.xlabel("迭代次数")
plt.show
第三步:输出不同步长情况下的损失值迭代图像
alpha_list =[0.005,0.01,0.05,0.1,0.5]
epoch =50
x_iter =[i for i in range(epoch)]
plt.figure(figsize=(8,7))
for i in alpha_list:
theta_al,cost_al =batch_gradient(theta2m,data2_Xm,data2_ym,i,epoch)
plt.plot(x_iter,cost_al[1:])
plt.legend(['alpha =0.005','alpha =0.01','alpha =0.05','alpha =0.1','alpha =0.5'])
plt.ylabel("损失函数值")
plt.xlabel("迭代次数")
plt.show