JobPlus知识库 IT 工业智能4.0 文章
机器学习回归算法拟合多项式

code:

[python]

  1. <span style="font-size:18px;">import numpy as np  
  2. from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV, ElasticNetCV  
  3. from sklearn.preprocessing import PolynomialFeatures  
  4. import matplotlib.pyplot as plt  
  5. from sklearn.pipeline import Pipeline  
  6. import matplotlib as mpl  
  7. import warnings  
  8. # 计算统计参数TSS RSS R  
  9. def xss(y, y_hat):  
  10.     # y转置  
  11.     y = y.ravel()  
  12.     y_hat = y_hat.ravel()  
  13.     # 都是利用差平方和公式计算  
  14.     tss = ((y - np.average(y)) ** 2).sum()  
  15.     rss = ((y_hat - y) ** 2).sum()  
  16.     ess = ((y_hat - np.average(y)) ** 2).sum()  
  17.     # 统计学中R参数计算公式  
  18.     r2 = 1 - rss/tss  
  19.     print('Rss:', rss)  
  20.     print('Ess:', ess)  
  21.     print('Rss + Ess:', rss + ess)  
  22.   
  23.     tss_list.append(tss)  
  24.     rss_list.append(rss)  
  25.     ess_list.append(ess)  
  26.     ess_rss_list.append(rss + ess)  
  27.     # 得到y和y_hat的相关系数  
  28.     corr_coef = np.corrcoef(y, y_hat)[0, 1]  
  29.     return r2, corr_coef  
  30.   
  31. if __name__ =='__main__':  
  32.     warnings.filterwarnings("ignore")  
  33.     np.random.seed(0)  
  34.     np.set_printoptions(linewidth=1000)  
  35.     N = 9  
  36.     x = np.linspace(0, 6, N) + np.random.randn(N)  
  37.     x = np.sort(x)  
  38.     y = x**2 - 4*x - 3 + np.random.randn(N)  
  39.     x.shape = -1, 1  
  40.     y.shape = -1, 1  
  41.     # 构建几个相关的线性模型回归,Ridge,LassoCV以及ElasticNetCV  
  42.     models = [Pipeline([('poly', PolynomialFeatures()), ('linear', LinearRegression(fit_intercept=False))]),  
  43.         Pipeline([('poly', PolynomialFeatures()), ('linear', RidgeCV(alphas=np.logspace(-3, 2, 50), fit_intercept=False))]),  
  44.         Pipeline([('poly', PolynomialFeatures()), ('linear', LassoCV(alphas=np.logspace(-3, 2, 50), fit_intercept=False))]),  
  45.         Pipeline([('poly', PolynomialFeatures()), ('linear', ElasticNetCV(alphas=np.logspace(-3, 2, 50), l1_ratio=[.1, .5, .7, .9, .95, .99, 1], fit_intercept=False))])  
  46.         ]  
  47.   
  48.     np.set_printoptions(suppress=True)  
  49.     plt.figure(figsize=(15, 15), facecolor='w')  
  50.     d_pool = np.arange(1, N, 1)  
  51.     m = d_pool.size  
  52.     # 存颜色的list  
  53.     clrs = []  
  54.     for c in np.linspace(16711680, 255, m):  
  55.         clrs.append('#%06x' % int(c))  
  56.     line_width = np.linspace(5, 2, m)  
  57.     titles = 'linear regression', 'Ridge regression', 'Lasso', 'ElasticNet'  
  58.     tss_list = []  
  59.     rss_list = []  
  60.     ess_list = []  
  61.     ess_rss_list = []  
  62.   
  63.     for t in range(4):  
  64.         model = models[t]  
  65.         plt.subplot(2, 2, t+1)  
  66.         plt.plot(x, y, 'ro', ms=10, zorder=N)  
  67.         for i, d in enumerate(d_pool):  
  68.             model.set_params(poly__degree=d)  
  69.             model.fit(x, y.ravel())  
  70.             lin = model.get_params('linear')['linear']  
  71.             output = '%s:%d level, parameters:'%(titles[t], d)  
  72.             if hasattr(lin, 'alpha_'):  
  73.                 idx = output.find('parameters')  
  74.                 output = output[:idx] + ('alpha = %.6f, ' % lin.alpha_) + output[idx:]  
  75.             # 这里使用交叉验证,从输入的l1_ratio(list)中选择一个最优的l1_ratio(float)值  
  76.             if hasattr(lin, 'l1_ratio_'):  
  77.                 idx = output.find('parameters')  
  78.                 output = output[:idx] + ('l1_ratio = %.6f, ' % lin.l1_ratio_) + output[idx:]  
  79.             print("output:\n", output)  
  80.             print("lin.coef_.ravel():\n", lin.coef_.ravel())  
  81.   
  82.             x_hat = np.linspace(x.min(), x.max(), num=100)  
  83.             x_hat.shape = -1, 1  
  84.             y_hat = model.predict(x_hat)  
  85.             s= model.score(x, y)  
  86.             r2, corr_coef = xss(y, model.predict(x))  
  87.             print("R2 and corrlated params:", r2, corr_coef)  
  88.             print('R2:', s, '\n')  
  89.   
  90.             z = N - 1 if (d == 2) else 0  
  91.             label = '%d level, $R^2 $=%.3f' %(d, s)  
  92.             if hasattr(lin, 'l1_ratio_'):  
  93.                 label += ', L1 ration=%.2f' % lin.l1_ratio_  
  94.   
  95.             plt.plot(x_hat, y_hat, color=clrs[i], lw=line_width[i], alpha=0.75, label=label, zorder=z)  
  96.         plt.legend(loc='upper left')  
  97.         plt.grid(True)  
  98.         plt.title(titles[t], fontsize=18)  
  99.         plt.xlabel("X", fontsize=15)  
  100.         plt.ylabel("Y", fontsize=15)  
  101.   
  102.     plt.tight_layout(pad=2.5, w_pad=0.5, rect=(0, 0, 1, 0.95))  
  103.     # plt.tight_layout()  
  104.     plt.suptitle('multiply curve fitness compare', fontsize=22)  
  105.     plt.show()  
  106.   
  107.     y_max = max(max(tss_list), max(ess_rss_list)) * 1.05  
  108.     plt.figure(figsize=(15,15), facecolor='w')  
  109.     t = np.arange(len(tss_list))  
  110.     plt.plot(t, tss_list, 'ro-', lw=2, label='Tss(Total Sum of Squares)')  
  111.     plt.plot(t, ess_list, 'mo-', lw=1, label='Ess(Explained Sum of Squares)')  
  112.     plt.plot(t, rss_list, 'bo-', lw=1, label='Ess(Residual Sum of Squares)')  
  113.     plt.plot(t, ess_rss_list, 'go-', lw=2, label='ESS + RSS')  
  114.     plt.ylim((0, y_max))  
  115.     plt.legend(loc='center right')  
  116.     plt.xlabel('trial:linear regression/RIdge?Lasso?ElasticNet', fontsize=15)  
  117.     plt.ylabel('XSS value', fontsize=15)  
  118.     plt.title('Total Sum Of Tss = ?', fontsize=18)  
  119.     plt.grid(True)  
  120.     plt.show()  
  121. </span>  

