数学建模社区-数学中国

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

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """
    9 j) v, @" v- }
  2. 函数说明:梯度上升算法测试函数
      r4 {0 v! G0 Z  A" b% }/ h6 y

  3. ( Y; t: o' e, d/ \
  4. 求函数f(x) = -x^2 + 4x的极大值
    & E1 m( i# l4 N/ a. t, e

  5. , [6 F4 C1 N, F; K+ V
  6. Parameters:" l/ Y) b) `$ W0 W) J6 \
  7.     无6 M. s) U# @" j- F& X
  8. Returns:
    2 N" ?# @' e  w& q
  9.     无
    $ O# y. U) A+ O. R0 b* z, O
  10. """6 s* E: o3 A! z6 ]: g2 J6 D6 S
  11. def Gradient_Ascent_test():% B  S9 r2 p0 e( ^9 F
  12.     def f_prime(x_old):                                    #f(x)的导数2 G5 }) ]0 x$ u
  13.         return -2 * x_old + 4
    " l3 a9 |4 J4 L0 P/ q/ i/ j: l
  14.     x_old = -1                                            #初始值,给一个小于x_new的值/ J% c- R# J4 w! q# g+ ^
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始
    ; Q, x0 a6 l" m
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度
    - |( n4 @2 D& r( i: U- ~% I2 N2 ^6 g
  17.     presision = 0.00000001                                #精度,也就是更新阈值
    & X/ _. @- e* K/ ^$ P, `
  18.     while abs(x_new - x_old) > presision:% v# v' c: Z6 w4 o
  19.         x_old = x_new" @8 c; j% C* y5 u
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式
    9 [2 w$ W0 g% t
  21.     print(x_new)                                        #打印最终求解的极值近似值$ J/ Y+ d) Z8 \  K

  22. : d# Y! X- W$ a8 V
  23. if __name__ == '__main__':
    8 N# q( [/ V" b  ?; c; ?3 {# [
  24.     Gradient_Ascent_test(), R6 \+ j: i5 j6 o# Z2 }8 L
复制代码
运行实例:
  1. 1.9999995152798579 T1 C$ _& B) ]; G3 M$ ]+ p7 D8 j
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  09 @$ `6 D7 S3 W# A% v. ^
  2. -1.395634  4.662541  1
    0 m+ _7 N3 F7 z; m: ?! V
  3. -0.752157  6.538620  0
    " V: b& s/ l2 [3 Z6 d- H
  4. -1.322371  7.152853  01 G/ ?0 Y1 S0 }. F" r- ]9 D. G! x
  5. 0.423363  11.054677  0
    # X3 N! g; T- u! J
  6. 0.406704  7.067335  1
    . s. ~4 W/ H% ?8 A3 F0 r
  7. 0.667394  12.741452  0; c! E" G( d1 A/ f  q1 o8 ^& J
  8. -2.460150  6.866805  1
    ; B4 k( Q! H+ F+ {6 k% l4 L- ^
  9. 0.569411  9.548755  06 h/ q4 S9 E1 v. S7 q: q9 t
  10. -0.026632  10.427743  0
    - |* \0 W. }1 E5 A
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt
    # D8 r+ U% q) C8 t+ w3 l" Q
  2. import numpy as np
    7 c6 }' [) J2 f
  3. ; i9 I' o9 \9 ~! W8 C- x4 t- D! s
  4. """
    ( T% f2 u3 w  i3 K2 M
  5. 函数说明:加载数据
    - x+ n4 _# s- m# Y- Z3 |! H' q" M, k

  6. % N5 W5 B; y9 b: {
  7. Parameters:) @# `' o& i8 |; b- k- L
  8.     无
    , B1 ^" y& }& Z) S$ F! q
  9. Returns:3 x% J' d9 H$ R+ ~+ M
  10.     dataMat - 数据列表0 A, @" I# ]- G* M( |+ m( Z. O
  11.     labelMat - 标签列表. F  ^0 {) z7 h2 t/ M9 `
  12. """1 u/ t- n# c5 r, x) L# d  L
  13. def loadDataSet():; j7 d; l' s5 O/ D7 }& b
  14.     dataMat = []                                                        #创建数据列表
    4 R7 Q- U, L4 V1 B% e! w7 l
  15.     labelMat = []                                                        #创建标签列表4 s+ N/ K3 S& H5 e
  16.     fr = open('testSet.txt')                                            #打开文件   
    ( {4 q- e/ q! C7 a* i! o" M: [
  17.     for line in fr.readlines():                                            #逐行读取! e7 Y2 ^5 ]; n* d7 _% J- q
  18.         lineArr = line.strip().split()                                    #去回车,放入列表) b) o- q5 y- p  C
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据. t9 Y' l! p0 N. ?+ F9 x0 N
  20.         labelMat.append(int(lineArr[2]))                                #添加标签
    4 `' T' P$ [, Z0 J* o; E
  21.     fr.close()                                                            #关闭文件* P% A4 B- W) ^2 J- [) T7 S% ]
  22.     return dataMat, labelMat                                            #返回1 Q4 F' E7 k7 X  k6 j- V! U
  23. * R. F4 Q7 B+ y- Z2 N* K
  24. """
    0 H, P, }5 n( y4 y
  25. 函数说明:绘制数据集& m4 C) M' U& ~$ E6 f
  26. ! U* ^, U2 q9 k  M
  27. Parameters:
    4 }) y: A. S  t+ [% p* M4 }, m6 r
  28.     无
    1 O+ S; p  p8 E
  29. Returns:
    * K' d( I) _  o* Y* T( ^8 Y% ?
  30.     无4 k: U, y2 Y. n! d
  31. """' B3 ^6 {* Y) O$ J* [
  32. def plotDataSet():: z: V8 Q8 s/ }3 n2 [/ G
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集
    * I0 b# Q6 [, F7 K1 V2 T- i$ t
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组
    + ^! ]3 F( t0 p- Z5 n' ^- R
  35.     n = np.shape(dataMat)[0]                                            #数据个数0 K: D* [2 T, }. G$ E( j
  36.     xcord1 = []; ycord1 = []                                            #正样本4 N% x  _% v, `, Z% c7 D) `
  37.     xcord2 = []; ycord2 = []                                            #负样本% W9 U4 a6 ^0 W( `
  38.     for i in range(n):                                                    #根据数据集标签进行分类! V: Z( q7 d5 {9 |0 x
  39.         if int(labelMat[i]) == 1:
    0 K4 N8 E  o% K8 I5 N
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本
    : ~, h0 b( @5 L/ X/ I9 R. p7 V
  41.         else:
    4 B% }1 W' E& h: @7 M/ w
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本# P; P" z4 g' c+ |; U/ R
  43.     fig = plt.figure()
    - Y" E$ y- Z$ m9 r! K" y/ _
  44.     ax = fig.add_subplot(111)                                            #添加subplot
    , ]+ O  [6 i# \' d; ^2 I) l
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本# k( H" c* v$ w* m1 d; j" A6 p
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
      c5 l5 @4 Y$ Y: F& P; T3 M' \
  47.     plt.title('DataSet')                                                #绘制title
    ; l" N9 G" e+ Q% p0 F% {* g  y
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label9 p) H: ?! _9 r
  49.     plt.show()                                                            #显示
    % J+ M" V9 W3 B  ?  G% S9 F
  50. 8 S8 h0 c& P/ \" T+ F- ]: u: j3 d
  51. if __name__ == '__main__':
    9 o$ {; P( f$ o& u
  52.     plotDataSet()
    - d. r: J! ?; b8 o0 Y" ?
复制代码
VeryCapture_20231130171817.jpg 9 l4 \3 K1 Z( B; N/ ^" a4 \
从上图可以看出数据的分布情况。假设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
    , Y: ~! {$ w1 W
  2. 2 V6 f: `  o0 ~- z0 L
  3. """1 _" ^1 |, w; O# C( _
  4. 函数说明:加载数据8 ]% X, ^( h$ t( g1 x$ K3 r
  5. ) b: ^: L; b$ x/ V5 }( W
  6. Parameters:$ e! K9 S. ~: b; ~6 g+ N
  7.     无
    # N' z/ \! P% g5 u% w; C* T) E
  8. Returns:$ L6 s! s6 c5 p4 P6 I, }. E" P, W$ y
  9.     dataMat - 数据列表
    . B' d- W" U! v/ e
  10.     labelMat - 标签列表
    8 r2 B, N) I6 b6 t" ]- N
  11. """& w3 I% l$ u+ @/ Q4 r' X; d- I& U
  12. def loadDataSet():
    * d6 ~- A" M4 k! P
  13.     dataMat = []                                                        #创建数据列表
    * G7 h5 b- W3 C; w& \  f( h% r
  14.     labelMat = []                                                        #创建标签列表3 x" L0 L/ m, P0 ?9 \8 u
  15.     fr = open('testSet.txt')                                            #打开文件   7 g' [; C3 X* Q
  16.     for line in fr.readlines():                                            #逐行读取
    ' z5 S' F+ |1 }8 E4 T/ Y7 L5 V1 n
  17.         lineArr = line.strip().split()                                    #去回车,放入列表3 K( q, s5 {( r2 ?8 T6 a6 e7 V
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    3 N, K6 q6 Y8 K, l' B
  19.         labelMat.append(int(lineArr[2]))                                #添加标签
      [2 \5 a: Q: ]; R
  20.     fr.close()                                                            #关闭文件
    1 F7 g. U/ x0 ?5 V
  21.     return dataMat, labelMat                                            #返回+ Q8 _3 y- V: M7 w/ s+ N

  22. : h' r: k/ W4 m+ p1 \
  23. """
      s* _2 O6 B6 Q- `* D* D) O
  24. 函数说明:sigmoid函数, o4 L5 x! G1 t3 r9 \1 Z( B9 j
  25. - {' _3 B9 U4 g) g6 ?
  26. Parameters:8 w7 o' m# N' n
  27.     inX - 数据
    6 g+ O0 G* ?, q6 m: ~2 {3 E( r6 f
  28. Returns:
    5 n/ i- u* Y, s4 H' c" @
  29.     sigmoid函数
    - b1 j4 e9 r* u- N/ H/ r
  30. """2 l6 A0 _2 U5 g/ e& s; Z9 u! g6 |
  31. def sigmoid(inX):
    ! m+ L+ N# b; [* H3 S$ i% r
  32.     return 1.0 / (1 + np.exp(-inX))# ~, f/ @& X+ j+ S  Y( o( B

  33. , h9 y' r: B; \, K  q, b8 I1 @
  34. 9 X5 t' E- }! k6 k6 h6 {, m1 b, T
  35. """
    ) F; b4 u/ z; {( i! T. v# @
  36. 函数说明:梯度上升算法" F# l9 b- Y+ ^

  37. , U& p1 B- Y2 @1 p* X
  38. Parameters:' m: X$ k" ~2 q9 r9 Z, E
  39.     dataMatIn - 数据集
    . _8 C5 g1 E! |; F9 ~3 ~' m
  40.     classLabels - 数据标签, t4 \" b5 g8 x6 a" z+ V) Z
  41. Returns:: k0 W2 F7 W6 [( j, s
  42.     weights.getA() - 求得的权重数组(最优参数)
    2 t: \: i! }  j$ ?8 h
  43. """
    + v5 C6 |" m7 V8 q! S  u
  44. def gradAscent(dataMatIn, classLabels):
    ' v% l- ?# U% ^3 ]
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat
    3 _1 b- M# _3 i2 O* A( P
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置3 K5 J6 O4 x3 L. L, z
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。
    9 J5 c% D$ n( F+ M: g* W) O+ m
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。
    $ l5 |+ r5 q4 a6 i; L- s
  49.     maxCycles = 500                                                        #最大迭代次数
    ; o, `+ M& r) o$ b$ E$ D
  50.     weights = np.ones((n,1))  q  ]8 s' R" T" r6 `  m9 R4 J
  51.     for k in range(maxCycles):
    9 Z7 s# B+ F# |, P+ f
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式7 ?; {1 ?1 Z1 v% N
  53.         error = labelMat - h5 }* P8 n5 z6 x. W- j
  54.         weights = weights + alpha * dataMatrix.transpose() * error8 o+ Z' H7 ^5 I% z. N1 r5 x
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组" K6 h7 ]( B! ]% \$ n* s# _, n7 v
  56. ) z# P# ]& _, z1 r1 ?( V
  57. if __name__ == '__main__':& J" Y' P- \7 ]& {2 W8 o5 G
  58.     dataMat, labelMat = loadDataSet()           
    ; z# u9 W8 V" }: I
  59.     print(gradAscent(dataMat, labelMat))$ Y0 P# U( p- S
复制代码
运行结果
  1. [[ 4.12414349]
    / G* q) `- ~6 |, K; T" o6 @0 n/ w
  2. [ 0.48007329]% W4 O5 n1 |& O, _
  3. [-0.6168482 ]]/ K- o1 N* G" ^0 e  _" ?$ `$ u
复制代码

$ X, m9 Z' f2 L1 N. n$ s3 T




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