Logistic回归返回错误的预测

时间:2019-05-21 00:29:34

标签: c++ machine-learning logistic-regression

我正在尝试在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 :(得分:0)

从很小的学习率开始,尝试更大的迭代次数。还没有测试您的代码。但是我想成本/错误/能量会从驼峰跳到驼峰。

答案 1 :(得分:0)

有些问题与您的问题无关,但不是使用pow计算e ^ -total,而是使用exp(这真是太快了!)。同样,也无需使Sigmoid函数成为成员函数,使其成为静态函数或仅使其成为普通C函数(不需要从结构中获取任何成员变量)。

static double sigmoid(double total)
{
    return 1.0 / (1.0 + exp(-total));
}