第一张图拟合出来的效果只是回归算法的loss function不同,但是出来的效果明显后两种要好。


接着,我们使用决策树以及bagging的决策树进行拟合看看效果:(关于bagging的决策树,就是GBDT,原理部分这个文章不累述)

[python] 

  1. <span style="font-size:18px;">import numpy as np  
  2. import matplotlib.pyplot as plt  
  3. import matplotlib as mpl  
  4. from sklearn.linear_model import RidgeCV  
  5. from sklearn.ensemble import BaggingRegressor  
  6. from sklearn.tree import DecisionTreeRegressor  
  7. from sklearn.pipeline import Pipeline  
  8. from sklearn.preprocessing import PolynomialFeatures  
  9.   
  10. def f(x):  
  11.     return 0.5*np.exp(-(x + 3)**2) + np.exp(-x**2) + 0.5*np.exp(-(x - 3)**2)  
  12.   
  13. if __name__ == '__main__':  
  14.     np.random.seed(0)  
  15.     N = 500  
  16.     # 得到200个在[-5, 5]的数据  
  17.     x = np.random.rand(N) *10 - 5  
  18.     x = np.sort(x)  
  19.     y = f(x) + 0.05*np.random.randn(N)  
  20.     x.shape = -1, 1  
  21.   
  22.     ridge = RidgeCV(alphas=np.logspace(-3, 2, 10), fit_intercept=False)  
  23.     ridged = Pipeline([('poly', PolynomialFeatures(degree=10)), ('Ridge', ridge)])  
  24.     bagging_ridged = BaggingRegressor(ridged, n_estimators=100, max_samples=0.3)  
  25.     dtr = DecisionTreeRegressor(max_depth=6)  
  26.     regs=[  
  27.         ('DecisionTree Regressor', dtr),  
  28.         ('Ridge Regressor(6 Degree)', ridged),  
  29.         ('Bagging Ridge(6 Degree)', bagging_ridged),  
  30.         ('Bagging DecisionTree Regressor', BaggingRegressor(dtr, n_estimators=100, max_samples=0.3))  
  31.     ]  
  32.     x_test = np.linspace(1.1*x.min(), 1.1*x.max(), 1000)  
  33.     plt.figure(figsize=(12, 8), facecolor='w')  
  34.     plt.plot(x, y, 'ro', label='train datas')  
  35.     plt.plot(x_test, f(x_test), color='k', lw=4, label='real datas')  
  36.     clrs = 'bmyg'  
  37.     for i, (name, reg) in enumerate(regs):  
  38.         reg.fit(x, y)  
  39.         y_test = reg.predict(x_test.reshape(-1, 1))  
  40.         plt.plot(x_test, y_test.ravel(), color=clrs[i], lw=i+1, label=name, zorder=6-i)  
  41.     plt.legend(loc='upper left')  
  42.     plt.xlabel('x', fontsize=15)  
  43.     plt.ylabel('y', fontsize=15)  
  44.     plt.title('regression curve fittness', fontsize=20)  
  45.     plt.ylim((-0.2, 1.2))  
  46.     plt.tight_layout(True)  
  47.     plt.grid(True)  
  48.     plt.show()</span>  

显然,使用线性拟合,对训练数据拟合效果是很好的,大部分都能落在拟合曲线上,而决策树就形成锯齿状,拟合的效果也不及线性拟合,这也是为什么说线性拟合分类器是强分类器,而决策树分类器是弱分类器。加入bagging(GBDT)后,拟合效果改善很大,不过其效果也不会达到线性拟合那么“完美”。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
265人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序