1

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 に変わります。

4

0 に答える 0