赶在国庆回家前做点小实验==
利用梯度下降法去拟合任意你想拟合的东西,哈哈
自己想出来的曲线:
目标函数:
其中:
,
然后计算迭代式:
其中:
k表示第k次迭代,
至此,有了梯度方向就可以计算啦,附上c++代码:
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
int main() {
//产生数据
srand(time(NULL));
vector<vector<double>> x(5,vector<double>(3,0.0));
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 3; j++) {
x[i][j] = rand() % 10+1;
//cout << x[i][j] << " ";
}
//cout << ",";
}
//double *y = new double[5];
double y[5];
for (int i = 0; i < 5; i++) {
y[i] = 3 * x[i][0] + 5 * x[i][1] - 7 * x[i][2] + double((rand() % 7)) / 10;
// cout << y[i] << endl;
}
double a=0.0,b=0.0,c=0.0,
aa=0.0,bb=0.0,cc=0.0;
double diff;
double error=0,error1=0;
int itertornum = 0;//记录迭代次数
while (1) {
itertornum++;
for (int i = 0; i < 5; i++) {
cout << "第"<<itertornum<<"次迭代:"<<aa << "," << bb << "," << cc << "," << endl;
diff = y[i] - (a*x[i][0] + b*x[i][1] + c*x[i][2]);
aa = aa + 0.001*diff*x[i][0];
bb = bb + 0.001*diff*x[i][1];
cc = cc + 0.001*diff*x[i][2];
}
a = aa; b = bb; c = cc;//更新状态量
error = 0;
for (int i = 0; i < 5; i++) {
error += 0.5*(pow(y[i] - (a*x[i][0] + b*x[i][1] + c*x[i][2]), 2));
}
if (abs(error - error1) < 1e-5) {
break;
}
else {
error1 = error;
}
}
cout << "最终结果是:" << a <<","<< b<<"," << c<<endl;
system("pause");
return 0;
}