机器学习实战Chp1: 梯度下降法--python实现

  • 参考博客:深入浅出–梯度下降法及其实现
  • 参考链接:https://blog.csdn.net/robotcat123/article/details/80588918
  • 参考链接:https://www.jianshu.com/p/c7e642877b0e

  • 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
  • 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向
  • 梯度的方向是函数在给定点上升最快的方向,那么梯度的反方向就是函数在给定点下降最快的方向
  • 为什么要梯度要乘以一个负号?
  • 梯度前加一个负号,就意味着朝着梯度相反的方向前进!我们在前文提到,梯度的方向实际就是函数在此点上升最快的方向!而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号

# -*- coding: utf-8 -*-
"""
Created on Thu Aug 02 17:01:54 2018

@author: muli
"""

import numpy as np
import matplotlib.pyplot as plt

# Size of the points dataset.
m = 20

# Points x-coordinate and dummy value (x0, x1).
X0 = np.ones((m, 1))
X1 = np.arange(1, m+1).reshape(m, 1)
#X1 = np.zeros((m, 1))
# 将两个向量,水平拓展
X = np.hstack((X0, X1))

# Points y-coordinate
y = np.array([
    3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
    11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)

# 学习率
alpha = 0.01


# 定义均方误差代价函数
def error_function(theta, X, y):
    '''Error function J definition.'''
    diff = np.dot(X, theta) - y
    # 转置相乘diff'*diff 
    return (1./2*m) * np.dot(np.transpose(diff), diff)


# 梯度下降函数,对代价函数求偏导即可
def gradient_function(theta, X, y):
    '''Gradient of the function J definition.'''
    diff = np.dot(X, theta) - y
    # 转置相乘 X'*diff 
    return (1./m) * np.dot(np.transpose(X), diff)


# 梯度下降 
def gradient_descent(X, y, alpha):
    '''Perform gradient descent.'''
    # theta:定义的系数
    theta = np.array([1, 1]).reshape(2, 1)
    gradient = gradient_function(theta, X, y)
    # 终止条件
    # 当梯度小于1e-5时,说明已经进入了比较平滑的状态,
    # 类似于山谷的状态,这时候再继续迭代效果也不大了,
    # 所以这个时候可以退出循环!
    while not np.all(np.absolute(gradient) <= 1e-5):
        theta = theta - alpha * gradient
        gradient = gradient_function(theta, X, y)
    return theta


optimal = gradient_descent(X, y, alpha)
print('optimal::', optimal)
print('error function:', error_function(optimal, X, y)[0,0])

fig = plt.figure()  
ax1 = fig.add_subplot(111)  
#设置标题  
ax1.set_title('Scatter Plot')  
#设置X轴标签  
plt.xlabel('X')  
#设置Y轴标签  
plt.ylabel('Y')  
#画散点图
# X原始图
for i in range(0,20):
        ax1.scatter(X[i,0],X[i,1],c = 'r',marker = 'o')  

# y的实际图 
for n in range(1,21):
    ax1.scatter(n,y[n-1],c = 'b',marker = 'x') 

# 获取的theta值
theta=optimal
y1=np.dot(X, theta)
print(y1)
# 拟合图
for n in range(1,21):
    ax1.scatter(n,y1[n-1],c = 'g',marker = 'v')  
#设置图标  
plt.legend('x1')  
#显示所画的图  
plt.show() 
  • 效果图:
    机器学习实战Chp1: 梯度下降法--python实现_第1张图片

  • 理解及计算过程:
    机器学习实战Chp1: 梯度下降法--python实现_第2张图片

你可能感兴趣的:(机器学习,python)