История изменений
Исправление 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;
Хочу в подобном стиле сделать для двухпараметрического. Без расчета ошибки оно не имеет смысла начинать.