Preface :
以下為 Machine Learning in Action 第四章內容, 相關代碼可以在 這裡下載 (Ch05).
這一章要提的 Machine Learning 是跟 Optimization algorithms 相關的 Logistic Regression. 而底下是有關這個演算法的描述 :
簡單來說就是我們希望找出一條方程式構成的 hyperplane , 並透過它將標示於座標上不同 class 的 data point group 可以區隔開來. 底下為此 Classification 的簡介 :
Classification with logistic regression :
在開始了解 logistic regression 先要來知道一些常識. 底下為使用 logistic regression 的說明 :
在 logistic regression 中, 我們透過一個函式稱為 sigmoid 來幫我們界定某個 data 的類別, 而該函式的長相如下 :
而上述方程式的 t 實際上為 logistic regression 中 features 值的合. 透過 sigmoid 計算出來的值如果大於 0.5 則歸類為類別 C1 ; 反之則歸類為類別 C2. 而 features 通常會用下面的方程式代表 :
而 x0 到 xn 的值為 input data ; 而我們的目的即是找出最佳的 coefficients w0~wn, 讓計算出來的 t 值套入sigmoid 得到的類別與預期的類別能有最大的相似度.
- Gradient ascent
第一個要接觸的 optimization algorithm 是 Gradient ascent. 詳細的演算法過程不在這裡介紹, 而這邊只說明概念. 考慮下面的式子 :
這個函式的概念就是透過不斷的計算預期值與運算值的差(預期值 - 運算值) :
- Train: Using gradient ascent to find the best parameters
首先我們先來撰寫載入 dataset , 計算 sigmoid 與 plot dataset 的函數 :
- Listing 5.1 (logRegres.py)
接著可以如下畫出 data set 的分布 :
執行後會出現下圖 :
接著是 Gradient ascent algorithm 的實作 :
接著可以如下測試 :
接著有了 weight matrix, 我們便可以計算 sigmoid(), 因為最佳界定類別 C1 與 類別 C2 在 t=0 的位置上故 :
(x1->x ; x2->y)
我們找到分開類別 C1 與 類別 C2 的 hyperplane 的方程式, 接著便可以透過下面函數畫出 logistic regression best-fin line :
接著可以如下測試
產生座標圖如下 :
- Train: stochastic gradient ascent
在使用 Gradient ascent algorithm 可以發現 loop 中的 data set 的每一筆 record 都會被拿來計算 sigmoid(). 這裡的 data set 只有 100 筆所以感覺不出來影響, 在處理大量的 data set (billions), 就會有 performance concern. 因此有另一個替代的 Stochastic gradient ascent algorithm, 一次只拿 data set 的一筆 record 來重新計算 weight matrix, 而透過它當有新的 data set 進來, 我們可以利用已經算好的 weight matrix 繼續往下運算而不用重新計算舊的 data set. 底下為其 pseudo code :
接著底下為其代碼實作 :
但 α(
alpha) 值應該隨著 loop 過程中而變小, 因為 error 會逐漸收斂, 故底下為優化過後的代碼 :
以下為 Machine Learning in Action 第四章內容, 相關代碼可以在 這裡下載 (Ch05).
這一章要提的 Machine Learning 是跟 Optimization algorithms 相關的 Logistic Regression. 而底下是有關這個演算法的描述 :
簡單來說就是我們希望找出一條方程式構成的 hyperplane , 並透過它將標示於座標上不同 class 的 data point group 可以區隔開來. 底下為此 Classification 的簡介 :
Classification with logistic regression :
在開始了解 logistic regression 先要來知道一些常識. 底下為使用 logistic regression 的說明 :
在 logistic regression 中, 我們透過一個函式稱為 sigmoid 來幫我們界定某個 data 的類別, 而該函式的長相如下 :
而上述方程式的 t 實際上為 logistic regression 中 features 值的合. 透過 sigmoid 計算出來的值如果大於 0.5 則歸類為類別 C1 ; 反之則歸類為類別 C2. 而 features 通常會用下面的方程式代表 :
而 x0 到 xn 的值為 input data ; 而我們的目的即是找出最佳的 coefficients w0~wn, 讓計算出來的 t 值套入sigmoid 得到的類別與預期的類別能有最大的相似度.
- Gradient ascent
第一個要接觸的 optimization algorithm 是 Gradient ascent. 詳細的演算法過程不在這裡介紹, 而這邊只說明概念. 考慮下面的式子 :
這個函式的概念就是透過不斷的計算預期值與運算值的差(預期值 - 運算值) :
- Train: Using gradient ascent to find the best parameters
首先我們先來撰寫載入 dataset , 計算 sigmoid 與 plot dataset 的函數 :
- Listing 5.1 (logRegres.py)
- # -*- coding: utf-8 -*-
- from numpy import *
- def plotDataSet(dataArr, labelArr):
- import matplotlib.pyplot as plt
- xcord1 = []; ycord1 = [];
- xcord2 = []; ycord2 = [];
- dataSize = len(dataArr)
- for i in range(dataSize):
- if labelArr[i] == 1:
- xcord1.append(dataArr[i][1]); ycord1.append(dataArr[i][2])
- else:
- xcord2.append(dataArr[i][1]); ycord2.append(dataArr[i][2])
- fig = plt.figure()
- ax = fig.add_subplot(111)
- ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
- ax.scatter(xcord2, ycord2, s=30, c='green')
- plt.show()
- def loadDataSet():
- dataMat = []; labelMat = []
- fr = open('testSet.txt')
- for line in fr.readlines():
- lineArr = line.strip().split()
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
- labelMat.append(int(lineArr[2]))
- return dataMat,labelMat
- def sigmoid(inX):
- return 1.0/(1+exp(-inX))
執行後會出現下圖 :
接著是 Gradient ascent algorithm 的實作 :
- def gradAscent(dataMatIn, classLabels, alpha=0.001, maxCycles=500):
- dataMatrix = mat(dataMatIn) # 轉 list 為 matrix
- labelMat = mat(classLabels).transpose() # 轉 class label list 為 matrix, 並做 transpose
- m,n = shape(dataMatrix) # m 為 data set size ; n 為 features size
- weights = ones((n,1)) # 初始 weight matrix 值為 1.
- for k in range(maxCycles): # for loop 進行 Gradient ascent algorithm 的計算.
- h = sigmoid(dataMatrix*weights) # 計算 t=w0x0 + w1x1 + ... + wnxn. 並將 t 帶入 sigmoid.
- error = (labelMat - h) # 計算 error > exp=1,0 - trt=1,0 = 0 ;
- # exp=1 - trt=0 = 1 (加大 weight) ; exp=0 - trt=1 = -1 縮小 weight)
- weights = weights + alpha * dataMatrix.transpose()* error # 重新計算 weight matrix
- return weights
接著有了 weight matrix, 我們便可以計算 sigmoid(), 因為最佳界定類別 C1 與 類別 C2 在 t=0 的位置上故 :
(x1->x ; x2->y)
我們找到分開類別 C1 與 類別 C2 的 hyperplane 的方程式, 接著便可以透過下面函數畫出 logistic regression best-fin line :
- def plotBestFit(weights):
- import matplotlib.pyplot as plt
- dataMat,labelMat=loadDataSet()
- dataArr = array(dataMat)
- n = shape(dataArr)[0]
- xcord1 = []; ycord1 = []
- xcord2 = []; ycord2 = []
- for i in range(n):
- if int(labelMat[i])== 1:
- xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
- else:
- xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
- fig = plt.figure()
- ax = fig.add_subplot(111)
- ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
- ax.scatter(xcord2, ycord2, s=30, c='green')
- x = arange(-3.0, 3.0, 0.1)
- y = (-weights[0]-weights[1]*x)/weights[2]
- ax.plot(x, y)
- plt.xlabel('X1'); plt.ylabel('X2');
- plt.show()
產生座標圖如下 :
- Train: stochastic gradient ascent
在使用 Gradient ascent algorithm 可以發現 loop 中的 data set 的每一筆 record 都會被拿來計算 sigmoid(). 這裡的 data set 只有 100 筆所以感覺不出來影響, 在處理大量的 data set (billions), 就會有 performance concern. 因此有另一個替代的 Stochastic gradient ascent algorithm, 一次只拿 data set 的一筆 record 來重新計算 weight matrix, 而透過它當有新的 data set 進來, 我們可以利用已經算好的 weight matrix 繼續往下運算而不用重新計算舊的 data set. 底下為其 pseudo code :
接著底下為其代碼實作 :
- def stocGradAscent0(dataMatrix, classLabels):
- m,n = shape(dataMatrix)
- alpha = 0.01
- weights = ones(n) #initialize to all ones
- for i in range(m):
- h = sigmoid(sum(dataMatrix[i]*weights))
- error = classLabels[i] - h
- weights = weights + alpha * error * dataMatrix[i]
- return weights
- def stocGradAscent1(dataMatrix, classLabels, numIter=150):
- m,n = shape(dataMatrix)
- weights = ones(n) #initialize to all ones
- for j in range(numIter):
- dataIndex = range(m)
- for i in range(m):
- alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not
- randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
- h = sigmoid(sum(dataMatrix[randIndex]*weights))
- error = classLabels[randIndex] - h
- weights = weights + alpha * error * dataMatrix[randIndex]
- del(dataIndex[randIndex])
- return weights
沒有留言:
張貼留言