Логистическая регрессия возвращает неправильный прогноз - PullRequest
0 голосов
/ 21 мая 2019

Я пытаюсь реализовать логистическую регрессию в C ++, но прогнозы, которые я получаю, даже близко не соответствуют ожиданиям.Я не уверен, есть ли ошибка в моем понимании логистической регрессии или кода.

Я рассмотрел алгоритмы и перепутал скорость обучения, но результаты очень противоречивы.

double theta[4] = {0,0,0,0};

double x[2][3] = {
    {1,1,1},
    {9,9,9},
    };

double y[2] = {0,1};

//prediction data
double test_x[1][3] = {
        {9,9,9},
        };

int test_m = sizeof(test_x) / sizeof(test_x[0]);

int m = sizeof(x) / sizeof(x[0]);

int n = sizeof(theta) / sizeof(theta[0]);

int xn = n - 1;

struct Logistic
{
    double sigmoid(double total)
    {
        double e = 2.71828;
    double sigmoid_x = 1 / (1 + pow(e, -total));
    return sigmoid_x;
}

double h(int x_row)
{
    double total = theta[0] * 1;

    for(int c1 = 0; c1 < xn; ++c1)
    {
        total += theta[c1 + 1] * x[x_row][c1];
    }

    double final_total = sigmoid(total);
    //cout << "final total: " << final_total;
    return final_total;
}


double cost()
{
    double hyp;
    double temp_y;
    double error;

    for(int c1 = 0; c1 < m; ++c1)
    {
        //passes row of x to h to calculate sigmoid(xi * thetai)
        hyp = h(c1);
        temp_y = y[c1];
        error += temp_y * log(hyp) + (1 - temp_y) * log(1 - hyp);
    }// 1 / m
    double final_error = -.5 * error;
    return final_error;
}

void gradient_descent()
{
    double alpha = .01;

        for(int c1 = 0; c1 < n; ++c1)
        {
            double error = cost();
            cout << "final error: " << error << "\n";
            theta[c1] = theta[c1] - alpha * error;
            cout << "theta: " << c1 << " " << theta[c1] << "\n";
        }   
}

void train()
{
    for(int epoch = 0; epoch <= 10; ++epoch)
    {
        gradient_descent(); 
        cout << "epoch: " << epoch << "\n";
    }   
}

vector<double> predict()
{
    double temp_total;
    double total;
    vector<double> final_total;

    //hypothesis equivalent function
    temp_total = theta[0] * 1;

    for(int c1 = 0; c1 < test_m; ++c1)
    {
        for(int c2 = 0; c2 < xn; ++c2)
        {
            temp_total += theta[c2 + 1] * test_x[c1][c2];
        }

        total = sigmoid(temp_total);
        //cout << "final total: " << final_total;
        final_total.push_back(total);
    }
    return final_total;
}

};

int main()
{
    Logistic test;
    test.train();
    vector<double> prediction = test.predict();
    for(int c1 = 0; c1 < test_m; ++c1)
    {
        cout << "prediction: " << prediction[c1] << "\n";
    }
}

Ответы [ 2 ]

0 голосов
/ 21 мая 2019

В некоторой степени не связанный с вашим вопросом, но вместо того, чтобы вычислять e ^ -total с использованием pow, используйте вместо этого exp (это намного быстрее!). Также нет необходимости превращать сигмоидную функцию в членскую функцию, делать ее статической или просто нормальной C-функцией (для нее не требуется переменная-член из вашей структуры).

static double sigmoid(double total)
{
    return 1.0 / (1.0 + exp(-total));
}
0 голосов
/ 21 мая 2019

начните с очень маленькой скорости обучения с большим числом итераций при попытке. Не проверял ваш код. Но я предполагаю, что цена / ошибка / энергия переходит от горба к горбу.

...