std::vector<std::vector<double>> buildVandermonde(const std::vector<double>& x, int degree) {
int m = x.size();
int n = degree + 1;
std::vector<std::vector<double>> X(m, std::vector<double>(n));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
X[i][j] = std::pow(x[i], j);
}
}
return X;
}
graph TD
A[原始数据点 xi, yi] --> B{是否需要预处理?}
B -->|是 | C[归一化/去噪]
B -->|否 | D[直接构造矩阵]
C --> D
D --> E[初始化空矩阵 X]
E --> F[遍历每个 xi]
F --> G[计算 1, xi, xi², ..., xin]
G --> H[填入矩阵第i行]
H --> I{是否所有点处理完毕?}
I -->|否 | F
I -->|是 | J[输出范德蒙矩阵 X]
boolread_csv(const std::string& filename, std::vector<double>& x_vec, std::vector<double>& y_vec){
std::ifstream file(filename);
if (!file.is_open()) {
throw std::runtime_error("Cannot open file: " + filename);
}
std::string line;
int line_num = 0;
while (std::getline(file, line)) {
++line_num;
std::istringstream ss(line);
std::string cell_x, cell_y;
if (!std::getline(ss, cell_x, ',')) continue;
if (!std::getline(ss, cell_y, ',')) {
throw std::invalid_argument("Incomplete data at line " + std::to_string(line_num));
}
try {
double x = std::stod(cell_x);
double y = std::stod(cell_y);
x_vec.push_back(x);
y_vec.push_back(y);
} catch (...) {
throw std::invalid_argument("Invalid number format at line " + std::to_string(line_num));
}
}
if (x_vec.empty()) {
throw std::length_error("No valid data found in file.");
}
returntrue;
}
set title "Polynomial Fit (degree $1)"
set xlabel "x"
set ylabel "y"
set grid
set terminal png size 800,600
set output 'fit_plot.png'
plot '$2' using 1:2 with points pt 7 ps 0.8 title "Data",\
'$2' using 1:3 with lines lw 2 title "Fitted Curve"
EOF
C++ 中调用:
std::system("gnuplot plot.gp");
从此告别手动画图,真正实现自动化报告生成。
模型诊断:防止自我欺骗的关键一步
最后提醒一句:不要盲目相信你的拟合结果。
系统应具备基本的自检能力:
if (degree >= 8 && rmse_on_test_region > 2 * global_rmse) {
std::cout << "[Warning] Possible overfitting detected. "
<< "Consider reducing polynomial degree." << std::endl;
}
double r2 = fitter.compute_r_squared();
if (r2 < 0.8) {
std::cout << "[Suggestion] Low R² (" << r2 << "). Model may underfit. Try higher degree or check data noise." << std::endl;
}