基于Octave/Matlab的二元逻辑回归(logistic regression)算法
基于Octave/Matlab的二元邏輯回歸(logistic regression)算法
本博文基于吳恩達老師的機器學習網課,是對作業代碼進行簡化和補充完整后的實現。
邏輯回歸算法的基本思想
sigmoid函數
在分類問題中,我們需要根據變量x來確定變量y的種類(離散的值),這種分類問題的算法稱之為邏輯回歸算法。在最簡單的二元邏輯分類問題中,我們將y分為兩類,并分別賦值0和1來區分。0表示負向類,1表示正向類。
我們需要計算出一個函數h(x),用來預測y的值,這里我們用到sigmoid函數:
上圖中g(z)即為sigmoid函數,當z>0時g(z)>0.5;當z<0時,g(z)<0.5 。 而z = theta‘*X , 所以當 theta’*X大于等于0時,預測y為1;反之為零。
和之前提到過的線性回歸相類似,這里的theta仍然是一個系數的列矩陣,而X則稍有不同,是一個可以存在多項式的X矩陣。
代價函數
在這個問題中,與線性回歸不同的是我們需要重新定義代價函數來更好的貼合這個問題的本質特性。
這樣可以發現,當預測值與實際值不符的情況下,代價函數將會反饋趨于無窮大的值;而如果預測值與實際值相符,則代價函數返回零值。
在這里我們仍然可以使用梯度下降法來求代價函數的最小值所對應的theta,算法的基礎思想如下:
由于h(x)的定義和之前的線性回歸的定義不同,所以雖然形式與之前的線性回歸相類似,但實際上是有所不同的。
fminunc函數
除梯度下降算法之外,還有一些常被用來令代價函數最小的算法,fminunc是Octave和matlab中都帶的一個最小值優化函數,使用時我們需要提供代價函數和每個參數的求導。
在octave中使用fminunc函數的示例如下:
二元線性邏輯回歸的算法實現
主函數:
clear; close all; clc data = load('ex2data1.txt'); X = data(:,[1,2]); y = data(:,3); %X代表數據的兩個變量,y是是否被錄取%畫實例圖 fprintf(['ploting...']); plotData(X,y); %調用plotData函數來繪制不同錄取結果的實例圖 hold on ; xlabel('exam1_score'); ylabel('exam2_score'); legend('admitted','unadmitted'); hold off;%計算代價和梯度 [m , n] = size(X); X = [ones(m,1) , X]; %在X的矩陣左側加一行代表X0的1 initial_theta = zeros(n + 1 , 1); %初始化theta值為0 ,且因為X矩陣加了一列, 所以theta矩陣也要增加一行 [cost, grad] = costFunction(initial_theta , X , y); %計算初始theta值情況下的代價函數和梯度值 fprintf('the cost by initial_theta is: %f\n',cost); fprintf('the grad by initial_theta is: %f\n',grad);%用fminunc函數來優化theta值 options = optimset('Gradobj','on','MaxIter',400); [theta, cost] = ...fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);%用fminunc函數來計算最優的theta值和相應的cost fprintf('theta found by fminunc: %f\n',theta); fprintf('cost at the theta found by fminunc: %f\n',cost);%畫出分界線 plotDecisionBoundary(theta,X,y); %調用plotDecisionBoundary函數來畫出分界線 hold on; xlabel('exam1_score'); ylabel('exam2_score'); legend('Admitted', 'Not admitted') hold off;%預測具體情況和計算準確度 prob = sigmoid([1 45 85] * theta); fprintf(['For a student with scores 45 and 85, we predict an admission ' ...'probability of %f\n\n'], prob); p = predict(theta, X); fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);PlotData函數:(用于繪制實例數據)
function plotData(X, y) pos = find(y==1); neg = find(y == 0);plot(X(pos, 1), X(pos, 2), 'k+','LineWidth', 2, 'MarkerSize', 7); plot(X(neg, 1), X(neg, 2), 'ko', 'MarkerFaceColor', 'y', 'MarkerSize', 7); hold off; endCostFunction函數:(計算代價函數)
function [J, grad] = costFunction(theta, X, y) m = length(y); % number of training examplesJ = 0; grad = zeros(size(theta)); J = (1 / m) * sum( -y'*log(sigmoid(X*theta)) - (1-y)'*log( 1 - sigmoid(X*theta)) ); grad = (1 / m) * sum( X .* repmat((sigmoid(X*theta) - y), 1, size(X,2)) );endPlotDecisionBoundary函數:(繪制回歸邊界)
function plotDecisionBoundary(theta, X, y) plotData(X(:,2:3), y); hold onif size(X, 2) <= 3% Only need 2 points to define a line, so choose two endpointsplot_x = [min(X(:,2))-2, max(X(:,2))+2];% Calculate the decision boundary lineplot_y = (-1./theta(3)).*(theta(2).*plot_x + theta(1));% Plot, and adjust axes for better viewingplot(plot_x, plot_y)% Legend, specific for the exerciselegend('Admitted', 'Not admitted', 'Decision Boundary')axis([30, 100, 30, 100]) else% Here is the grid rangeu = linspace(-1, 1.5, 50);v = linspace(-1, 1.5, 50);z = zeros(length(u), length(v));% Evaluate z = theta*x over the gridfor i = 1:length(u)for j = 1:length(v)z(i,j) = mapFeature(u(i), v(j))*theta;endendz = z'; % important to transpose z before calling contour% Plot z = 0% Notice you need to specify the range [0, 0]contour(u, v, z, [0, 0], 'LineWidth', 2) end hold offendPredict函數:(預測未知x所對應的y)
function p = predict(theta, X) p = sigmoid(X * theta)>=0.5 ;end運行結果
上圖是運行plotData函數的結果,可以發現實例中有兩類結果,分別是被錄取和沒有被錄取的。
上圖是運行PlotDecisionBoundary函數的結果,可見在這里兩種實例被一條直線分開,基本實現了分類。
帶正則化的二元回歸
基本思想
由于實際問題中大部分的分類問題不能簡單的用線性來分類,所以在回歸曲線中引入高次項來更好的貼合分界曲線是有必要的。但高次項的引入會導致過擬合(overfitting)的問題,即得到的曲線過于貼合已有實例而不能很好的適應添加進判定系統的新實例。
過擬合的問題一般是由于高次項的參數偏大,導致判定曲線過于曲折。但如果去除高次項會導致欠擬合,如上圖所示,左側為欠擬合(underfitting),右側為過擬合(overfitting)。所以這里采用折中的辦法——正則化。即保留所有的特征,但是減少參數的大小。
正則化的具體操作是在原有的代價函數上做一定的修改,正則化的代價函數為:
這樣就將參數加入了代價函數,這樣做的結果是隨著代價函數的更新,高次項的參數也會相應的減小以使代價函數減小。
這樣,減小代價函數的算法就變成了:
在接下來的實現過程中,實際的求取最優theta值的過程仍然是使用fminunc函數。
算法實現
主函數
clear ; close all; clc%% Load Data data = load('ex2data2.txt'); X = data(:, [1, 2]); y = data(:, 3);plotData(X, y);% Put some labels hold on;% Labels and Legend xlabel('Microchip Test 1') ylabel('Microchip Test 2')% Specified in plot order legend('y = 1', 'y = 0') hold off;%% =========== Part 1: Regularized Logistic Regression ============ X = mapFeature(X(:,1), X(:,2));% Initialize fitting parameters initial_theta = zeros(size(X, 2), 1);% Set regularization parameter lambda to 1 lambda = 1;% Compute and display initial cost and gradient for regularized logistic % regression [cost, grad] = costFunctionReg(initial_theta, X, y, lambda);fprintf('Cost at initial theta (zeros): %f\n', cost);%% ============= Part 2: Regularization and Accuracies =============% Initialize fitting parameters initial_theta = zeros(size(X, 2), 1);% Set regularization parameter lambda to 1 (you should vary this) lambda = 1;% Set Options options = optimset('GradObj', 'on', 'MaxIter', 400);% Optimize [theta, J, exit_flag] = ...fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options);% Plot Boundary plotDecisionBoundary(theta, X, y); hold on; title(sprintf('lambda = %g', lambda))% Labels and Legend xlabel('Microchip Test 1') ylabel('Microchip Test 2')legend('y = 1', 'y = 0', 'Decision boundary') hold off;% Compute accuracy on our training set p = predict(theta, X);fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);正則化代價函數
function [J, grad] = costFunctionReg(theta, X, y, lambda) m = length(y); % number of training examplesJ = 0; grad = zeros(size(theta));J = ( (1 / m) * sum(-y'*log(sigmoid(X*theta)) - (1-y)'*log( 1 - sigmoid(X*theta))) ) + (lambda/(2*m))*sum(theta(2:length(theta)).*theta(2:length(theta))) ;grad = (1 / m) * sum( X .* repmat((sigmoid(X*theta) - y), 1, size(X,2)) );grad(:,2:length(grad)) = grad(:,2:length(grad)) + (lambda/m)*theta(2:length(theta))'; end運行結果
這是本算法用到的實例的繪制
采用正則化,可以擬合出較為準確的判定邊界。
這里應注意,算法要求設置不同的lambda值,這里僅呈現效果最好的lambda=1的情況,其他的情況擬合效果欠佳。
至此就是二元邏輯回歸算法的基本內容。
總結
以上是生活随笔為你收集整理的基于Octave/Matlab的二元逻辑回归(logistic regression)算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Allegro-默认打开空白PCB文件
- 下一篇: 厂房 安全等级四色图 且可修改