数学建模社区-数学中国

标题: Logistic回归--实例 [打印本页]

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """
    / W) m& b; H3 c9 |7 W& C
  2. 函数说明:梯度上升算法测试函数/ ^* T( v# V9 E$ f$ N- @
  3. - l( }$ [  Y1 I* h
  4. 求函数f(x) = -x^2 + 4x的极大值
    1 r; `! ?* ]8 O

  5. 2 Z: {5 t4 z- ~
  6. Parameters:
    " e5 Y# U( b5 n4 L7 d* G) G1 g7 k
  7.     无
      z, }: T* s# f+ M
  8. Returns:0 M$ m8 M1 C9 ?0 n) T
  9.     无. `1 Q1 M6 v  W% S
  10. """
    ; v. m3 D) e5 K( M) c
  11. def Gradient_Ascent_test():
    2 y# h5 ~. P1 I9 m
  12.     def f_prime(x_old):                                    #f(x)的导数* P# ]/ \9 j8 j7 z6 I7 i
  13.         return -2 * x_old + 4& G7 s' W: s, B; m% [
  14.     x_old = -1                                            #初始值,给一个小于x_new的值
    3 j5 w2 I; ^; O0 C
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始
    1 D8 X, I* C. `/ D
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度
    ! K4 A7 f6 `: p7 T+ M
  17.     presision = 0.00000001                                #精度,也就是更新阈值
      x8 z. ]7 |8 u; m. G
  18.     while abs(x_new - x_old) > presision:
    , p( U1 \; B# A2 v: L
  19.         x_old = x_new
    3 `, ?6 x8 s' x% d6 G' O6 J8 v' T2 ~
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式
    ) x* J3 v/ z' S* |! y. G6 K
  21.     print(x_new)                                        #打印最终求解的极值近似值/ }, h0 ?: B5 l4 t+ I9 b8 {/ Z) o1 d
  22. . ?' T3 k; C3 H6 A
  23. if __name__ == '__main__':
    ' t% N/ c1 @, p/ H; ~) z
  24.     Gradient_Ascent_test()( N' \9 ^1 b$ W: j* @
复制代码
运行实例:
  1. 1.9999995152798571 K! [5 W7 p% x3 u+ K# w  O
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  0
    ( I, D- G  }9 K6 ~& q
  2. -1.395634  4.662541  1' }6 p7 r' @) P+ i
  3. -0.752157  6.538620  0
    4 F4 r4 X+ m& u
  4. -1.322371  7.152853  0
    3 Z& \. j$ y  r- f( g% m
  5. 0.423363  11.054677  0
    3 `$ z1 E4 i0 p  i2 E
  6. 0.406704  7.067335  1
    9 \! T+ {& T+ D& }
  7. 0.667394  12.741452  0
    0 v7 i9 r3 h; N# f% s  _! X+ s
  8. -2.460150  6.866805  1
    % h- X3 e1 V8 K" w, g6 @
  9. 0.569411  9.548755  0. T* [. z" ]1 \
  10. -0.026632  10.427743  0
    & N7 k5 |& J4 M& j! h4 H" d
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt
    * O! O( h  }7 E. ~
  2. import numpy as np! E, z& ]: O6 s6 L  x
  3. , H& o' {2 y5 X7 A% I; m9 }! b
  4. """
    % X, v" ]5 j' G$ n8 a
  5. 函数说明:加载数据) u( U( D0 }0 z( H' z$ p

  6. . g& j8 t9 [9 z8 V8 C3 q* L
  7. Parameters:
    $ v- u+ P- T9 K4 i
  8.     无
    ! g8 q& d5 X% j  ~! Z! m
  9. Returns:" I$ A+ N0 Y- O
  10.     dataMat - 数据列表: J3 B8 _: ^2 O; ?) u
  11.     labelMat - 标签列表3 e8 C4 c) W. A# m0 e
  12. """5 v- p( y* m4 c7 U) {
  13. def loadDataSet():: n2 Z7 h' W, \! }) @# O( T/ Y
  14.     dataMat = []                                                        #创建数据列表
    ' V4 @6 a8 g. x
  15.     labelMat = []                                                        #创建标签列表: |+ P2 d! ?  E' G' C
  16.     fr = open('testSet.txt')                                            #打开文件   
    , l/ l" v2 M" f# H/ a
  17.     for line in fr.readlines():                                            #逐行读取
    7 j4 R1 {8 A0 L* @" t
  18.         lineArr = line.strip().split()                                    #去回车,放入列表  K$ f5 q) d9 u* Y6 s
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    + B/ I+ P! ~7 I& y
  20.         labelMat.append(int(lineArr[2]))                                #添加标签
    5 r2 P4 ]$ ^  V, {9 f
  21.     fr.close()                                                            #关闭文件
    ! d1 K+ d7 E/ t& I. O: \" x
  22.     return dataMat, labelMat                                            #返回: F5 i4 \5 A: d9 [6 h8 L1 j
  23. ' D6 ?9 K+ @9 Q" `$ E- Q
  24. """
    , V7 f/ ?, q3 i5 I2 C& h0 ^, [
  25. 函数说明:绘制数据集* `+ x9 o$ w: F- H( [  _- R

  26. ! \' l( k! n/ d: f& P' z/ g$ N; ]
  27. Parameters:, _% T9 H: _- K% O, @/ m* a
  28.     无7 V- C3 F* D" ^7 b3 o& B
  29. Returns:  H# e3 c# Z1 I7 ?; _
  30.     无
    & P( s; B/ z  D! ^# ?
  31. """
    - A: N7 v# C) Y
  32. def plotDataSet():
    2 ]" h% B7 V$ r1 |5 w) [  m, s3 J
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集. H7 S3 B) S4 l! `9 X
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组9 E. g+ N+ U! j% I
  35.     n = np.shape(dataMat)[0]                                            #数据个数9 b& H4 n4 t, [" E# T( k0 I
  36.     xcord1 = []; ycord1 = []                                            #正样本5 @, s( a# l" g3 N
  37.     xcord2 = []; ycord2 = []                                            #负样本( A: a& E& B- b# c
  38.     for i in range(n):                                                    #根据数据集标签进行分类
    ; N, c) Q1 b/ a* J5 U, l
  39.         if int(labelMat[i]) == 1:
    + a8 K3 }% X* a/ F2 A  e. m
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本
    + l5 r/ U% b) f7 e
  41.         else:
      f- o4 r0 B6 U9 X0 Q
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本
    3 b$ {- i. e7 X5 V1 y
  43.     fig = plt.figure()! p) u+ M: a5 g
  44.     ax = fig.add_subplot(111)                                            #添加subplot
    " Z' X$ K5 E; C) W
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本" j4 h; |8 N: R; R9 R/ d
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
    0 _! n: b5 x/ o! m. r! Z
  47.     plt.title('DataSet')                                                #绘制title
    : l! m! r+ V) L+ m: N  s' p
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label
    * n. N; c6 m! g' J/ ~$ I
  49.     plt.show()                                                            #显示
    ; ]" d, b$ E& I& ]

  50. ( k1 {7 x" p4 J& i' K! N# k
  51. if __name__ == '__main__':- f' F) o+ g, @* O9 r6 h$ t  I
  52.     plotDataSet()5 v8 D1 D  N; f$ u0 o$ @& a
复制代码
VeryCapture_20231130171817.jpg : J- k. ]0 R' C3 c3 \3 R7 B9 L
从上图可以看出数据的分布情况。假设Sigmoid函数的输入记为z,那么z=w0x0 + w1x1 + w2x2,即可将数据分割开。其中,x0为全是1的向量,x1为数据集的第一列数据,x2为数据集的第二列数据。另z=0,则0=w0 + w1x1 + w2x2。横坐标为x1,纵坐标为x2。这个方程未知的参数为w0,w1,w2,也就是我们需要求的回归系数(最优参数)。
  1. import numpy as np, I8 _) J# ?# o5 }- P4 Q
  2. " T' Y% @  m+ V
  3. """
    / O& a+ Y* E2 y+ g" U7 o8 R& g
  4. 函数说明:加载数据
    2 }/ }6 A7 F! z: L( }' d. E% u8 r" w
  5. 5 O5 u& g9 W, B$ f, k8 s
  6. Parameters:) K# S1 ]9 b4 H3 U0 y
  7.     无! d9 s$ S, _2 b6 y, j& `' m- A6 p0 u
  8. Returns:9 w+ e/ Z$ f- j# h; F- H: v5 q5 V
  9.     dataMat - 数据列表
    ) m7 Q- M7 ^. A( R
  10.     labelMat - 标签列表
    : D% {- s; z' e; o
  11. """
    5 b* P* c8 H* y# O$ o  y$ y
  12. def loadDataSet():
    7 l' o* t% o9 W5 j$ T7 {  ]
  13.     dataMat = []                                                        #创建数据列表
    3 ^" m2 w( V1 W# N# T2 I
  14.     labelMat = []                                                        #创建标签列表
    3 [. ]  S) P/ p+ c
  15.     fr = open('testSet.txt')                                            #打开文件   
    - |# X- ]. A8 W% C2 H  H; S
  16.     for line in fr.readlines():                                            #逐行读取
    ; o3 S% i4 c; h9 a; A& ]* `
  17.         lineArr = line.strip().split()                                    #去回车,放入列表: Z  Z& J1 w0 c) J& w& z
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据: ?; E) O8 Q8 {& L% H" ^+ G
  19.         labelMat.append(int(lineArr[2]))                                #添加标签
    ) F* m  x$ C# k' l; Z2 S
  20.     fr.close()                                                            #关闭文件
    9 ^$ _( Q; M( n! \2 e+ s
  21.     return dataMat, labelMat                                            #返回) @2 q" w) g* k$ x3 o
  22. 6 X2 B! j2 d6 u' h
  23. """
    ( Q3 S% W. a7 [
  24. 函数说明:sigmoid函数: T4 P, D6 y" r# z& d. E
  25. : T  p6 B8 b3 j! y* Q
  26. Parameters:  u) y- S# Z3 H; m. H
  27.     inX - 数据5 b4 I$ x3 z# f2 h/ H: j. B
  28. Returns:/ J0 v9 P# v2 e# L, F' t
  29.     sigmoid函数" M! H! }6 q; h
  30. """3 o* ?6 M- h( m4 K/ r, }( [4 w
  31. def sigmoid(inX):2 W: ^" Y+ s4 L  r
  32.     return 1.0 / (1 + np.exp(-inX))7 n$ E. D* s2 ~7 v0 S
  33. / |7 I- H* h6 w, W5 \

  34. ) k; M) a6 u0 K  N% S
  35. """# W. W. @0 t2 l8 f
  36. 函数说明:梯度上升算法
    6 h6 a7 D: U3 ?! D% m" \

  37. 7 ~6 Z6 o# B$ C" E+ E4 [' u
  38. Parameters:! x1 d# ~5 J9 o: u# A& s, F2 n) X
  39.     dataMatIn - 数据集
    ; P: _  R  b5 {" P5 A; u8 E+ f2 b) G
  40.     classLabels - 数据标签- ^+ s9 ?" O! W
  41. Returns:( B6 m+ r$ o: y. s8 D3 @+ c
  42.     weights.getA() - 求得的权重数组(最优参数)/ \4 p6 b0 O; O* x
  43. """) O  d3 W) e7 R, s3 h- E2 w5 ]- h; p
  44. def gradAscent(dataMatIn, classLabels):' x# Y9 t7 B0 h( N' |
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat
    $ P+ Q5 {# c( u% z5 q( |
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置
    0 \! {0 m) Z8 n6 k" {0 A$ E
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。
    , U8 F5 U8 A5 t+ P
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。) k% [1 f) W) b. L1 W
  49.     maxCycles = 500                                                        #最大迭代次数% V' `; E4 ?+ ?. j& y# r
  50.     weights = np.ones((n,1))6 N7 f) T1 m4 h! s3 ~0 c
  51.     for k in range(maxCycles):
    ( ]9 M7 I( b0 s+ S+ S6 R) Y! V
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式
    4 o2 b9 u2 Q. d2 `# n) g6 t( Z3 B
  53.         error = labelMat - h$ C( R1 j, Y9 ]: J% M$ t- ^4 {
  54.         weights = weights + alpha * dataMatrix.transpose() * error1 t4 Q" O* T; T' T6 q% f
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组/ |1 ?, u  A: B% x7 N7 N1 h

  56. * ]/ Q3 q3 Y8 s- q$ M0 D4 ]8 L
  57. if __name__ == '__main__':9 Q9 O; s* y+ F; `) H5 d
  58.     dataMat, labelMat = loadDataSet()           ( g$ t& k9 |; s' {8 ~: U: f  U
  59.     print(gradAscent(dataMat, labelMat))9 F' P: B0 @& _3 {$ w5 r
复制代码
运行结果
  1. [[ 4.12414349]
    , X7 [: y  v1 S! B1 C. N' X
  2. [ 0.48007329]
    , B5 L5 L/ L9 D+ P: b6 Y+ t0 _
  3. [-0.6168482 ]]
    / l; o+ T+ E- x" d5 A
复制代码

8 l" V2 ~' p3 y) g3 h2 z8 n8 i* T




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