线性回归
用线性函数 f(x)=w⊤x+b 去拟合一组数据 D={(x1,y1),(x2,y2),...,(xn,yn)},并且使得损失(cost function) J=n1∑i=1n(f(xi)−yi)2 最小。
线性回归带来的过拟合问题
Lasso回归和岭回归
Lasso 回归和岭回归(ridge regression)都是在标准线性回归的基础上修改 cost function,为了解决过拟合问题。
Lasso 的全称为 least absolute shrinkage and selection operator,又译最小绝对值收敛和选择算子、套索算法。
Lasso 回归对 J 加入 L1 正则化,其 cost function 如下:
J=n1i=1∑n(f(xi)−yi)2+λ∥w∥1
其中 λ∣∣w∣∣1=λ∑j=1n∣wj∣。
岭回归对式(2)加入 L2 正则化,其 cost function 如下:
J=n1i=1∑n(f(xi)−yi)2+λ∥w∥22
其中 λ∣∣w∣∣22=λ∑j=1nwj2。
其中,通俗来讲,最后一项正则化的加入使得程序不会让 w 变得过于复杂,对过于复杂的 w 进行惩罚。
约束范围
实例
1 2 3 4 5 6 7 8 9 10 11 12 13
| 0.002 0.05 //两个参数 10 2 1.1 1.1 1.4 1.5 1.7 1.8 1.7 1.7 1.8 1.9 1.8 1.8 1.9 1.8 2.0 2.1 2.3 2.4 2.4 2.5 16.3 16.8 19.2 18.0 19.5 20.9 21.1 20.9 20.3 22.0
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include "matrix.h" #include "euclid.h" using namespace std; Matrix<long double>X[20],Y,w; long double res[20]; int n,m; long double lambda=0.01; Matrix<long double>grad(){ Matrix<long double>gw(1,m+1); for (int j=1;j<=m+1;++j){ for (int i=1;i<=n;++i){ gw[1][j]+=2*X[i][1][j]*res[i]/n; } gw[1][j]+=2*lambda*w[1][j]; if (w[1][j]>0) gw[1][j]+=2*lambda; if (w[1][j]<0) gw[1][j]-=2*lambda; } return gw; } int main(){ double alpha=0.03; cin>>lambda>>alpha; cin>>n>>m; for (int i=1;i<=n;++i) X[i].resize(1,m+1); Y.resize(n,1); w.resize(1,m+1); for (int i=1;i<=n;++i){ X[i][1][1]=1; for (int j=1;j<=m;++j) cin>>X[i][1][j+1]; } for (int i=1;i<=n;++i) cin>>Y[i][1]; int iter=50000; while (iter--){ long double J=0; for (int i=1;i<=n;++i){ res[i]=(X[i]&w)-Y[i][1]; J+=res[i]*res[i]; } J/=n; w=w-alpha*grad(); } long double J=0; for (int i=1;i<=n;++i){ res[i]=(X[i]&w)-Y[i][1]; cout<<res[i]<<endl; J+=res[i]*res[i]; } J/=n; cout<<J<<endl; cout<<w<<endl; }
|
可以得到 10.9051 6.10542 -1.33797
之类的结果,和原数据比较接近。
(中间调参过程比较玄学)