A-05 前向選擇法和前向梯度法

更新、更全的《機器學習》的更新網站,更有python、go、數據結構與算法、爬蟲、人工智能教學等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlpython

前向選擇法和前向梯度法

因爲前向選擇法和前向梯度法的實現原理涉及過多的矩陣運算,本文只給出兩種算法的思路。二者實現都是把矩陣中的向量運算具體化成平面幾何中的向量運算。算法

1、前向選擇法

前向選擇法是一種典型的貪心算法。數據結構

一般用前向選擇法解決線性模型的迴歸係數。對於一個有\(m\)個樣本,每一個樣本有\(n\)個特徵的訓練集而言,假設能夠擬合一個線性模型\(Y=\omega^TX\),其中\(Y\)\(m*1\)的向量,\(X\)\(m*n\)的矩陣,\(\omega\)\(n*1\)的向量。便可經過前向選擇法求得最小化該模型的參數\(\omega\)機器學習

1.1 餘弦類似度求投影

首先把矩陣\(X\)當作\(n\)\(m*1\)的向量\(X_i \quad(i=1,2,\cdots,n)\),以後選擇與向量\(Y\)餘弦類似度最大,即與\(Y\)最爲接近的一個變量\(X_i\),而後用\(X_i\)逼近\(Y\),便可獲得
\[ \hat{Y}=X_i\omega_i \]
其中\(\omega_i={\frac{<X_i,Y>}{{||X_i||}^2}}\quad\text{餘弦類似度}\),其中\(<X_i,Y>=|Y|*\cos\alpha\)\(\alpha\)\(X_i\)\(Y\)的夾角。學習

上述公式所以能夠認爲\(\hat{Y}\)\(Y\)\(X_i\)上的投影。網站

獲得\(Y\)的接近值\(\hat{Y}\)後既能夠獲得殘差值爲\(Y_{err}=Y-\hat{Y}\),因爲\(\hat{Y}\)是投影,則\(\hat{Y}\)\(X_i\)是正交的,所以能夠以\(Y_{err}\)爲新的變量,從剩下的\(X_i\quad(i=1,2,i-1,i+2,\cdots,n)\)中,選擇一個新的最接近殘差\(Y_{err}\)\(X_i\)重複上述投影和計算殘差的流程,直至殘差爲0,中止算法。便可獲得\(\omega\)人工智能

1.2 舉例

# 舉例圖例
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')

