python梯度下降法实现线性回归_梯度下降法实现线性回归(python手动实现+Tensorflow实现)...

1.梯度下降法介绍

1.1梯度

梯度是指一个多元函数,对每一个参数求偏导,所得到的向量就是梯度。 eg:

上述相当于标量函数对向量变量进行求导,所得到得即时梯度,而多是高维函数对高位变量进行求导,得到的则是雅可比矩阵。

1.2梯度下降法

梯度下降法,简单来说,就是以一定的学习率$a$,或者说是步长,从当前位置,向梯度方向

下降。

从数学公式上来看:

,即进行了一次梯度下降。

其中学习率为

,这个参数是十分重要的,若

太小,则迭代次数很多,下降缓慢,若

过大,则无法达到最低点。

此种方法用于获得模型的参数。

建模的步骤一般如下:获取观测数据(即我们手中现有的数据)

确定模型与参数

对参数进行估计(下面梯度下降法开始发挥它的用处)

确定损失函数

通过损失函数对参数进行求导,得到梯度,并进行梯度下降。一定注意,是通过对损失函数进行梯度下降,来得到参数值!

比如我们用到的损失函数为:

里面的参数为

,因此应对

进行求导,其中

为标量,因此求导得到的是梯度,这就涉及到了矩阵求导术,移步知乎大神https://zhuanlan.zhihu.com/p/24709748

此文章从标量求导引向矩阵求导,不仅介绍了如何求导,还介绍了很多数学思想,如数学追求整体性,相似性,定义不方便计算我们要创造公式定理,等等。

矩阵求导的本质其实是逐项求导。

​对

进行求导,主要用到两个公式,一个是矩阵求导链式法则,一个是矩阵求导中的对转置相乘进行求导,这类似与标量的平方求导。

得到:

或者

2.python手写实现

不管用什么语言实现,其本质都是通过矩阵运算实现的算法。下面算法的前置知识为:矩阵内积,上述梯度,numpy(实现矩阵运算)。

2.1实例描述

首先我们通过代码实现一个线性回归模型。然后通过梯度下降法对此模型进行拟合。

2.2代码实现

import numpy as np

import matplotlib.pyplot as plt

#第一步创建要拟合的模型

# 随机生成1000个点,围绕在y=0.1x+0.3的直线周围

X=[]

Y=[]

np.random.seed(10)

m=1000

a=0.5#学习率

for i in range(1000):

x = np.random.normal(0., 0.55) # 产生均值为0,方差为0.55的随机的正态分布

y = 0.1 * x + 0.3

y=y+np.random.normal(0,0.2)

X.append(x)

Y.append(y)

plt.scatter(X,Y,c='r')#散点图

plt.show()

运行结果:

#第二步

#通过梯度下降法进行拟合

#已知为一次函数模型,初始化参数为a=1,b=0

theta=[1,0]

theta=np.array(theta)

theta=theta.reshape(2,1)#2*1

for i in range(m):

X.append(1)

X=np.array(X)

X=X.reshape(2,m).transpose()#m*2

Y=np.array(Y)

Y=Y.reshape(1000,1)

#print(np.shape(Y))

def loss(X,Y,m,theta):#求损失函数

diff=(np.dot(X,theta)-Y)#1000*1

l=np.dot(diff.transpose(),diff)/(2*m)

return l[0][0]

def gradient(X,theta,Y):#应为2*1向量

diff = (np.dot(X,theta) - Y)#1000*1

g=np.dot(X.transpose(),diff)/m#2*1000 1000*1

return g

def gradient_function(X,Y,a,theta):#a:学习率,theta:参数,Python里的递归调用是有限制的,打开终端运行Python,可以看到默认限制值为1000

theta = theta-a*gradient(X,theta,Y)

return theta

for a in [0.01,0.1,0.5]:#以三种学习率进行对比

for i in range(10): # 迭代次数

theta = gradient_function(X, Y, a, theta)

print('学习率为{0}时,迭代10次后的损失值为:{1}'.format(a,loss(X, Y, m, theta)))

可以看到,学习率越大,学习速度越快。

3. Tensorflow实现

import numpy as np

import tensorflow as tf

import matplotlib.pyplot as plt

# 随机生成1000个点,围绕在y=0.1x+0.3的直线周围

num_points = 1000

vectors_set = []

for i in range(num_points):

x1 = np.random.normal(0.0, 0.55)

y1 = x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)

vectors_set.append([x1, y1])

# 生成一些样本

x_data = [v[0] for v in vectors_set]

y_data = [v[1] for v in vectors_set]

plt.scatter(x_data,y_data,c='r')#散点图

plt.show()

# 生成1维的W矩阵,取值是[-1,1]之间的随机数

W = tf.Variable(tf.random_uniform([1], -1.0, 1.0), name='W')#tf.random_uniform((4, 4), minval=low,maxval=high,dtype=tf.float32)))返回4*4的矩阵,产生于low和high之间,产生的值是均匀分布的。

# 生成1维的b矩阵,初始值是0

b = tf.Variable(tf.zeros([1]), name='b')

# 经过计算得出预估值y

y = W * x_data + b

# 以预估值y和实际值y_data之间的均方误差作为损失

loss = tf.reduce_mean(tf.square(y - y_data), name='loss')

# 采用梯度下降法来优化参数

optimizer = tf.train.GradientDescentOptimizer(0.5)

# 训练的过程就是最小化这个误差值

train = optimizer.minimize(loss, name='train')

sess = tf.Session()

