正在学习线性回归问题,选取的是房价和面积的线性关系。训练数据9组。
h(x)= a*x+b
通过【正规方程法】求得 a=5.8, b=-111
通过【梯度下降法】分别设置a和b的学习率
lr_a =0.000016
lr_b =0.01
迭代2000次也能求得近似 a=5.8, b=-111
但是进行归一化特征缩放后,a=4.8,而b的值每次运行都不一样,代价函数依然能收敛,这是为什么?刚学到线性回归,求通俗解答。
# 导入numpy
import numpy as np
# 导入pandas库
import pandas as pd
# 导入绘图库
from matplotlib import pyplot as plt
# 读取excel文件
df = pd.read_excel('house_price.xlsx')
# 将df某列转化为numpy格式
area = df['Size'].to_numpy()
price = df['Price'].to_numpy()
# 定义归一化方法
def normalize(array):
min_value = np.min(array)
max_value = np.max(array)
return (array - min_value) / (max_value - min_value)
# 对原数据进行归一化
x = normalize(area)
# 为了形式统一,我们虽然定义了y,但注意不要对y进行处理
y = price
print(x)
# 使用平方/均方误差作为代价函数
def cost_function(a,b):
cost = np.sum((a * area + b - price) ** 2)
return cost
def cost_avg_function(a,b):
cost_avg = np.sum((a * area+b - price) ** 2)/len(area)
return cost_avg
# 计算梯度
def grad_a_func(a,b):
grad_a = np.sum((a * area + b - price) * area)
return grad_a
def grad_b_func(a,b):
grad_b = np.sum(a * area + b - price)
return grad_b
# 定义超参数
# 学习率
lr = 0.000016
# 迭代次数
epoch = 1000
# 创建一个数组,记录每一次迭代时的代价,用于最后绘图
cost_log = np.empty(epoch)
# 为待训练参数生成随机初始值
a1 = np.random.randint(10)
b1 = np.random.randint(10)
# 开始迭代
for e in range(epoch):
cost = cost_function(a1, b1)
# 分别计算两个方向上的梯度
gradient_a = grad_a_func(a1, b1)
gradient_b = grad_b_func(a1, b1)
# 同时更新a1和b1
a1 = a1 - lr * gradient_a
b1 = b1 - lr * gradient_b
# 记录本次迭代的代价
cost_log[e] = cost
print(f'当前迭代第{e}次:cost={cost},a={a1},b={b1}')
# 绘制图形
plt.title('Cost Function Curve')
plt.xlabel('Epoch')
plt.ylabel('Cost')
plt.plot(np.arange(epoch), cost_log)
plt.show()