机器学习算法 | 梯度下降法

一、梯度下降法的理解

1.梯度:在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来(有方向的斜率)

2.梯度下降:是一种求解的最优化算法

比如我们在一座大山上的某处位置,由于我们不知道怎么下山是最快的,选择在该位置最陡峭的位置向下走一步,然后继续求解当前位置梯度,向这一步所在位置沿着最陡峭最易下山的位置走一步。这样一步步的走下去,一直走到觉得我们已经到了山脚。当然这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处。

 

二、梯度下降的概念

1.假设函数(hypothesis function)

在监督学习中,为了拟合输入样本,而使用的假设函数,记为h_{\Theta }(x)。比如对于单个特征的m个样本(x(i),y(i))(i=1,2,...m),可以采用拟合函数如下:h_{\Theta }=\Theta _0+\Theta _1x

2.损失函数

J(\Theta_0 ,\Theta_1)=\sum_{m}^{i=1}(h_{\Theta}(x^{i})-y^{i})^2

3.学习率(步长\alpha

\alpha太大可能无法收敛

\alpha太小可能运行时间太慢

三、梯度下降的算法

1.代数方式

1.1函数

假设函数:h_\theta(x_1,...,x_n)=\Theta_0+\Theta_1x_1+...+\Theta_nx_n

损失函数:J(\Theta_0 ,\Theta_1)=\frac{1}{2m}\sum_{m}^{i=1}(h_{\Theta}(x^{i})-y^{i})^2

1.2.算法过程

1.2.1确定当前位置的损失函数的梯度,即\frac{\partial }{\partial x}J(\Theta_0,\Theta_1,...,\Theta_n)

1.2.2用步长乘以梯度,得到下降距离,即\alpha \frac{\partial }{\partial x}J(\Theta_0,\Theta_1,...,\Theta_n)

1.2.3确定是否所有θ的下降距离都小于\varepsilon

(运行过程会自动缩小距离,找到最低点的导数等于原位置)

1.2.4不是的话,更新所有θ,\Theta_j=\Theta_j-\alpha \frac{\partial }{\partial x}J(\Theta_0,\Theta_1,...,\Theta_n)

 

2.矩阵方式

2.1函数

假设函数:h_\Theta(X)=X\Theta

损失函数:J(\Theta)=\frac{1}{2}(X\Theta-Y)^T(X\Theta-Y)

2.2更新表达式

\Theta=\Theta-\alpha X^T(X\Theta-Y)

(求导过程和最小二乘法那一模一样)

四、应用(糖尿病s1)

1.前期

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import warnings
warnings.filterwarnings('ignore')

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

# 导包获取糖尿病数据集
from sklearn.datasets import load_diabetes  
data_diabetes = load_diabetes()

data = data_diabetes['data']
target = data_diabetes['target']
feature_names = data_diabetes['feature_names']

df = pd.DataFrame(data,columns=feature_names)
#切分数据集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data,target,test_size=0.2)

#选取其中一个特征s1
from numpy import mat
x_train_df = pd.DataFrame(x_train,columns=feature_names)
s1=x_train_df.iloc[:,4]
s11=mat(s1.values).T
s12=np.hstack([np.ones((len(s11),1)),s11.reshape(-1,1)])

#画图
plt.scatter(s1, y_train)
plt.show()

2.手写代码

#梯度下降
#损失函数
def J(X,Y,theta):
    try:
        return np.sum((Y-X.dot(theta))**2)/len(X)
    except:
        return float('inf')

#损失函数求导
def dJ(X,Y,theta):
    res = np.empty(len(theta))
    res[0] = np.sum(X.dot(theta)-Y)
    for i in range(1,len(theta)):
        res[i] = (X.dot(theta)-Y).dot(X[:,i])
    return res*2 / len(X)

def gradient_descent(X,Y,initial_theta,eta,n_iters=1e4,epsilon=1e-8):
    theta=initial_theta
    cur_iter=0
    
    while cur_iter<n_iters:
        gradient = dJ(X,Y,theta)
        last_theta=theta
        theta = theta - eta * gradient
        
        if(abs(J(X,Y,theta)-J(X,Y,last_theta))<epsilon):
            break
        cur_iter += 1
    
    return theta
#带入数据
eta = 0.01
itheta=np.zeros(s12.shape[1])

gradient_descent(s12,y_train,itheta,eta)

输出结果:
array([150.49064571, 106.10190172])

3.sklearn的对比

from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
reg = SGDRegressor()
reg.fit(s12,y_train)
print(reg.score(s12,y_train))
print(reg.coef_)

输出结果:
0.001314261902390479
[75.39860165  6.40174396]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值