一维数据拟合
参考自https://blog.csdn.net/shenliang1985/article/details/112327554?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_ecpm_v1~rank_aggregation-1-112327554.pc_agg_rank_aggregation&utm_term=%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95%E7%9A%84%E5%81%8F%E5%AF%BC%E6%95%B0%E6%8E%A8%E5%AF%BC&spm=1000.2123.3001.4430
设目标一维方程为
[Y= ax+b+ε
]
a | 斜率 |
---|---|
b | Y的截距 |
ε | 误差 |
一维方程可得
[ε=Y - ax - b
]
[Q=sum_{i=1}^{n}{ε_i^2}=sum_{i=1}^{n}({Y_i} -{y_i})^2 = sum_{i=1}^{n}(Yi - ax-b)^2
]
Q | 残差平方和 |
---|---|
ε | 差量 |
Y | 实际值 |
y | 拟合函数值 |
a | 斜率 |
b | Y的截距. |
将a,b设为变量,求Q对两个待估函数的偏导数:
[egin{cases}
frac{∂Q}{∂a}=-2sum_{i=1}^{n}(Y-a{x_i}-b){x_i}=0\
frac{∂Q}{∂b}=-2sum_{i=1}^{n}(Y-a{x_i}-b)=0
end{cases}
]
[a=frac{nsum_{i = 1}^{n}{x_i}{y_i}-sum_{i=1}^{n}{x_i}sum_{i = 1}^{n}{y_i}}{nsum_{i = 1}^{n}{x_i}^2-(sum_{i = 1}^{n}{x_i})^2}\
b=frac{sum_{i = 1}^{n}{x_i}^2sum_{i = 1}^{n}{y_i}-sum_{i=1}^{n}{x_i}sum_{i = 1}^{n}{x_i}{y_i}}{nsum_{i = 1}^{n}{x_i}^2-(sum_{i = 1}^{n}{x_i})^2}
]
由C++实现代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int n;
vector<double>x, y;
template <typename T>
inline void read(T& x) {
x = 0;
T op = 1;
char c = getchar();
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') op = -1;
for (; c <= '9' && c >= '0'; c = getchar())
x = (x << 3) + (x << 1) + c - '0';
x *= op;
}
inline double Get_a() {
double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i = 0; i < n; ++i)
sum1 += x[i] * y[i], sum2 += x[i], sum3 += y[i], sum4 += x[i] * x[i];
return (sum1 * n - sum2 * sum3) / (sum4 * n - sum2 * sum2);
}
inline double Get_b() {
double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i = 0; i < n; ++i)
sum1 += x[i] * y[i], sum2 += x[i], sum3 += y[i], sum4 += x[i] * x[i];
return (sum4 * sum3 - sum1 * sum2) / (sum4 * n - sum2 * sum2);
}
int main() {
freopen("data.txt", "r", stdin);
read(n);
for (int i = 1; i <= n; ++i) {
double nx, ny;
scanf("%lf%lf", &nx, &ny);
x.push_back(nx);
y.push_back(ny);
}
double a = Get_a();
double b = Get_b();
printf("y = %lfx + %lf", a, b);
return 0;
}
多维拟合
多维拟合和一维拟合在本质上差别不大,即对多维方程求偏导,解出各个未知量。(因为不会求了,所以水不下去了)