trybeetle

take it slow!!

Logistic regressionについて


Posted on July 17, 2018, 10:19 a.m.



Logistic Regressionの導入方法について記載します。 
CourseraのMachine Learningコースを元にしています。

Logistic Regressionは、regressionとなっていますが、部類で言うとclassificationモデルです。スパムメールフィルタであるように是か非かを判断するものです。


トレーニングデータの読み込み

まずは、トレーニングデータのDatasetを読み込みます。Xをfeatureとし、yをlabelとします。mはDatasetの数。Datasetの内容としては、Exam1の点数、Exam2の点数、合否の結果(0が不合格、1が合格)です。(例:60,86,1)


%% Load Data
data = load('ex2data1.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);

データがどのように分散しているかグラフ化し確認します。


% plotData関数の定義
function plotData(X, y)
figure; hold on;
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);
xlabel('Exam 1 score')
ylabel('Exam 2 score')
legend('Admitted', 'Not admitted')
hold off;
end

% 関数の実行
plotData(X, y);

hypotehsisは、0と1の結果を得るために、h = g(z) のsigmoid関数を想定しています。また、z = θ0*X0 + θ1*X1 + θ2*X2 とします。(θ0はバイアスのため、X0 = 1となるように、matrix Xの左列に1を追加します。)


X = [ones(m, 1) X];

Cost functionの定義

まず、m(training dataset数)、n(feature数)、thetaの初期値を定めます。


[m, n] = size(X);
theta = zeros(n, 1);

今回は、classificationの問題のため、hypothesisの値を0 or 1で求めます。そのため、sigmoid関数を使用します。
下記の様にhypothesisを定義します。


function g = sigmoid(z)
g = zeros(size(z));
g = 1 ./ (1 + e.^-z);
end

続いて、cost functionを定義します。


% costFunction関数の定義
function [J, grad] = costFunction(theta, X, y)
m = length(y); % number of training examples
J = 0;
grad = zeros(size(theta));
h_theta = sigmoid(X * theta);
J = 1/m * ((-y' * log(h_theta)) - ((1 - y)' * log(1 - h_theta)));
grad = 1/m * ((h_theta - y)' * X)';
end

fminuncによる最適化

octaveのfminunc関数を使用し、θの値を最適化します。
fminuncのオプションを指定し、実行します。


options = optimset('GradObj', 'on', 'MaxIter', 400);
[theta, cost] = fminunc(@(t)(costFunction(t, X, y)), theta, options);

Decision Boundaryの表示

上記で求めたθで、0と1の境界線を表示させます。


% plotDecisionBoundary関数の定義
function plotDecisionBoundary(theta, X, y)
plotData(X(:,2:3), y);
hold on
if size(X, 2) <= 3
    % Only need 2 points to define a line, so choose two endpoints
    plot_x = [min(X(:,2))-2,  max(X(:,2))+2];

    % Calculate the decision boundary line
    plot_y = (-1./theta(3)).*(theta(2).*plot_x + theta(1));

    % Plot, and adjust axes for better viewing
    plot(plot_x, plot_y)

    % Legend, specific for the exercise
    legend('Admitted', 'Not admitted', 'Decision Boundary')
    axis([30, 100, 30, 100])
else
    % Here is the grid range
    u = linspace(-1, 1.5, 50);
    v = linspace(-1, 1.5, 50);

    z = zeros(length(u), length(v));
    % Evaluate z = theta*x over the grid
    for i = 1:length(u)
        for j = 1:length(v)
            z(i,j) = mapFeature(u(i), v(j))*theta;
        end
    end
    z = 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)
endif
xlabel('Exam 1 score')
ylabel('Exam 2 score')
legend('Admitted', 'Not admitted')
hold off
end

% 関数の実行
plotDecisionBoundary(theta, X, y);

確認

exam1が45点、exam2が85点の場合の、合否を予測します。


prob = sigmoid([1 45 85] * theta);

また、このモデルのaccuracyは下記の様に求めます。


% predict関数の定義
function accuracy = predict(theta, X, y)
m = size(X, 1); % Number of training examples
p = round(sigmoid(X * theta));
accuracy = mean(double(p == y)) * 100;
end

% 関数の実行
accuracy = predict(theta, X, y);

補足

上記の例は、0 or 1判定のbinary classificationでした。Multi classificationの場合にも上記と同様に求めます。
その際には、one-vs-restをclass数分だけ繰り返します。(例えば、3つのclass A,B,Cに分ける場合には、A-vs-BC, B-vs-AC, C-vs-AB、となるようにbinary classificationを3回繰り返します。)
繰り返し、最もhypothesisの値が高かったclassに分類します。

以上、logistic regressionについてでした。


Category:ML
Tag: ML Octave
July 17, 2018, 10:19 a.m.

Comments