一、梯度下降法的理解
1.梯度:在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来(有方向的斜率)
2.梯度下降:是一种求解的最优化算法
比如我们在一座大山上的某处位置,由于我们不知道怎么下山是最快的,选择在该位置最陡峭的位置向下走一步,然后继续求解当前位置梯度,向这一步所在位置沿着最陡峭最易下山的位置走一步。这样一步步的走下去,一直走到觉得我们已经到了山脚。当然这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处。
二、梯度下降的概念
1.假设函数(hypothesis function)
在监督学习中,为了拟合输入样本,而使用的假设函数,记为。比如对于单个特征的m个样本(x(i),y(i))(i=1,2,...m),可以采用拟合函数如下:
2.损失函数
3.学习率(步长)
太大可能无法收敛
太小可能运行时间太慢
三、梯度下降的算法
1.代数方式
1.1函数
假设函数:
损失函数:
1.2.算法过程
1.2.1确定当前位置的损失函数的梯度,即
1.2.2用步长乘以梯度,得到下降距离,即
1.2.3确定是否所有θ的下降距离都小于
(运行过程会自动缩小距离,找到最低点的导数等于原位置)
1.2.4不是的话,更新所有θ,
2.矩阵方式
2.1函数
假设函数:
损失函数:
2.2更新表达式
(求导过程和最小二乘法那一模一样)
四、应用(糖尿病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]