# X1*w1
plt.annotate(xytext=(2, 5), xy=(8, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(6, 4.5, s='$X_1*\omega_1$', color='g')
# X2*w2
plt.annotate(xytext=(8, 5), xy=(9.3, 7.5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(9.3, 7, s='$X_2*\omega_2$', color='g')
# X1
plt.annotate(xytext=(2, 5), xy=(4, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2.5, 4.5, s='$X_1$', color='g')
# X2
plt.annotate(xytext=(2, 5), xy=(3, 7), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2, 6, s='$X_2$', color='g')
# X2
plt.annotate(xytext=(8, 5), xy=(9, 7), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(8.2, 6.5, s='$X_2$', color='g')
# Y
plt.annotate(xytext=(2, 5), xy=(8, 8), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5, 7.5, s='$Y$', color='g')
#
plt.annotate(xytext=(8, 5), xy=(8, 8), s='', color='r',
             arrowprops=dict(arrowstyle="-", color='gray'))
plt.text(7.5, 6.5, s='$Y_1$', color='g')
#
plt.annotate(xytext=(8, 8), xy=(9.3, 7.5), s='',
             arrowprops=dict(arrowstyle="-", color='gray'))
plt.text(8.5, 8, s='$Y_2$', color='g')

plt.xlim(0, 11)
plt.ylim(2, 10)
plt.title('前向選擇法舉例', fontproperties=font, fontsize=20)
plt.show()

png

上圖假設\(X\)\(2\)維,首先能夠看出,離\(Y\)最接近的是\(X_1\),所以畫出\(Y\)\(X_1\)上的投影紅線\(X_1*\omega_1\),此時殘差爲灰線\(Y_1\)。因爲目前只剩下\(X_2\),因此接着用殘差\(Y_1\)\(X_2\)上投影獲得紅線\(X_2*\omega_2\),若是不僅是\(X_2\),則選擇最接近\(Y_1\)\(X_i\)。此時的\(X_1\omega_1+X_2\omega_2\)則模擬了\(Y\),即\(\omega=[\omega_1,\omega_2]\)spa

1.3 前向選擇法優缺點

1.3.1 優勢

  1. 算法對每一個\(X_i\)只作一次操做,速度快。

1.3.2 缺點

  1. 因爲變量\(X_i\)之間不是正交的,因此每次都必須作投影縮小殘差,因此前向選擇法最後只能給出一個局部近似解。(能夠考慮下面的前向梯度法)

2、前向梯度法

前向梯度法相似於前向選擇法,不一樣之處在於前向梯度法廢除了前向選擇法的投影逼近\(Y\),取而代之的是在每次最接近\(Y\)的向量\(X_i\)的方向上移動一小步,而且向量\(X_i\)移動會不會被剔除,而是繼續從\(X_i \quad(i=1,2,i-1,i,i+1,\cdots,n)\)中選擇一個最接近殘差\(Y_{err}\)(注:殘差計算方式相似於前向選擇法)的向量\(X_i\),而後再走一小步,直至殘差爲0,中止算法,便可獲得\(\omega\)code

2.1 舉例

# 舉例圖例
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')

# X1
plt.annotate(xytext=(2, 5), xy=(3, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(2.4, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(4, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(3.2, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(5, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(4.2, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(2.8, 5), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(1.9, 4.8, s='$X_1$', color='g')
# eX1
plt.annotate(xytext=(6.1, 6.2), xy=(7, 6.2), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(6.2, 6, s='$\epsilon{X_1}$', color='g')

# ex2
plt.annotate(xytext=(5, 5), xy=(6.2, 6.2), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='r'))
plt.text(5.2, 5.8, s='$\epsilon{X_2}$', color='g')
# X2
plt.annotate(xytext=(2, 5), xy=(3, 6), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2, 5.5, s='$X_2$', color='g')
# X2
plt.annotate(xytext=(5, 5), xy=(6, 6), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5.6, 5.5, s='$X_2$', color='g')

# Y
plt.annotate(xytext=(2, 5), xy=(8, 7), s='', color='r',
             arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5, 6.2, s='$Y$', color='g')

plt.annotate(xytext=(5, 5), xy=(8, 7), s='', color='r',
             arrowprops=dict(arrowstyle="-", color='gray'))

plt.xlim(1, 9)
plt.ylim(4, 8)
plt.title('前向梯度法舉例', fontproperties=font, fontsize=20)
plt.show()

png

上圖假設\(X\)\(2\)維,首先能夠看出,離\(Y\)最接近的是\(X_1\),所以沿着向量\(X_i\)的方向走上一段距離,此處的\(\epsilon\)是一個手動調整的超參數,走了一段距離後發現,離殘差\(Y_{err}\)最近接的仍是\(X_1\),所以繼續接着走一段距離,直到走到離殘差\(Y_{err}\)最近的爲\(X_2\)的時候,沿着向量\(X_2\)的方向走上一段距離,發現此時殘差\(Y_{err}\)\(X_1\)更近,則沿着\(X_1\)走一段距離,直到走到最後殘差爲0,中止算法,便可獲得\(\omega\)

2.2 前向梯度法優缺點

2.2.1 優勢

  1. 能夠手動控制\(\epsilon\)的大小,便可以控制算法的精準度,若是\(\epsilon\)較小的時候算法精準度很高

2.2.2 缺點

  1. \(\epsilon\)小,算法精準度高,同時算法迭代次數增長;\(\epsilon\)大,算法精準度下降。相似於梯度降低,這是前向梯度法較大的一個問題。(參考最小角迴歸法)
相關文章
相關標籤/搜索