数学建模社区-数学中国

标题: 多项式函数拟合sin函数(最小二乘法求解参数及其正则化) [打印本页]

作者: 杨利霞    时间: 2020-4-25 16:12
标题: 多项式函数拟合sin函数(最小二乘法求解参数及其正则化)
多项式函数拟合sin函数(最小二乘法求解参数及其正则化)
& _" x. A9 @) R% @
/ \2 k# f. T4 P% q4 M- V! U' ]4 _+ x% f+ X1.统计学习是关于计算机基于数据构建概率统计模型并运用模型对数据进行分析与预测的一门学科。统计学习包括监督学习、非监督学习、半监督学习和强化学习。
( e& S: v, P. H! d8 w# d$ E! }2.统计学习方法三要素——模型、策略、算法,对理解统计学习方法起到提纲挈领的作用。
1 w3 R, h/ g- Z6 t- I3.本书主要讨论监督学习,监督学习可以概括如下:从给定有限的训练数据出发, 假设数据是独立同分布的,而且假设模型属于某个假设空间,应用某一评价准则,从假设空间中选取一个最优的模型,使它对已给训练数据及未知测试数据在给定评价标准意义下有最准确的预测。. v3 ~1 ~$ ]) ?) {
4.统计学习中,进行模型选择或者说提高学习的泛化能力是一个重要问题。如果只考虑减少训练误差,就可能产生过拟合现象。模型选择的方法有正则化与交叉验证。学习方法泛化能力的分析是统计学习理论研究的重要课题。
& @+ ?" R' ]; f: C( u7 I5.分类问题、标注问题和回归问题都是监督学习的重要问题。本书中介绍的统计学习方法包括感知机、K近邻法、朴素贝叶斯法、决策树、逻辑斯谛回归与最大熵模型、支持向量机、提升方法、EM 算法、隐马尔可夫模型和条件随机场。这些方法是主要的分类、标注以及回归方法。它们又可以归类为生成方法与判别方法。
# V) Z& ]- p) i. |. K7 K2 ?9 B. p  E6 |7 W$ }3 f( _9 O. z' H
% z1 {6 S, g6 r4 ~- @- ^
1.png * l3 m2 |) e$ O. I$ t. y

# t, f7 `5 X& D+ x" ?9 l 2.png   r# x9 Q7 H% x
import numpy as np
  G4 F, {- |3 d7 Wimport matplotlib.pyplot as plt4 c( a9 K+ G+ b% ?0 {
from scipy.optimize import leastsq8 u% F$ V* T/ G; @' l- E

; I9 H7 d+ N+ X1 B
4 ]" ~! X% Q9 C# 我们要拟合的目标函数
, i1 W9 Y/ e1 g9 {3 i4 Y5 q$ G: Kdef real_func(x):
1 `5 c% g9 ?  c" d    return np.sin(2*np.pi*x)
( H) @/ _4 c! G
9 v' B4 k7 Q1 l' }
% f! [) j" C: v) O; M  O" I2 ~# 我们自己定义的多项式函数. u, m5 |: z4 _0 G" L' F! y
def fit_func(p, x):; k, d' Y9 w1 m. n! O+ Q
    f = np.poly1d(p)  # np.poly1d([2,3,5,7])返回的是函数,2x3 + 3x2 + 5x + 7
+ {- G5 _0 M, G4 V6 J8 d    ret = f(x)
. c" Z; B( j1 ?    return ret
# h7 \" o+ ]" D9 M! Z8 h2 G! e1 t" o5 W) P) p7 x

' F% K0 I7 W9 I+ e/ ^0 N) ~# 计算残差' Z) G  b* H2 Y. O( i8 n. U
def residuals_func(p, x, y):
1 M1 x1 w. s0 i0 r    ret = fit_func(p, x) - y, s) p' B/ m. t) T
    return ret8 E" F! e  o0 D( ]
! y, K: t  ^9 T+ i
% ]4 m/ }0 E8 @% j5 g: N) q# X
def fitting(M=0):& m* L/ L/ @  Q! t7 }9 T* k
    """
9 ]) }& w( I) p4 |( ]        M    为 多项式的次数6 _5 u3 x# ^8 n+ Z
    """
% k3 M: ~* G/ I, u    # 随机初始化多项式参数
5 F# Q6 o" R6 C0 L* n, U    p_init = np.random.rand(M + 1)  # 返回M+1个随机数作为多项式的参数0 v( y/ R) @3 c) f
    # 最小二乘法:具体函数的用法参见我的博客:残差函数,残差函数中参数一,其他的参数0 }+ o' M+ I/ S1 [
    p_lsq = leastsq(residuals_func, p_init, args=(x, y)): w/ B" W: `# i
    # 求解出来的是多项式当中的参数,就是最小二乘法中拟合曲线的系数  S$ p. a* D9 B, z* R6 o! O
    # print('Fitting Parameters:', p_lsq[0])
6 O* A4 n# X5 ~; ~3 R/ O    return p_lsq[0]
! g, Y: V1 \7 S& ?" t  O- l8 \& L4 T$ f0 i) G& u! z

* I2 o; m2 O5 z) x4 c9 h# \6 _# 书中10个点,对y加上了正态分布的残差
. ?7 s$ ^  q- l1 nx = np.linspace(0, 1, 10)
5 _- U9 [4 D/ J. X; Ty_old = real_func(x)0 b8 @1 {1 w8 j! e0 T4 z# {
y = [np.random.normal(0, 0.1) + yi for yi in y_old]9 o+ Y+ u8 L) o+ E0 R

5 @8 x: m/ n/ G+ K3 |5 n6 Q- ]; u* J6 E. V2 E
x_real = np.linspace(0, 1, 1000)1 W6 @( X" V: W
y_real = real_func(x_real)
0 c% x+ l! t5 V8 r: x9 B) m
% j; X5 m1 T' G1 ?8 ~# z7 A3 Q$ \* x, E
plt.plot(x_real, y_real, label="real")
! g" l: |3 s  U; U, k9 L; kplt.plot(x, y, 'bo', label='point')
* u! D6 C# P, H2 R#  fiitting函数中args=(x, y)是条用的是上面定义的10个点的全局变量x,y
0 V, `+ L2 z+ \plt.plot(x_real, fit_func(fitting(9), x_real), label="fitted curve")2 s2 v% y8 h+ ^* a5 x7 @
plt.legend()8 O1 L7 a$ @7 y& K. `$ K7 h4 X6 t* r
plt.show()
0 K5 A3 E. h! I5 ?" Q2 g# v
3 V- [! f7 e) P/ jM=0
' f* h% r3 d& h. U6 o1 U% |2 K5 f" `# F! p
3.png   X6 Z$ x9 M/ N9 R9 U5 u( l; d
M=1) j# ?' ?; M! A! W2 L
4.png 6 h3 f: g) i9 e2 D* M
M=30 F: `5 A; U; ?- X1 Z
2 N' m' u' w. f% |- [& I9 h* P, V8 P
5.png   V2 g& r0 B( Y7 Z1 a$ t" E

0 L4 w5 J- D/ L( P- O4 RM=9
+ c4 a$ f! O7 C" c6 @5 G 6.png
, j% k6 Z: v1 i# C" D' r6 v/ i& G 7.png 7 P6 @. p% E, h! U5 L: E. _

! Q/ [* x3 j/ m# d$ B7 C4 |W是参数,就是最小二乘法求得到的系数0 ~& x, g% k5 X/ i) ~& a
lambda是regularization,是自定义的系数。
0 B( E/ G; V  {/ [( q' ^import numpy as np* r# X1 Q) n. g9 H( ?1 I* g
import matplotlib.pyplot as plt
7 E9 [# v* o3 C+ V( e" |from scipy.optimize import leastsq0 {: C/ Z  _. U" K' D3 q* Y( W

, Q. p4 ]. U( M1 P% e5 l
  h% Q  H& v; ]6 j# 我们要拟合的目标函数9 l/ k+ y5 z$ e9 G, d- M2 g+ k2 ^. v
def real_func(x):
. B. Z. T' D' S    return np.sin(2*np.pi*x)3 X4 m. u' A3 T# f5 ~7 Y

2 I3 I( }8 J/ D" }
+ F( i! Z; q& W  q# 我们自己定义的多项式函数
4 I+ x5 `: U: I4 ?! `8 F  Y4 b9 C( K+ bdef fit_func(p, x):+ k) T5 }1 ~4 h% ]
    f = np.poly1d(p)  # np.poly1d([2,3,5,7])返回的是函数,2x3 + 3x2 + 5x + 7  o% t- b, O/ k& G
    ret = f(x)
2 U! c5 i8 M7 }2 F* K7 j, M$ a8 s    return ret
, z7 X$ ^& H, m3 V- U/ P
0 i/ I- `# q) |) ?2 I3 w6 _& s' E  C8 }5 A! f* N) [, }$ N( N
# 计算残差$ Q; C' ~' `! O& v1 d" I; Y" \
def residuals_func(p, x, y):: ^5 x0 @3 Z- @( a
    ret = fit_func(p, x) - y
2 O" L  p4 u: R; p  T    return ret
& K- W; `& H* i7 r, L4 C* o# j' y( Q4 l0 Y

$ h# X4 T; h2 N) R# 返回残差和正则项$ G# I+ C- H( I7 J
def residuals_func_regularization(p, x, y):
% U; G, F" \7 _7 v    ret = fit_func(p, x) - y
1 D( G: E8 R. l5 ]# c) s8 W( W& o    ret = np.append(ret,- S& m- q# j' T2 q  S
                    np.sqrt(0.5 * regularization * np.square(p)))  # L2范数作为正则化项  K0 o# a1 y5 j
    return ret- U8 k! a. A( o3 ?9 l9 j

- Q$ ^$ N7 C# [0 ~) \' T' `1 g6 s# g8 D1 c+ i3 y4 j+ I
def fitting(M=0):
  G- H) g. c% B2 s    """
* w6 x1 I* l7 |: |0 X        M    为 多项式的次数
2 @5 P+ j/ a+ \9 ?% {) j/ u2 C    """
7 V- @- ?# ?) U. e$ p3 W    # 随机初始化多项式参数9 O8 O' v. m2 N4 P! _
    p_init = np.random.rand(M + 1)  # 返回M+1个随机数作为多项式的参数) h% t. P# v; B8 s) a8 @# r
    # 最小二乘法:具体函数的用法参见我的博客:残差函数,残差函数中参数一,其他的参数+ ^% w& \) {; ^7 m3 @' \* X+ E) k/ I$ |2 r
    p_lsq = leastsq(residuals_func, p_init, args=(x, y))8 n! j$ v: g  D5 J: E
    # 求解出来的是多项式当中的参数,就是最小二乘法中拟合曲线的系数/ m4 M) @$ [% U5 Z4 [( I$ d
    # print('Fitting Parameters:', p_lsq[0])( B1 o" {9 L5 K& \# T. E
    return p_lsq[0]
. }& _& }3 G2 M# }: }3 b8 x. w/ c+ ^& t1 T  f4 o$ ]7 A$ l9 V; i
- \8 r7 l2 A; L7 L  m4 m/ _
# 书中10个点,对y加上了正态分布的残差
( r! K& h# m: R/ u2 Ix = np.linspace(0, 1, 10)' |2 X3 P+ H% U
y_old = real_func(x)
! \' f: Z0 ?. e5 d' Q' y8 V. |y = [np.random.normal(0, 0.1) + yi for yi in y_old]( h2 v4 O6 b) F2 h! L

  W. ~. A3 ?) ~7 Z; S
