今天我又复习了一下昨天写的博客,发现数据集有问题,怎么会出现负数呢,我有查看了黄老师给的数据集,又仔细想了一下,收益可以是负数嘛,是自己多虑了。这篇博客接着写单变量线性回归的梯度下降解法,最关键最重要的就是梯度下降解法,不仅在这个问题中能用到,在以后的其他问题中也都能用到。
一、导入所需库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
二、构造矩阵
data = pd.read_csv("linear_regression.csv")
data.insert(0,'ones',1)
n = data.shape[1]
x = data.iloc[:,:n-1]
y = data.iloc[:,n-1:]
x = np.matrix(x)
y = np.matrix(y)
w = np.array([0,0]).reshape(1,2)
w一定要定义成二维矩阵的形式,千万不能写成w = np.array([0,0]),否在在后面的计算当中会出现错误
三、构造目标函数、损失函数、代价函数
#其实不需要写 在代价函数中有体现 我只是拿来复习一下理论知识
def obiect_function(x,w):
'''
:param x: 特征矩阵
:param w: 权重矩阵
:return: 返回目标函数的值
'''
return x*w.T
#其实不需要写 在代价函数中有体现 我只是拿来复习一下理论知识
def loss_function(x,y,w):
'''
:param x:特征矩阵一个样本值
:param w: 权重矩阵
:param y: 对应x的实际值
:return: 返回一个样本的损失函数值
'''
return x*w.T-y
#代价函数 也是梯度下降要针对的函数
def cost_function(x,y,w):
'''
:param x: 特征矩阵
:param w: 权重矩阵
:param y: 实际值矩阵
:return: 返回代价函数的值
'''
#一共有m个样本
m = x.shape[0]
return np.sum(np.power(x*w.T-y,2))/(2*m)
四、梯度下降
def gradient_descent(x,y,w,alpha,iters):
'''
:param x: 特征矩阵
:param y: 实际值
:param w: 权重矩阵
:param alpha: 步长
:param iters: 迭代次数
:return: 返回迭代之后的权重矩阵w和每次迭代之后的代价函数的值组成的数组cost
'''
temp = np.zeros(w.shape)
x_len = x.shape[0]
w_len = w.shape[1]
cost = np.zeros(iters)
for i in range(iters):
error = x*w.T-y
for j in range(w_len):
temp[0,j] =w[:,j] - sum(np.multiply(error,x[:,j]))*(alpha/x_len)
w = temp
cost[i] = cost_function(x,y,w)
return w,cost
五、计算梯度下降
alpha = 0.01
iters = 1000
w,cost = gradient_descent(x,y,w,alpha,iters)
六、绘制预测收益和实际收益图
plt.figure(figsize=(12,8))
plt.scatter(data["人口"],data['收益'],label = '实际值')
plt.xlabel("人口")
plt.ylabel("收益")
plt.title("人口收益预测模型图")
c = np.linspace(min(data["人口"]),max(data['人口']),100)
f = [w[0,0]+w[0,1]* i for i in c]
plt.plot(c,f,label = "预测模型",color = "r")
plt.legend()
plt.show()
七、绘制迭代次数和代价函数关系图
plt.plot(range(1,iters+1),cost,label = '迭代次数和代价函数关系')
plt.xlabel("迭代次数")
plt.ylabel('代价函数')
plt.title('迭代次数和代价函数关系图')
plt.legend()
plt.show()
八、注意问题
①:绘制图形时plt.figure(figsize=(12,8))
②:在进行梯度下降运算时,一定要考虑向量化操作,不要在想for循环
③:黄老师实验课给的代码写的真好
def batch_gradientDescent(X, y, w, alpha, iters):
temp = np.matrix(np.zeros(w.shape))
parameters = int(w.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (X * w.T) - y
for j in range(parameters):
term = np.multiply(error, X[:, j])
temp[0, j] = w[0, j] - ((alpha / len(X)) * np.sum(term))
w = temp
cost[i] = computeCost(X, y, w)
return w, cost
④:对于梯度下降的代码要多看,多看,多看,很容易忘记其中的一些公式参数,写着写着就忘了
九、附录代码
# 一、导入所需库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 二、构造矩阵
data = pd.read_csv("linear_regression.csv")
data.insert(0,'ones',1)
n = data.shape[1]
x = data.iloc[:,:n-1]
y = data.iloc[:,n-1:]
x = np.matrix(x)
y = np.matrix(y)
w = np.array([0,0]).reshape(1,2)
# 三、构造目标函数、损失函数、代价函数
#其实不需要写 在代价函数中有体现 我只是拿来复习一下理论知识
def obiect_function(x,w):
'''
:param x: 特征矩阵
:param w: 权重矩阵
:return: 返回目标函数的值
'''
return x*w.T
#其实不需要写 在代价函数中有体现 我只是拿来复习一下理论知识
def loss_function(x,y,w):
'''
:param x:特征矩阵一个样本值
:param w: 权重矩阵
:param y: 对应x的实际值
:return: 返回一个样本的损失函数值
'''
return x*w.T-y
#代价函数 也是梯度下降要针对的函数
def cost_function(x,y,w):
'''
:param x: 特征矩阵
:param w: 权重矩阵
:param y: 实际值矩阵
:return: 返回代价函数的值
'''
#一共有m个样本
m = x.shape[0]
return np.sum(np.power(x*w.T-y,2))/(2*m)
# 四、梯度下降
def gradient_descent(x,y,w,alpha,iters):
'''
:param x: 特征矩阵
:param y: 实际值
:param w: 权重矩阵
:param alpha: 步长
:param iters: 迭代次数
:return: 返回迭代之后的权重矩阵w和每次迭代之后的代价函数的值组成的数组cost
'''
temp = np.zeros(w.shape)
x_len = x.shape[0]
w_len = w.shape[1]
cost = np.zeros(iters)
for i in range(iters):
error = x*w.T-y
for j in range(w_len):
temp[0,j] =w[:,j] - sum(np.multiply(error,x[:,j]))*(alpha/x_len)
w = temp
cost[i] = cost_function(x,y,w)
return w,cost
alpha = 0.01
iters = 1000
w,cost = gradient_descent(x,y,w,alpha,iters)
# 五、绘制预测收益和实际收益图
# plt.figure(figsize=(12,8))
# plt.scatter(data["人口"],data['收益'],label = '实际值')
# plt.xlabel("人口")
# plt.ylabel("收益")
# plt.title("人口收益预测模型图")
#
# c = np.linspace(min(data["人口"]),max(data['人口']),100)
# f = [w[0,0]+w[0,1]* i for i in c]
#
# plt.plot(c,f,label = "预测模型",color = "r")
# plt.legend()
# plt.show()
# 六、绘制迭代次数和代价函数关系图
plt.plot(range(1,iters+1),cost,label = '迭代次数和代价函数关系')
plt.xlabel("迭代次数")
plt.ylabel('代价函数')
plt.title('迭代次数和代价函数关系图')
plt.legend()
plt.show()