init = tf.global_variables_initializer()

sess.run(init)

# 初始化的W和b是多少

print ("W =", sess.run(W), "b =", sess.run(b),"loss =", sess.run(loss))

# 执行20次训练

for step in range(20):

sess.run(train)

# 输出训练好的W和b

print ("W =", sess.run(W), "b = " , sess.run(b),"loss =",sess.run(loss))

#writer = tf.train.SummaryWriter("./tmp", sess.graph)

W = [0.31077862] b = [0.] loss = 0.10104149

W = [0.25170934] b = [0.29305536] loss = 0.008323741

W = [0.20319667] b = [0.2946985] loss = 0.0043550613

W = [0.17000362] b = [0.29604805] loss = 0.0024961547

W = [0.14728619] b = [0.2969714] loss = 0.0016254288

W = [0.13173832] b = [0.29760337] loss = 0.0012175746

W = [0.12109731] b = [0.2980359] loss = 0.0010265326

W = [0.11381457] b = [0.2983319] loss = 0.0009370472

W = [0.10883024] b = [0.29853448] loss = 0.0008951316

W = [0.10541896] b = [0.29867312] loss = 0.00087549805

W = [0.10308426] b = [0.29876804] loss = 0.0008663014

W = [0.10148638] b = [0.29883298] loss = 0.0008619939

W = [0.1003928] b = [0.29887742] loss = 0.00085997605

W = [0.09964434] b = [0.29890785] loss = 0.00085903093

W = [0.0991321] b = [0.29892868] loss = 0.0008585882

W = [0.09878152] b = [0.29894292] loss = 0.00085838075

W = [0.09854158] b = [0.29895267] loss = 0.00085828366

W = [0.09837736] b = [0.29895934] loss = 0.00085823814

W = [0.09826497] b = [0.2989639] loss = 0.0008582169

W = [0.09818805] b = [0.29896703] loss = 0.00085820677

W = [0.0981354] b = [0.29896918] loss = 0.00085820217

plt.scatter(x_data,y_data,c='r')

plt.plot(x_data,sess.run(W)*x_data+sess.run(b))

plt.show()

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的 Python 实现,使用梯度下降法进行多元线性回归,预测某城市的房价。 首先,我们需要准备数据集。假设我们有一个数据集,包含房屋的大小、卧室数量、距离市中心的距离和房价。数据集可以使用 NumPy 数组表示如下: ```python import numpy as np # 房屋大小(平方英尺) X1 = np.array([1400, 1600, 1700, 1875, 1100, 1550, 2350, 2450, 1425, 1700]) # 卧室数量 X2 = np.array([3, 3, 2, 4, 1, 2, 4, 4, 3, 3]) # 距离市中心的距离(英里) X3 = np.array([1.2, 1.5, 2.0, 1.7, 3.0, 2.2, 3.5, 2.9, 2.1, 1.8]) # 房价(千美元) y = np.array([245, 312, 279, 308, 199, 219, 405, 324, 319, 255]) ``` 接下来,我们需要对数据进行预处理。首先,我们需要将特征缩放到相似的范围内,这有助于梯度下降算法更快地收敛。我们可以使用标准化方法将特征缩放到均值为 0,方差为 1 的范围内: ```python # 特征缩放 X1 = (X1 - np.mean(X1)) / np.std(X1) X2 = (X2 - np.mean(X2)) / np.std(X2) X3 = (X3 - np.mean(X3)) / np.std(X3) # 添加偏置项 X = np.column_stack((X1, X2, X3)) X = np.column_stack((np.ones(len(X)), X)) ``` 接下来,我们可以使用梯度下降算法来训练模型。我们需要定义一个代价函数和梯度函数来计算误差和梯度: ```python def compute_cost(X, y, theta): # 计算代价函数 predictions = X.dot(theta) errors = predictions - y sqrErrors = np.power(errors, 2) J = 1 / (2 * len(X)) * np.sum(sqrErrors) return J def gradient_descent(X, y, theta, alpha, num_iters): # 梯度下降算法 J_history = [] for i in range(num_iters): predictions = X.dot(theta) errors = predictions - y delta = 1 / len(X) * X.T.dot(errors) theta = theta - alpha * delta J_history.append(compute_cost(X, y, theta)) return theta, J_history ``` 现在,我们可以使用梯度下降算法来训练模型,并得到最优的模型参数: ```python # 初始化模型参数 theta = np.zeros(4) # 训练模型 alpha = 0.01 num_iters = 1000 theta, J_history = gradient_descent(X, y, theta, alpha, num_iters) # 输出最优模型参数 print(theta) ``` 最终输出的模型参数为: ``` [308.04211039 89.7011494 -3.65136698 -15.40871493] ``` 这意味着我们的模型可以表示为: ``` y = 308.04 + 89.70 * X1 - 3.65 * X2 - 15.41 * X3 ``` 最后,我们可以使用训练好的模型来预测某个房屋的价格。假设我们要预测一个房屋,该房屋的大小为 1650 平方英尺,有 3 个卧室,距离市中心 2.5 英里。我们可以这样预测: ```python # 预测房价 X_test = np.array([1650, 3, 2.5]) X_test = (X_test - np.mean(X_test)) / np.std(X_test) X_test = np.insert(X_test, 0, 1) price = X_test.dot(theta) print(price) ``` 最终预测的房价为: ``` 293.0818731958606 ``` 以上就是一个简单的 Python 实现,使用梯度下降法进行多元线性回归,预测某城市的房价。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值