8 R: R: w' Y; l" W8 j& U! Z! o& lx_real = np.linspace(0, 1, 1000)
$ c7 n, Q3 F) M1 a& py_real = real_func(x_real)
: N# {4 ~6 p) a5 |4 A# L
  w( j; R/ [% v& B9 n8 c: L+ e# N. I
# X% ?5 Q+ H1 r; K" C" q6 J# # 画出10个散点,sin图像,和拟合的曲线
; K8 F. r( y" m+ J5 A# plt.plot(x_real, y_real, label="real")
, ^: e* ~5 [/ C" E; l9 S# plt.plot(x, y, 'bo', label='point')
! ^# [4 }( c9 J8 h, c0 ^# plt.plot(x_real, fit_func(fitting(9), x_real), label="fitted curve")" W! p8 h* I4 h* `/ b( P# s  d
# plt.legend()
* [: i- K3 y" I( x- `# plt.show()
0 T- G  U) T" t+ m' x( {; U# b
8 u* o) K. l+ Y+ N* q3 P0 x  y! ^. w! ^* z
# 画出添加正则项的曲线' t3 {8 s3 D3 [
regularization = 0.0001- d- K! Q# P0 \/ [$ a
p_init = np.random.rand(9 + 1)
% x! F7 L  M& f8 P9 |( v! Kp_lsq_regularization = leastsq(
' m, `; q$ k- v* z* T' u6 Y    residuals_func_regularization, p_init, args=(x, y))
, _! G# K6 Q$ S9 }  I- S3 \/ ]' Z, ]0 X
) @2 H8 F3 g3 K
# 画出原sin图像,不加正则项的图像,加上正则项的图像,10个点的散点图
8 y  n7 H) Q$ |5 a# 不加正则项和加上正则项都是9次方,10个系数, K* `  D+ I6 G2 l
plt.plot(x_real, real_func(x_real), label='real')3 ]* U. q2 q& u; C( l) a
plt.plot(x_real, fit_func(fitting(9), x_real), label='fitted curve')
  S  K1 {/ I1 ?plt.plot(
7 `& d. |- H. H0 Y/ x    x_real,3 F8 n; a/ B, Y; n9 ?: q
    fit_func(p_lsq_regularization[0], x_real),
9 i9 v( }' t: U; K4 ^, V5 j2 u    label='regularization')) g1 [' K9 y; i, ]4 \$ d0 w; l
plt.plot(x, y, 'bo', label='noise')) T+ A9 E5 r1 T- H% O( Q. E0 q
plt.legend()
0 U7 ~( p9 D" F. K' \9 R- R4 p1 Splt.show()( d2 g: K) |4 c' [4 ]6 M+ }
7 P# v( N' ]3 ^
8.png 0 H' A+ |, u; q3 y

' [0 Z, J0 f; T& d3 c% }- ^. C! ~, |
' Z8 O* h6 H# C
% ~3 ?' K. R: K7 I7 \6 \




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5