利用python语言实现一个简单的线性回归问题求解y = w * x + b
实现内容大致如下:通过读取data.csv文件内容获得若干组坐标数据,构造损失函数,不断更新迭代梯度,获取最接近得权重和偏置的值,确定最终线性函数
1.导入的函数库如下:
import numpy as np
import matplotlib.pyplot as plt
2.建立损失函数:
def compute_error_for_line_given_points(b,w,points):
totalError = 0
for i in range(0,len(points)): # points就类似于(x,y)坐标
x = points[i, 0]
y = points[i, 1]
totalError += (y - (w * x + b)) ** 2
plt.scatter(x, y, marker='o')
return totalError / float(len(points)) #loss 可能类似于一个均值
这里我们将loss定义为
这是因为在现实数据中并非如同解决数学问题一样两点即可确定一条准确的直线,而是会存在一种噪声(误差),比如y = w * x + b + ξ (ξ~N(0.01,1))
所以这里的损失函数构造并不是求y = w * x + b的最小值,而是求y和w*x+b之间的最小值,即求得w和b,使得y和w*x+b无限接近
3.建立梯度信息
def step_gradient(b_current,w_current,points,learningRate):
b_gradient = 0
w_gradient = 0
N = float(len(points)) #avg均值,loss是各个点累加起来得到的
for i in range(0,len(points)):
x = points[i,0]
y = points[i,1]
b_gradient += -(2/N) * (y - ((w_current * x) + b_current)) #偏L偏b
w_gradient += -(2/N) * x * (y - ((w_current * x) + b_current)) #偏L偏W
new_b = b_current - (learningRate * b_gradient)
new_w = w_current - (learningRate * w_gradient)
# w’ = w - lr * gradient
return [new_b,new_w]
梯度表示的是各点处的函数值减小最多的方向,虽然梯度的方向不一定是指向最小值,但是沿着它的方向能够最大限度地减少函数值
梯度法:函数的取值从当前位置沿着梯度方向前进一定的距离,然后在新的地方重新求梯度,再沿着梯度的方向前进,不断更新梯度然后前进,像这样沿着梯度的方向前进,逐渐减小函数值的过程就是梯度法
这里对于w和b的求导公式推理如下:
求得梯度后,利用梯度法更新参数:
4.循环更新梯度
def gradient_descent_runner(points,starting_b,starting_w,learning_rate,num_iterations):
b = starting_b
w = starting_w
for i in range(num_iterations):
b,w = step_gradient(b,w,np.array(points),learning_rate)
return [b,w]
根据读取文件内地坐标信息和超参数,不断更新迭代梯度,循环num_iter次
完整代码如下所示:
import numpy as np
import matplotlib.pyplot as plt
# y = wx +b
def compute_error_for_line_given_points(b,w,points):
totalError = 0
for i in range(0,len(points)): # points就类似于(x,y)坐标
x = points[i, 0]
y = points[i, 1]
totalError += (y - (w * x + b)) ** 2
plt.scatter(x, y, marker='o')
return totalError / float(len(points)) #loss 可能类似于一个均值
#梯度信息
def step_gradient(b_current,w_current,points,learningRate):
b_gradient = 0
w_gradient = 0
N = float(len(points)) #avg均值,loss是各个点累加起来得到的
for i in range(0,len(points)):
x = points[i,0]
y = points[i,1]
b_gradient += -(2/N) * (y - ((w_current * x) + b_current)) #偏L偏b
w_gradient += -(2/N) * x * (y - ((w_current * x) + b_current)) #偏L偏W
new_b = b_current - (learningRate * b_gradient)
new_w = w_current - (learningRate * w_gradient)
# w’ = w - lr * gradient
return [new_b,new_w]
#循环迭代梯度信息
def gradient_descent_runner(points,starting_b,starting_w,learning_rate,num_iterations):
b = starting_b
w = starting_w
for i in range(num_iterations):
b,w = step_gradient(b,w,np.array(points),learning_rate)
return [b,w]
def run():
points = np.genfromtxt("data.csv",delimiter=",")
print(points)
learning_rate = 0.0001
initial_b = 0 #initial y-intercept guess
initial_w = 0 #initial slope guess
num_iteration = 1000 #迭代1000次
print("Starting gardient descent at b = {0},m = {1},error = {2}"
.format(initial_b,initial_w,
compute_error_for_line_given_points(initial_b,initial_w,points)))
print("Running...")
[b,w] = gradient_descent_runner(points,initial_b,initial_w,learning_rate,num_iteration)
print("after {0} iteration ,b ={1},w = {2},error = {3}".
format(num_iteration,b,w,
compute_error_for_line_given_points(b,w,points)))
x = np.arange(0,100)
y = w * x + b
plt.plot(x,y)
plt.show()
if __name__ == '__main__':
run()
最后可以利用matplotlib将线性函数图像展示出来
控制台打印了点的数据以及计算前后的比较结果
获取到相关坐标数据后,利用python完成的线性回归问题的求解
初次编写,有很多不足和错误的地方,望各位指出,定及时更改
感谢观看!