数学建模社区-数学中国

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

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """
    ; Z0 |4 R- m' p3 Z' m! L
  2. 函数说明:梯度上升算法测试函数
    0 u( d; V! }5 |) D7 u+ C
  3. - U6 B: T/ W6 v- L# c& G0 L
  4. 求函数f(x) = -x^2 + 4x的极大值( D9 e  `. V- L- L0 [$ x3 r& c2 m( V
  5. , K6 j! n" F3 y- X
  6. Parameters:( D2 p" D; [# r
  7.     无
    ' |) E! S3 E* V. C9 ^
  8. Returns:1 Y4 L4 I6 a/ E% Y* o
  9.     无
      G1 S8 q* B& i4 @
  10. """
    : c& J) _9 ]+ ]" g, s; L3 Z9 {
  11. def Gradient_Ascent_test():/ E# R+ X4 g, Q
  12.     def f_prime(x_old):                                    #f(x)的导数6 H9 p& d- M, d7 k$ v7 H
  13.         return -2 * x_old + 4. X' |6 E1 J3 \. h. b, r1 H4 Z
  14.     x_old = -1                                            #初始值,给一个小于x_new的值
    9 T  Z1 b" ?/ C4 C& n( J
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始
    * q! S" V3 R' y$ U
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度
    8 ^( v! r$ z  K# E3 N* n0 X( D' }
  17.     presision = 0.00000001                                #精度,也就是更新阈值4 x' o! j: @+ s% t) i; J7 h' t
  18.     while abs(x_new - x_old) > presision:
    ( |( q! C- @8 L2 z% Q7 A" a' H
  19.         x_old = x_new
    & q/ X) m" V' f) s) q
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式
    + b# m7 d5 ^% d4 e9 Y
  21.     print(x_new)                                        #打印最终求解的极值近似值8 W3 ^* n/ w- P  _7 V- i
  22. : [2 p0 Q3 s- Y$ ?& f+ a0 U& l
  23. if __name__ == '__main__':1 Y; ]* }8 x# u4 |& O
  24.     Gradient_Ascent_test()0 V& y5 b4 U: T7 m
复制代码
运行实例:
  1. 1.999999515279857
    2 u5 ~* M1 ^" G1 U! }8 J
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  0
    5 `  v; s  Y" a1 [
  2. -1.395634  4.662541  1% z; p) ~# A" V* \# @9 C; W0 \" A
  3. -0.752157  6.538620  0
    1 d/ K' ^/ `* S+ W, M9 E
  4. -1.322371  7.152853  0- }. Q+ u* u* {
  5. 0.423363  11.054677  0
    8 N3 V0 B8 K: q: C
  6. 0.406704  7.067335  1
    % E1 h; H* l% k( W/ Q& |
  7. 0.667394  12.741452  0; ^- Z- y* F( m, t( j+ _
  8. -2.460150  6.866805  1) B9 _8 @4 M$ P
  9. 0.569411  9.548755  0/ G! z( J3 X( _* G: q  ?
  10. -0.026632  10.427743  0
    ) E7 c8 C$ m5 b) T0 k# S
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt
    ; u- O/ _4 A& I0 m" M
  2. import numpy as np
    9 c$ D, l8 K6 @; J# F  E( w

  3. ! {( K; P6 [$ F9 L
  4. """
    " M& r+ B5 S6 M, |/ f! e6 ^0 Y: Q
  5. 函数说明:加载数据5 q. I) S7 ^3 b/ _* @! m6 d3 U6 J# W  C

  6. % [0 F$ `. ~; ]9 h
  7. Parameters:' H  W* i! s+ ^6 W: o1 s7 ^& A3 r
  8.     无* V  P8 h* J5 p6 G' l- e* F7 ?
  9. Returns:2 R! Y( O# F; Y8 F8 x6 ^
  10.     dataMat - 数据列表2 q4 J. r. m& ^  q/ U* ~
  11.     labelMat - 标签列表; L7 @9 J" o+ d( j4 x, g$ U9 ~
  12. """
    ! |! _2 ?" u; }+ o1 ]
  13. def loadDataSet():
      G* p7 X9 k$ A. u6 n
  14.     dataMat = []                                                        #创建数据列表
    9 V% S/ N9 p  ?5 ?  j) U# l
  15.     labelMat = []                                                        #创建标签列表  n7 J, f9 `8 ]( n/ p; X
  16.     fr = open('testSet.txt')                                            #打开文件   8 X+ I( j* `  m- ^4 |; J; l8 \9 _
  17.     for line in fr.readlines():                                            #逐行读取+ [0 @% T3 e% z: M! C6 r) P* z( c6 r
  18.         lineArr = line.strip().split()                                    #去回车,放入列表& v: y) J, y6 l3 B
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据& Q6 I8 \0 k" j& j* H2 J
  20.         labelMat.append(int(lineArr[2]))                                #添加标签
    # M% G3 \9 }+ n# R( Z5 |
  21.     fr.close()                                                            #关闭文件
    8 J/ w( ~( I# o, d( X) H: c+ C& k$ ?
  22.     return dataMat, labelMat                                            #返回
    # |9 \6 \. F( }6 @; G8 W3 v/ ]- n
  23. % [  J- S* l" ^: m
  24. """6 s: l4 `! ]/ }% V" w
  25. 函数说明:绘制数据集$ e7 [8 B) |0 [' J( J

  26. ' a4 D9 G' _* R4 [& w: N9 _, i& D
  27. Parameters:
    / V. j# P- F, z' `3 G3 C
  28.     无
    6 d% `6 L  l/ k8 X
  29. Returns:4 F. l+ G, ]3 Z6 K3 K/ S& _
  30.     无
    2 D6 p( D4 @; o2 u& f$ w
  31. """
    $ w# w+ r1 P9 G; v
  32. def plotDataSet():
    ( C" g5 \# H' x* u8 ]1 O% @
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集
    3 {1 v9 H5 W" K
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组& N4 H' `) A" Z/ u2 f
  35.     n = np.shape(dataMat)[0]                                            #数据个数! F. M& x2 _$ c9 h" {, M
  36.     xcord1 = []; ycord1 = []                                            #正样本
    " p& R1 w3 ?8 B, k8 z+ k7 |2 Z+ v
  37.     xcord2 = []; ycord2 = []                                            #负样本
    8 W! Y' G) i5 q/ S# c6 e' [' X
  38.     for i in range(n):                                                    #根据数据集标签进行分类
    $ \' @0 [, N1 l& w& d
  39.         if int(labelMat[i]) == 1:
    ( M# ?0 X9 X, d# o) N% G1 }
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本3 g5 J$ N* A% P  ]- O4 n( f
  41.         else:
    9 E0 }9 L, _- h& v, d  Q" y
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本
    $ I; j- Q* L8 W! O1 `8 s
  43.     fig = plt.figure()* S' O: o  ^" w8 Y
  44.     ax = fig.add_subplot(111)                                            #添加subplot& @: L. \5 O* s. N( ^4 C
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
    3 s7 h3 m/ N' Z( i' o" l6 J
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
    $ U, q+ j$ B- i/ C) U# ^, P
  47.     plt.title('DataSet')                                                #绘制title
    0 X2 v" U/ f$ T: c
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label8 ~3 n" @2 m  e8 ~
  49.     plt.show()                                                            #显示" d5 D. @; p6 u8 \$ i
  50. 4 B" M+ h) k# w1 E" E) t! L
  51. if __name__ == '__main__':
    * @& ?- M/ p6 B" R, \
  52.     plotDataSet()
    ' n8 J/ f, o; G$ Q6 L: z
复制代码
VeryCapture_20231130171817.jpg & q0 U; x$ k6 _- j# b+ v
从上图可以看出数据的分布情况。假设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
    ( ?2 }0 C6 N# B5 `8 H
  2. ; X5 i( b( U: p1 N! _9 e
  3. """
    $ N' M# P8 B6 \4 T% u. _: w
  4. 函数说明:加载数据5 F6 l  z1 D" h- S$ X( l

  5. * s$ ^" l2 r* _
  6. Parameters:
    1 U$ d: g3 Y" F" g5 O
  7.     无3 {( C. \1 `; Z2 O8 Y
  8. Returns:
    6 U& ^8 G- I$ H& o! R) L- ~
  9.     dataMat - 数据列表3 L. I1 n  d, r% U1 ]2 x0 G
  10.     labelMat - 标签列表
    0 }; {. T% L/ e
  11. """
    2 }8 v2 l% E/ C( l# j  r9 C2 ~( m
  12. def loadDataSet():8 m, p5 @6 g2 p
  13.     dataMat = []                                                        #创建数据列表" t( C3 z5 j) Z6 q3 ]% k; D9 U
  14.     labelMat = []                                                        #创建标签列表
    # O; X0 n+ V3 g7 H7 [
  15.     fr = open('testSet.txt')                                            #打开文件   3 ?( S6 Q( O) i  e( Y
  16.     for line in fr.readlines():                                            #逐行读取. `% k3 q6 V2 w) O  L
  17.         lineArr = line.strip().split()                                    #去回车,放入列表
    4 U8 @1 ^% A7 l8 |& ^
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    ; w; z3 M; M' y5 u: `( N/ W% {
  19.         labelMat.append(int(lineArr[2]))                                #添加标签3 x% M8 W; {7 Z/ K; F$ G
  20.     fr.close()                                                            #关闭文件
    # {+ \: R  D+ r6 s4 k! Q6 c: j
  21.     return dataMat, labelMat                                            #返回
    5 n7 u7 I# s! O' c

  22. 4 W% \" Q+ S) t- B- o3 d$ V9 T) _
  23. """
    & {. M5 c3 i5 m# T
  24. 函数说明:sigmoid函数
    * Q# I, }7 ]# Y% P4 M3 N4 s
  25. / r: ]) Q- F! b. R4 G$ Y# \% Q, B
  26. Parameters:
    * `0 x: I  I; @. x
  27.     inX - 数据
    & @" z% n# X$ l2 _' J
  28. Returns:5 c+ ?3 G: G% N7 a2 x( i0 n
  29.     sigmoid函数. q& k4 t: \, \2 s$ L
  30. """8 C# b- t/ U& _8 Q* W
  31. def sigmoid(inX):
    6 H1 c1 ~* x% t. [, t) H
  32.     return 1.0 / (1 + np.exp(-inX)), J6 U  h/ R5 B- n. B& A6 _( |) Z7 E
  33. # X- }% B. C$ w2 ?9 u
  34. ! z* L8 l7 s) ^( ~, X. J) O
  35. """# G' N( u4 X" {8 h9 f2 T, O
  36. 函数说明:梯度上升算法4 g( I$ X# D0 j" w* F  y7 h

  37. 3 {: d2 c6 ~1 c! L: B; T/ l
  38. Parameters:  S4 ~7 G& R5 j$ c, u
  39.     dataMatIn - 数据集3 Q% v: g. V/ {7 }# u- n$ @
  40.     classLabels - 数据标签
    & {% s/ c4 [% |/ w8 _
  41. Returns:
    9 u+ V& K* I& z. l6 L( w; y* x
  42.     weights.getA() - 求得的权重数组(最优参数)
    ; w9 R6 q7 c, K$ h1 R" I
  43. """9 n; ?9 s9 U5 m! u7 e( _
  44. def gradAscent(dataMatIn, classLabels):
    & F, U: }  C' y) t% W; M
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat1 [7 b% C( a) w
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置
    7 h) Q6 {7 S- [. R! q0 a- ?. d: a/ b
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。+ W3 ^7 g7 m9 [! k; w  r
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。
    - f) o2 C3 ^, G3 k4 n! G8 L
  49.     maxCycles = 500                                                        #最大迭代次数
    * ]! z. O' D& k5 M3 F* g
  50.     weights = np.ones((n,1))
    ' ]" i9 W; Z3 X: D+ {1 z
  51.     for k in range(maxCycles):
    1 \" Y; s7 C. ^) K
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式
    + [9 x9 u) o1 Z/ c
  53.         error = labelMat - h3 q7 g6 B! k1 e& k
  54.         weights = weights + alpha * dataMatrix.transpose() * error" [1 a( v+ S4 N! {2 E+ ]9 |6 n
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组( M3 d4 H) k8 n" I$ ~, G
  56. 4 m! O0 o) z, S* X9 s0 {
  57. if __name__ == '__main__':# `% P, `6 q2 T
  58.     dataMat, labelMat = loadDataSet()           
    0 H2 [  W% h5 f0 g
  59.     print(gradAscent(dataMat, labelMat))
    0 v3 N- h/ c$ d" X
复制代码
运行结果
  1. [[ 4.12414349]; ?) W: f+ x" f
  2. [ 0.48007329]: r, v8 U) Z" M1 V
  3. [-0.6168482 ]]
    " R6 K! n, x4 p: C6 j( @
复制代码
9 o5 {- m- v. ]7 d3 q( `, j





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