Regularized Logistic Regression(Octave轉換爲Python)

詳細代碼參考github

Regularized Logistic Regression

實例:
建立Regularized Logistic Regression模型,預測微型集成芯片能否通過質量保證(QA)。我們有芯片兩次不同的測試結果,要通過建立的模型預測處理器是否能夠通過QA。

1.可視化數據

數據爲118組芯片兩次測試情況以及測試的結果,維度爲(118,3)結果爲1,通過,用“+”表示,否則不通過, 用“·”表示,從圖中可以看出,無法用一條直線將兩種結果區分開來,普通的邏輯迴歸無法解決該問題。
可視化
參考代碼:

def plotData(self):
    y1_index = np.where(self.y == 1.0)
    x1 = self.x[y1_index[0]]
    y0_index = np.where(self.y == 0.0)
    x0 = self.x[y0_index[0]]
    plt.scatter(x1[:, 0], x1[:, 1], marker='+', color='k')
    plt.scatter(x0[:, 0], x0[:, 1], color='y')
    plt.legend(['y = 1', 'y = 0'])
    plt.xlabel('Microchip Test 1')
    plt.ylabel('Microchip Test 2')
    # plt.show()
2.Feature mapping

通過數據分佈,單純的一條直線解決不了問題,我們嘗試用兩種測試結果的多項式形式來處理,最高6次冪,這樣邊界將是一條曲線,如果多項式的最高次冪太高的話,容易過擬合,太低的話容易欠擬合,通過mapFeature函數,將2組特徵數據,轉換爲28組特徵數據,其中第一組數據是1,其餘數據按照下式生成。

參考代碼:

def mapFeature(self, x1, x2):
   	# 生成多項式
   	out = np.ones((x1.shape[0], 1))
   	for i in range(6):
   		for j in range(i+2):
   			out = np.hstack([out, (x1**(i+1-j)*(x2**j))])
   	return out
3.損失函數和梯度

同普通的邏輯迴歸一樣,只不過多了一部分正則化項,公式如下,容易忽略的地方,參數theta0是不需要正則化的,故下標是從1開始。

損失函數的梯度公式,分爲兩部分,同樣theta0不需要正則化。


參考代碼:

def costFunctionReg(self, theta, lanmda):
   	m = self.y.shape[0]
   	J = (-np.dot(self.y.T, np.log(self.sigmoid(self.map_x.dot(theta))))-np.dot((1-self.y).T, np.log(1-self.sigmoid(self.map_x.dot(theta))))) / m+ (lanmda*np.sum(theta[1::]**2, axis=0))/(2*m)  # 正則化從j = 1開始
   	return J

def gradient(self, theta, lanmd):
   	m = self.y.shape[0]
   	theta = theta.reshape((self.map_x.shape[1], 1))
   	grad = np.zeros((self.map_x.shape[1], 1))
   	grad[0] = np.dot(self.map_x[:, 0:1].T, (self.sigmoid(self.map_x.dot(theta))-self.y)) / m
   	grad[1::] = np.dot(self.map_x[:, 1::].T, (self.sigmoid(self.map_x.dot(theta))-self.y)) / m + lanmd*theta[1::] / m
   	# grad = np.dot(self.map_x.T, (self.sigmoid(self.map_x.dot(theta)) - self.y)) / m
   	return grad
4.求解最優的theta

同樣使用scipy.optimize中的minimize函數,注意參數的數量,在梯度和損失函數定義的兩個函數中,傳入參數爲2個,故minimize函數使用args=()參數
參考代碼:

def fminunc(self):  # costFunction需要幾個參數就傳幾個,本例有兩個,x0,利用args=(100, )
	optiTheta = op.minimize(fun=self.costFunctionReg, x0=np.zeros((28, )), args=(100, ), method='TNC', jac=self.gradient)
		return optiTheta  # dict

這裏出現一個問題:當設置lambda值爲0.1、1、10、100時均可求出最優theta,但當lambda=0時,始終返回failure,找不到最優解,有大神看到還請幫忙解答。

5.繪製決策邊界

按照設置的lambda值,生成了四個結果。原試驗中還有lambda=0的情況,但上面求解函數中求不到值,把原octave試驗結果貼出來,放在一起便於分析。
清楚的看出來,當lambda較小的時候,邊界可以將訓練數據很好的分開,但是邊界非常複雜,明顯的過擬合;當lamda=100的時候,得到了偏移很多的決策邊界,沒能很好的區分,欠擬合,找到較爲的合適的lambda值,是求得較好結果的關鍵。
在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

5.lambda值

貼出吳老師用手注靈魂的PPT,當lambda很大很大的時候,要最小化J,所有的theta就會很小很小,約等於0,那麼求出來的h(theta)函數就近似一條直線,結果欠擬合;lambda很小的時候,正則化項幾乎不起作用,不能很好的處理過擬合。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章