LINUX.ORG.RU

История изменений

Исправление victor79, (текущая версия) :

Ту ошибку, что «residual sum of squares (RSS)»

То, что с матрицами это легче, это понятно. А без матриц следующие плюсы:

1. Производительность и расчет в один проход без необходимости сохранения матриц.

2. Слагаемость результата - все компоненты представляют собой суммы, и можно взять два набора результатов расчета от двух разных данных и сложить между собой. И вычитаемость. Если есть расчет больших данных, и из пачки делается исключение небольшого набора, то пересчитывать большие данные не обязательно, а можно вычесть расчет исключаемой пачки.

Последний пункт очень удобен для расчетов классификаций - деление множеств данных на пачки.

Для однопараметрического уравнения у меня такие расчеты:

// добавление значения в расчет, sg это знак добавления,
//   и если -1 значит вычитание.
void Corr::add_value(double x, double y, double w, double sg) {
    su_w += w * sg;
    su_w_sqr += w * w * sg;
    su_x_y += x * y * w * sg;
    su_x += x * w * sg;
    su_y += y * w * sg;
    su_x_sqr += x * x * w * sg;
    su_y_sqr += y * y * w * sg;
}

// сложение и вычитание расчитанных пачек 
void Corr::add_other(const Corr &o, double k_other) {
    su_w += o.su_w * k_other;
    su_w_sqr += o.su_w_sqr * k_other * k_other;
    su_x_y += o.su_x_y * k_other;
    su_x += o.su_x * k_other;
    su_y += o.su_y * k_other;
    su_x_sqr += o.su_x_sqr * k_other;
    su_y_sqr += o.su_y_sqr * k_other;
}

// это расчет коэффициентов
PairDbl Corr::get_a_b() const {

    assert( x_more_zero(su_w) );

    double divider = su_w * su_x_sqr - su_x * su_x;

    if (is_zero(divider))
        return {0, su_y / su_w};

    double d1 = su_w * su_x_y - su_x * su_y;

    double a = d1 / divider;
    double b = (su_y - a * su_x) / su_w;

    return {a,b};
}

// а это расчет ошибки.

    auto [a,b] = get_a_b();

    double d3 =
         su_y_sqr
         - 2. * a * su_x_y
         - 2. * b * su_y
         + 2. * a * b * su_x
         + a * a * su_x_sqr
         + b * b * su_w;

    double variance = d3 / su_w;
    
    double error = std::sqrt(variance);

Хочу в подобном стиле сделать для двухпараметрического. Без расчета ошибки оно не имеет смысла начинать.

Исправление victor79, :

Ту ошибку, что «residual sum of squares (RSS)»

То, что с матрицами это легче, это понятно. А без матриц следующие плюсы:

1. Производительность и расчет в один проход без необходимости сохранения матриц.

2. Слагаемость результата - все компоненты представляют собой суммы, и можно взять два набора результатов расчета от двух разных данных и сложить между собой. И вычитаемость. Если есть расчет больших данных, и из пачки делается исключение небольшого набора, то пересчитывать большие данные не обязательно, а можно вычесть расчет исключаемой пачки.

Последний пункт очень удобен для расчетов классификаций - деление множеств данных на пачки.

Для однопараметрического уравнения у меня такие расчеты:

// добавление значения в расчет, sg это знак добавления,
//   и если -1 значит вычитание.
void Corr::add_value(double x, double y, double w, double sg) {
    su_w += w * sg;
    su_w_sqr += w * w * sg;
    su_x_y += x * y * w * sg;
    su_x += x * w * sg;
    su_y += y * w * sg;
    su_x_sqr += x * x * w * sg;
    su_y_sqr += y * y * w * sg;
}

// сложение и вычитание расчитанных пачек 
void Corr::add_other(const Corr &o, double k_other) {
    su_w += o.su_w * k_other;
    su_w_sqr += o.su_w_sqr * k_other * k_other;
    su_x_y += o.su_x_y * k_other;
    su_x += o.su_x * k_other;
    su_y += o.su_y * k_other;
    su_x_sqr += o.su_x_sqr * k_other;
    su_y_sqr += o.su_y_sqr * k_other;
}

// это расчет коэффициентов
PairDbl Corr::get_a_b() const {

    assert( x_more_zero(su_w) );

    double divider = su_w * su_x_sqr - su_x * su_x;

    if (is_zero(divider))
        return {0, su_y / su_w};

    double d1 = su_w * su_x_y - su_x * su_y;

    double a = d1 / divider;
    double b = (su_y - a * su_x) / su_w;

    return {a,b};
}

// а это расчет ошибки.

    auto [a,b] = get_a_b();

    double d3 =
         su_y_sqr
         - 2. * a * su_x_y
         - 2. * b * su_y
         + 2. * a * b * su_x
         + a * a * su_x_sqr
         + b * b * su_w;

    res.a = a;
    res.b = b;
    res.er_pow2 = d3 / su_w;

Хочу в подобном стиле сделать для двухпараметрического. Без расчета ошибки оно не имеет смысла начинать.

Исходная версия victor79, :

То, что с матрицами это легче, это понятно. А без матриц следующие плюсы:

1. Производительность и расчет в один проход без необходимости сохранения матриц.

2. Слагаемость результата - все компоненты представляют собой суммы, и можно взять два набора результатов расчета от двух разных данных и сложить между собой. И вычитаемость. Если есть расчет больших данных, и из пачки делается исключение небольшого набора, то пересчитывать большие данные не обязательно, а можно вычесть расчет исключаемой пачки.

Последний пункт очень удобен для расчетов классификаций - деление множеств данных на пачки.

Для однопараметрического уравнения у меня такие расчеты:

// добавление значения в расчет, sg это знак добавления,
//   и если -1 значит вычитание.
void Corr::add_value(double x, double y, double w, double sg) {
    su_w += w * sg;
    su_w_sqr += w * w * sg;
    su_x_y += x * y * w * sg;
    su_x += x * w * sg;
    su_y += y * w * sg;
    su_x_sqr += x * x * w * sg;
    su_y_sqr += y * y * w * sg;
}

// сложение и вычитание расчитанных пачек 
void Corr::add_other(const Corr &o, double k_other) {
    su_w += o.su_w * k_other;
    su_w_sqr += o.su_w_sqr * k_other * k_other;
    su_x_y += o.su_x_y * k_other;
    su_x += o.su_x * k_other;
    su_y += o.su_y * k_other;
    su_x_sqr += o.su_x_sqr * k_other;
    su_y_sqr += o.su_y_sqr * k_other;
}

// это расчет коэффициентов
PairDbl Corr::get_a_b() const {

    assert( x_more_zero(su_w) );

    double divider = su_w * su_x_sqr - su_x * su_x;

    if (is_zero(divider))
        return {0, su_y / su_w};

    double d1 = su_w * su_x_y - su_x * su_y;

    double a = d1 / divider;
    double b = (su_y - a * su_x) / su_w;

    return {a,b};
}

// а это расчет ошибки.

    auto [a,b] = get_a_b();

    double d3 =
         su_y_sqr
         - 2. * a * su_x_y
         - 2. * b * su_y
         + 2. * a * b * su_x
         + a * a * su_x_sqr
         + b * b * su_w;

    res.a = a;
    res.b = b;
    res.er_pow2 = d3 / su_w;

Хочу в подобном стиле сделать для двухпараметрического. Без расчета ошибки оно не имеет смысла начинать.