邏輯迴歸的講解和程式碼
阿新 • • 發佈:2018-12-17
邏輯迴歸模型是由以下條件概率分佈表示的分類模型。
邏輯迴歸模型源自邏輯分佈,其分佈函式使S形函式;
邏輯迴歸:用於分類問題中,預測值為離散值;演算法的性質是輸出值永遠在0和1之間;
邏輯迴歸的模型假設:,
h(x)的作用:對於給定的輸入變數,根據選擇的引數計算輸出變數=1的可能性,
代價函式:
梯度下降演算法:
高階優化演算法:共軛梯度法、BFGS變尺度法、L-BFGS限制變尺度法、fminunc無約束最小化函式
正則化:保留所有的特徵,減小引數的大小;
其中lamda是正則化引數,lamda越大,引數越小。因為需要最小化代價函式,但是加上了尾部的這一部分,尾部越大,則整個代價函式越大,則theta越小,才能保證最小的代價函式。
程式碼部分,最重要的是實現代價函式和sigmoid函式。
import matplotlib.pyplot as plt import numpy as np import scipy.optimize as opt from plotData import * import costFunctionReg as cfr import plotDecisionBoundary as pdb import predict as predict import mapFeature as mf plt.ion() # Load data # The first two columns contain the exam scores and the third column contains the label. data = np.loadtxt('ex2data2.txt', delimiter=',') X = data[:, 0:2] y = data[:, 2] plot_data(X, y) plt.xlabel('Microchip Test 1') plt.ylabel('Microchip Test 2') plt.legend(['y = 1', 'y = 0']) input('Program paused. Press ENTER to continue') # ===================== Part 1: Regularized Logistic Regression ===================== X = mf.map_feature(X[:, 0], X[:, 1]) # Initialize fitting parameters initial_theta = np.zeros(X.shape[1]) # Set regularization parameter lambda to 1 lmd = 1 # Compute and display initial cost and gradient for regularized logistic regression cost, grad = cfr.cost_function_reg(initial_theta, X, y, lmd) np.set_printoptions(formatter={'float': '{: 0.4f}\n'.format}) print('Cost at initial theta (zeros): {}'.format(cost)) print('Expected cost (approx): 0.693') print('Gradient at initial theta (zeros) - first five values only: \n{}'.format(grad[0:5])) print('Expected gradients (approx) - first five values only: \n 0.0085\n 0.0188\n 0.0001\n 0.0503\n 0.0115') input('Program paused. Press ENTER to continue') # Compute and display cost and gradient with non-zero theta test_theta = np.ones(X.shape[1]) cost, grad = cfr.cost_function_reg(test_theta, X, y, lmd) print('Cost at test theta: {}'.format(cost)) print('Expected cost (approx): 2.13') print('Gradient at test theta - first five values only: \n{}'.format(grad[0:5])) print('Expected gradients (approx) - first five values only: \n 0.3460\n 0.0851\n 0.1185\n 0.1506\n 0.0159') input('Program paused. Press ENTER to continue') # ===================== Part 2: Regularization and Accuracies ===================== # Optional Exercise: # In this part, you will get to try different values of lambda and # see how regularization affects the decision boundary # # Try the following values of lambda (0, 1, 10, 100). # # How does the decision boundary change when you vary lambda? How does # the training set accuracy vary? # # Initializa fitting parameters initial_theta = np.zeros(X.shape[1]) # Set regularization parameter lambda to 1 (you should vary this) lmd = 1 # Optimize def cost_func(t): return cfr.cost_function_reg(t, X, y, lmd)[0] def grad_func(t): return cfr.cost_function_reg(t, X, y, lmd)[1] theta, cost, *unused = opt.fmin_bfgs(f=cost_func, fprime=grad_func, x0=initial_theta, maxiter=400, full_output=True, disp=False) #使用的是優化庫函式裡面的牛頓法 # Plot boundary print('Plotting decision boundary ...') pdb.plot_decision_boundary(theta, X, y) plt.title('lambda = {}'.format(lmd)) plt.xlabel('Microchip Test 1') plt.ylabel('Microchip Test 2') # Compute accuracy on our training set p = predict.predict(theta, X) print('Train Accuracy: {:0.4f}'.format(np.mean(y == p) * 100)) print('Expected accuracy (with lambda = 1): 83.1 (approx)') input('ex2_reg Finished. Press ENTER to exit') import numpy as np from sigmoid import * def cost_function_reg(theta, X, y, lmd): m = y.size hypothesis = sigmoid(np.dot(X, theta)) reg_theta = theta[1:] cost = np.sum(-y * np.log(hypothesis) - (1 - y) * np.log(1 - hypothesis)) / m \ + (lmd / (2 * m)) * np.sum(reg_theta * reg_theta) normal_grad = (np.dot(X.T, hypothesis - y) / m).flatten() grad[0] = normal_grad[0] grad[1:] = normal_grad[1:] + reg_theta * (lmd / m) # =========================================================== return cost, grad import matplotlib.pyplot as plt import numpy as np from plotData import * from mapFeature import * def plot_decision_boundary(theta, X, y): plot_data(X[:, 1:3], y) if X.shape[1] <= 3: # Only need two points to define a line, so choose two endpoints plot_x = np.array([np.min(X[:, 1]) - 2, np.max(X[:, 1]) + 2]) # Calculate the decision boundary line plot_y = (-1/theta[2]) * (theta[1]*plot_x + theta[0]) plt.plot(plot_x, plot_y) plt.legend(['Decision Boundary', 'Admitted', 'Not admitted'], loc=1) plt.axis([30, 100, 30, 100]) else: # Here is the grid range u = np.linspace(-1, 1.5, 50) v = np.linspace(-1, 1.5, 50) z = np.zeros((u.size, v.size)) # Evaluate z = theta*x over the grid for i in range(0, u.size): for j in range(0, v.size): z[i, j] = np.dot(map_feature(u[i], v[j]), theta) z = z.T # Plot z = 0 # Notice you need to specify the range [0, 0] cs = plt.contour(u, v, z, levels=[0], colors='r', label='Decision Boundary') plt.legend([cs.collections[0]], ['Decision Boundary']) import numpy as np def map_feature(x1, x2): degree = 6 x1 = x1.reshape((x1.size, 1)) x2 = x2.reshape((x2.size, 1)) result = np.ones(x1[:, 0].shape) for i in range(1, degree + 1): for j in range(0, i + 1): result = np.c_[result, (x1**(i-j)) * (x2**j)] return result import matplotlib.pyplot as plt import numpy as np def plot_data(X, y): plt.figure() pos = np.where(y == 1)[0] #輸出滿足條件的座標 neg = np.where(y == 0)[0] plt.scatter(X[pos, 0], X[pos, 1], marker="+", c='b') plt.scatter(X[neg, 0], X[neg, 1], marker="o", c='y') import numpy as np from sigmoid import * def predict(theta, X): m = X.shape[0] p = np.zeros(m) p = sigmoid(np.dot(X, theta)) pos = np.where(p >= 0.5) neg = np.where(p < 0.5) p[pos] = 1 p[neg] = 0 # =========================================================== return p import numpy as np def sigmoid(z): g = np.zeros(z.size) g = 1 / (1 + np.exp(-z)) return g