MATLAB でロジスティック回帰分類を実装しようとしていますが、勾配降下法を使用して正しい重みを計算することに固執しています。
私は確率論的アプローチを使用しているので、重みのベクトル内の各重みを特徴ごとに個別に更新してから、次のサンプルに移動してもう一度行います。
更新方程式を使用しています
theta_j := theta_j - alpha * (y_i - h_theta(x_i)) * x_ij
そして、最後の重みベクトルと現在の重みベクトルの差が 0.00005 未満になると中断します。2 つのベクトルの「差」を計算するには、一方を他方から引き、差ベクトルの内積の平方根をとります。
問題は、4 回の更新だけで更新が停止するように見えるため、8 行の重みベクトルの最初の 4 つだけがまったく更新されないことです。これは、私の学習率 (アルファ) に関係なく発生します。
これが私の実装です:
function weightVector = logisticWeightsByGradientDescentStochastic(trueClass,features)
%% This function attemps to converge on the best set of weights for a logistic regression order 1
%% Input:
% trueClass - the training data's vector of true class values
% features
%% Output:
% weightVector - vector of size n+1 (n is number of features)
% corresponding to convergent weights
%% Create one vector and append to features
oneVector = ones( size(features,1) , 1); %create one vector to append to features
regressData = horzcat(oneVector, features); % create dataset that we will use to calculate regression weights
%% Get Data Size
dataSize = size(regressData);
%% Initial pick for weightVector
weightVector = rand( dataSize(2), 1); %create a zero vector equal to size of regressData
weightVector = 100.*weightVector
%% Choose learning Rate
learningRate = 1000;
%% Stochastic Gradient Descent
oldWeightVector = weightVector; %set oldWeightVector
newWeightVector = oldWeightVector; % pre-allocate size for newWeightVector
difference = Inf; %initial difference to get into loop
iterCount = 0; %for testing to see how long it takes
while(difference > 0.000005)
for m=1:dataSize(1) %for all samples
for n=1:dataSize(2) %for all features
%% calculate Sigmoid predicted
predictedClass = evaluateSigmoid(oldWeightVector, regressData(m,:))
%% Calculate the error
error = learningRate .* (trueClass(m) - predictedClass) .* regressData(m,n);
%% Update weightVector for feature n
newWeightVector(n) = oldWeightVector(n) - error;
%% Calculate difference
vectorDifference = newWeightVector - oldWeightVector; %find difference vector between new and old weight vectors
difference = sqrt( dot( vectorDifference, vectorDifference)) %calculate the magnitude of difference between new and old weight vectors
iterCount = iterCount + 1;
%%Break if difference is below threshold
if(difference < 0.00005)
break
else
oldWeightVector = newWeightVector; % update Old Weight Vector for next prediction
end
end %for n
%%Break if difference is below threshold
if(difference < 0.000005)
break
end
end %for m
end %while difference > 0.0005
weightVector = newWeightVector
iterCount
end
また、確率的ではなくグローバルな方法を試してみましたが、それでも非常に大きな重み値が得られます。
これが私のevaluateSigmoid関数です
function logisticPrediciton = evaluateSigmoid(weightVector, sample)
%% This function evaluates the sigmoid with a given weight vector and sample
%% Input:
% weightVector - column vector of n weights
% sample - row vector sample with n-1 features (a 1 will be appended to the
% beginning for the constant weight
sample = transpose(sample); % sample is fed in as a row vector, so must be transposed
exponent = exp( transpose(weightVector) * sample);
logisticPrediciton = 1 ./ ( 1 + exponent);
end
そして、これが私が扱っているデータセットです。最後の列はフィルターで除外され、最初の列はしきい値 (22 未満は 0、上は 1) を満たすかどうかに基づいて 1 または 0 に変わります。