数学建模社区-数学中国

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

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """
    * j' f  P& k9 I" D7 |7 Y3 b2 D' M
  2. 函数说明:梯度上升算法测试函数
    # u! {# _0 x& v5 o

  3. # L: L' j3 |4 S) M
  4. 求函数f(x) = -x^2 + 4x的极大值4 k+ I/ r& Z4 `: D  x; ?' c% N
  5. ' d' T: K4 m  a
  6. Parameters:4 d$ z4 I; ]: T' ~5 u+ o
  7.     无
    4 n4 O$ B% T/ W0 @4 l9 y
  8. Returns:' {9 R6 A9 O( Y; }- R
  9.     无
    ) X) x4 L5 C4 }9 [/ p* {- M
  10. """, X* c$ T1 U5 {3 q2 U7 ]
  11. def Gradient_Ascent_test():! k  r1 ?- |% E
  12.     def f_prime(x_old):                                    #f(x)的导数
    - m* r* R# v. _7 E2 x: `8 K# r( W
  13.         return -2 * x_old + 4
    0 Z9 `/ D% O: D, k& }  A. y
  14.     x_old = -1                                            #初始值,给一个小于x_new的值8 {, C# x: [3 E# Z! q: G
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始
    $ ?4 l! b* ?" r
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度( b* p+ I/ j/ v9 _1 W5 f
  17.     presision = 0.00000001                                #精度,也就是更新阈值
    ) t6 o: Z! b4 P" d" F
  18.     while abs(x_new - x_old) > presision:
    . \9 e" o7 j$ y0 P7 L2 V) }
  19.         x_old = x_new+ W0 K! S3 f" q% f7 ]9 f
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式
      r% P% h  p+ M% ?6 t9 `; s; ^! }
  21.     print(x_new)                                        #打印最终求解的极值近似值) V/ E* b* O. w) U. o
  22. 0 t% t: x6 `' x( {: O! ^7 U1 M
  23. if __name__ == '__main__':
    1 c/ C* A- }; m  z0 H
  24.     Gradient_Ascent_test()! z3 K; y6 r( g6 F* b1 b
复制代码
运行实例:
  1. 1.999999515279857  X1 O" P+ J8 B2 S
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  0
    # p7 ]# g9 y2 [. b" r. Y4 v) l$ E, [
  2. -1.395634  4.662541  1
    6 @- K, m" E7 f2 `5 v, z
  3. -0.752157  6.538620  0' v% t+ V$ ]0 {1 N9 h, X. ~4 V% R# b
  4. -1.322371  7.152853  0
    $ y6 r( [( U" T/ L. E/ c/ b' g
  5. 0.423363  11.054677  05 J; b. R8 d# T3 |  {+ p
  6. 0.406704  7.067335  15 Q& l  {5 _  ~* i- j
  7. 0.667394  12.741452  0
    1 [" k) }' v; H& t
  8. -2.460150  6.866805  19 R3 R' W& R3 g9 V& U" e5 d
  9. 0.569411  9.548755  0
    6 s/ U" x! v, R- I9 J4 ^5 l) d
  10. -0.026632  10.427743  0
    , E0 {( V: @( D
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt
    ) `- u  u+ W5 F
  2. import numpy as np" D. J. L) B$ i3 Z1 v' Y* {

  3. ( j+ h2 C" T0 ^# [- |9 ~, U) T
  4. """+ c( v7 p. B; N; w
  5. 函数说明:加载数据
    . k$ a" z. O$ i8 l
  6. ; t( `. e" P! a1 @- S; s2 [6 @
  7. Parameters:! O- @! G' q+ G5 B4 c
  8.     无7 w1 Z0 M: a: X& o/ ~: X
  9. Returns:
    . H. ~0 G0 G: M3 u  j6 `
  10.     dataMat - 数据列表" ?6 E" ~& I& k1 w- I2 `0 b
  11.     labelMat - 标签列表
    ( \9 B& S5 W. ^0 l5 W
  12. """3 Z4 Q3 I$ I- n. R
  13. def loadDataSet():
    9 N6 J$ F4 ]1 K( z7 R- L
  14.     dataMat = []                                                        #创建数据列表3 E" {6 ^, s, r# [
  15.     labelMat = []                                                        #创建标签列表
    8 O" T) ?" t* ~6 \; n' P
  16.     fr = open('testSet.txt')                                            #打开文件   
    " _: g. W& J" V/ n- y
  17.     for line in fr.readlines():                                            #逐行读取! Y+ x% U7 S/ e' w" X
  18.         lineArr = line.strip().split()                                    #去回车,放入列表, v/ q7 T. {  X: L. P' R; N1 X& Q
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据; E, F% |$ x: w4 q" h
  20.         labelMat.append(int(lineArr[2]))                                #添加标签- G& h2 |* S$ H2 |  u7 U; |. D1 S
  21.     fr.close()                                                            #关闭文件
    " C( H% i) M) l4 o2 G
  22.     return dataMat, labelMat                                            #返回3 V7 O* l8 [, |8 F/ t

  23. 3 ~, U4 Z+ A4 _! Z( P
  24. """
    ; b- M1 x: x+ S" [
  25. 函数说明:绘制数据集
    0 K; n' u$ N- v) L8 D/ C
  26. + l% }; f7 b* T' o$ w
  27. Parameters:3 w$ \: ~: K: R2 H; E* Y
  28.     无
    6 c* R# }; e1 Y: J" z1 l) V8 Z
  29. Returns:
    ; ~  Y3 A4 u9 s" \2 ~: R3 c# }
  30.     无
    0 y4 k7 t9 X( G3 d+ ~; u
  31. """
    & s& g+ N  M) Y3 }3 g1 o4 l! N
  32. def plotDataSet():0 M- s! [2 N  J4 Y1 \  G9 R' A3 X
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集4 d. x. f3 j4 n- T: H: O: f. l
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组0 b9 m  ~, w  \* f
  35.     n = np.shape(dataMat)[0]                                            #数据个数
    ) d3 X! D7 h; ^% l9 F$ \
  36.     xcord1 = []; ycord1 = []                                            #正样本, u7 [/ _0 Z; y' k7 t* W
  37.     xcord2 = []; ycord2 = []                                            #负样本
    9 E2 G+ Q; y# o: v1 n- M
  38.     for i in range(n):                                                    #根据数据集标签进行分类
    + u4 S# H: u9 A! l4 i7 @1 ^: e
  39.         if int(labelMat[i]) == 1:
    2 q/ R! S0 J8 m
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本/ P6 ]6 ~# B9 X7 m/ z
  41.         else:4 V$ k8 h& B$ y) `2 [0 M
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本
    / L% R4 x2 z1 d' q: L) r6 k- T
  43.     fig = plt.figure()
    5 [( `3 m- y4 o7 Z
  44.     ax = fig.add_subplot(111)                                            #添加subplot" j/ _- Z" n; Z4 }, u
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本3 ?* c  ~% O* i: w/ `
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
    $ o) @5 v! f) U8 S0 E4 G# y( B) A! T
  47.     plt.title('DataSet')                                                #绘制title
    " I$ K& A6 b  J8 V# O. W  S" }  {
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label4 q# r* W; A5 b8 n
  49.     plt.show()                                                            #显示" E) n5 b% o+ a( |2 ^! k. Y6 {
  50. . c# i/ B: ^$ E# Y; z8 x" T: A; M
  51. if __name__ == '__main__':
    : v8 ]: e- D! r. g& ?. x' B+ d+ o
  52.     plotDataSet()$ A% w. d) P; ?, F
复制代码
VeryCapture_20231130171817.jpg 5 ]4 z: B* i8 `
从上图可以看出数据的分布情况。假设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
    : T& i1 X. K, i2 A  h) V3 \( ]
  2. , H: d2 Q# y$ V9 ]% c
  3. """; {% ^0 V& v$ d) X: x
  4. 函数说明:加载数据
    0 ]6 q7 ]! b3 r9 K

  5.   J7 x' w5 m8 L8 C. d
  6. Parameters:
    ! b7 l5 N6 p6 M  b  r; U* r9 I5 ~
  7.     无4 r" A$ T* b  l: O! @% U4 q
  8. Returns:
    . R7 h7 `$ F- w- a5 h2 x7 X8 v
  9.     dataMat - 数据列表
    3 x5 c6 G% Y8 r
  10.     labelMat - 标签列表. u( Q  ]( ~; ]5 H6 u" b
  11. """
    4 Q1 J( x+ n5 r; M
  12. def loadDataSet():" @: j  @# w+ g5 O
  13.     dataMat = []                                                        #创建数据列表
    1 r! E- d% o( {; r5 L$ S8 A6 Z
  14.     labelMat = []                                                        #创建标签列表
    ' q9 P+ O" Q$ e8 {
  15.     fr = open('testSet.txt')                                            #打开文件   0 Z" X$ D+ O& @; @3 q5 q) Y4 v
  16.     for line in fr.readlines():                                            #逐行读取7 v  j: }+ b6 L/ m
  17.         lineArr = line.strip().split()                                    #去回车,放入列表
    - D/ Q3 V2 l/ M6 G. X# ^
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    . _- g/ \% @4 a) a# y
  19.         labelMat.append(int(lineArr[2]))                                #添加标签- S: q9 o. n, s: Z
  20.     fr.close()                                                            #关闭文件# b9 Y; |2 I. H2 l# ]* O, v5 ?
  21.     return dataMat, labelMat                                            #返回
    : V+ Y9 A! Z, K$ C& j2 @$ m0 i8 h6 B

  22. , V- Y/ n/ A+ q3 F& [( v1 x
  23. """& u# T. h* W* I9 a; f% g2 G; ]4 Q% T, b3 E
  24. 函数说明:sigmoid函数
    * x7 [& C0 F. @) I# l
  25. # B7 V: p, ~* E% e
  26. Parameters:
    3 `- ~# o7 H& d# n) i0 ?
  27.     inX - 数据% C$ l8 b8 C! U
  28. Returns:
    / g3 Y4 Q; d3 R# g' N
  29.     sigmoid函数
    7 i  @; h; a' s1 T5 ?, U$ l$ N
  30. """
    - |$ T2 I7 v! Y
  31. def sigmoid(inX):6 p" H+ ~2 U0 o0 R
  32.     return 1.0 / (1 + np.exp(-inX))
    : c% f% J5 k2 _- M# `5 _1 [+ y

  33. # v  V5 I& `" c6 U# ]6 _# Z: |( x
  34. 6 O4 |8 J# I7 S' k' e! V
  35. """5 ?% x( X: p! u$ D1 b) |
  36. 函数说明:梯度上升算法/ D1 h, J) W# x( K

  37. 0 ?/ W9 z# Y( x/ z/ S. R
  38. Parameters:8 ^- Y# x1 \7 Y2 C) B# Z
  39.     dataMatIn - 数据集* {( t" I  b- H& [+ k
  40.     classLabels - 数据标签0 _5 i% ~* ~. \! R2 b
  41. Returns:; H2 p7 F/ F1 g
  42.     weights.getA() - 求得的权重数组(最优参数)
    # S" k" A' _; t" J/ D, C! E7 O
  43. """; F5 y' _  A1 X& x) D0 |
  44. def gradAscent(dataMatIn, classLabels):
    7 k0 U+ R0 `' R/ d8 E5 W, G/ z
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat
      l& a" D" @( E. _0 f
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置
    4 Y- |+ l# _3 `
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。
    7 V3 @  a" q1 V: T
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。% @0 i/ [# k; E" G$ S3 [! H. i+ D
  49.     maxCycles = 500                                                        #最大迭代次数1 e( }" C" j& _8 R( p" ~
  50.     weights = np.ones((n,1))
    " C8 Q' Y1 k7 D/ `" b7 g
  51.     for k in range(maxCycles):
    . p: `' w: W) L$ [5 F6 y) g9 N
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式
    2 q. x; K' L; l. k  _. z* b, n
  53.         error = labelMat - h# j; G$ u. k6 p! J1 _' \0 A
  54.         weights = weights + alpha * dataMatrix.transpose() * error
    . `+ N! y, j: M
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组
    0 I" }3 y' ]1 m. Y

  56. ; n# i1 P. `" N8 o4 t( e( P
  57. if __name__ == '__main__':
    " d2 O6 `8 m& `1 e- d2 {  k* @
  58.     dataMat, labelMat = loadDataSet()           
    # B7 i; m8 z4 Q( b; U9 m
  59.     print(gradAscent(dataMat, labelMat))
    + m& K* {' e; I2 G: V
复制代码
运行结果
  1. [[ 4.12414349]
    2 e, |* S/ `. x: F- ]
  2. [ 0.48007329]- B2 y. G. L& q/ J+ w& k+ g# R
  3. [-0.6168482 ]]# l; _3 }$ B" ?" X# j
复制代码
4 F9 {3 Z. ^. S7 S) y% h( X, h( j





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