数学建模社区-数学中国

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

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """5 w' x3 n9 T/ ?: A: S5 U2 j
  2. 函数说明:梯度上升算法测试函数
    8 f2 ~8 O9 S- a/ V( _
  3. ! J; L; G0 }* F. m9 A6 a
  4. 求函数f(x) = -x^2 + 4x的极大值
    , S* H& ^; d, |0 m- ?0 P
  5. , Y) X9 M' `- F/ x" o9 Y4 w* _
  6. Parameters:7 Z7 q- Z9 K; a! y/ l
  7.     无/ ~0 i& \; b( {# q8 X9 R4 l# S* v
  8. Returns:5 {8 Q# I. U' p6 p8 m
  9.     无
    . r$ G6 E, O* v" j
  10. """
    4 p! J; i4 g/ |2 i, t
  11. def Gradient_Ascent_test():3 `+ g' V! h9 E. I. ]$ K
  12.     def f_prime(x_old):                                    #f(x)的导数9 e4 |% Y, ~( i. [
  13.         return -2 * x_old + 4* L  X3 p6 c( \+ d8 d
  14.     x_old = -1                                            #初始值,给一个小于x_new的值2 C- B8 f/ G% W5 A* c' j. x
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始# e$ ?6 d  a, D, j/ _. l4 k
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度
    6 Y! P" K6 c' }
  17.     presision = 0.00000001                                #精度,也就是更新阈值
    2 m" F7 [* z2 ]6 D
  18.     while abs(x_new - x_old) > presision:
    + e( t) s) x6 A
  19.         x_old = x_new6 I  {4 |) I* M; Z. h$ z
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式
    0 _# |3 `- x8 o+ x4 H1 u( m+ w
  21.     print(x_new)                                        #打印最终求解的极值近似值
    ) V" M3 D+ o2 |. q* O
  22. " M' R; b& Q" t& C* E4 |
  23. if __name__ == '__main__':. L0 l% ~3 r; x: L
  24.     Gradient_Ascent_test()4 |+ O( p% f* r# y! S5 n
复制代码
运行实例:
  1. 1.999999515279857
    & b0 }9 ]4 u) v- X
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  0  _0 N4 C" D. S2 v0 f% H
  2. -1.395634  4.662541  1
    ; `) r8 P! f) T* i: A
  3. -0.752157  6.538620  0
    : M5 h3 f  m+ D% G! F
  4. -1.322371  7.152853  0
    & |7 G# W' f+ k2 A% M
  5. 0.423363  11.054677  05 p+ L( H: T3 U% c
  6. 0.406704  7.067335  1
    + D; N) H4 }1 S0 u) k' o
  7. 0.667394  12.741452  0+ v# [' n$ R& P; E9 {6 R# Z; _
  8. -2.460150  6.866805  13 u2 F- _' Y( V' j# I4 k: ]* B
  9. 0.569411  9.548755  0+ E, i4 h0 x, b) I( S* C' M
  10. -0.026632  10.427743  0& H  h4 h" s# L6 j8 b
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt
    4 G, {* n8 `+ X* b" z6 i
  2. import numpy as np, T9 W5 f9 M  z  u8 ^
  3. . B' i- |# b  [
  4. """
    ; p: B3 w+ T+ |$ w9 P! n
  5. 函数说明:加载数据  m( I) r7 J6 j( d7 f

  6. , x6 s" F8 ~9 w9 ]; a
  7. Parameters:9 @0 Y7 ~% }8 ^5 O5 \, L! z
  8.     无
    : a: I( N, y3 s: ?1 w
  9. Returns:
    ' C) H/ C, u# S5 d' T
  10.     dataMat - 数据列表
    7 ]+ e( B4 d6 k* m
  11.     labelMat - 标签列表
    5 ~2 j4 _$ v8 {2 j" C# i7 a, R
  12. """) @* F; i$ r6 f+ r% M9 C! b& M* j
  13. def loadDataSet():
    " E  x. [0 v5 d7 l( T2 b9 i* f) y
  14.     dataMat = []                                                        #创建数据列表
    + m5 v8 T2 e! C. ]( r6 U( }, I, \5 S
  15.     labelMat = []                                                        #创建标签列表& e( N& a8 a) g1 c! @- S8 ~! M
  16.     fr = open('testSet.txt')                                            #打开文件   
    0 t# B8 b# H) `0 ^- d* P
  17.     for line in fr.readlines():                                            #逐行读取
    / _& P  Z6 c" b
  18.         lineArr = line.strip().split()                                    #去回车,放入列表
    ( s' g+ M; m3 x  \7 _' T2 y
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    . a7 l/ J$ }# \
  20.         labelMat.append(int(lineArr[2]))                                #添加标签, W( P& Z4 [' F; e; {1 ~/ w7 i
  21.     fr.close()                                                            #关闭文件
    + ^7 l. A3 f' j( x" O4 _
  22.     return dataMat, labelMat                                            #返回
    ( S6 i7 s5 E; Y  Y

  23. 9 z3 S3 u4 [$ w
  24. """5 o' O, R! ~# t$ G# V
  25. 函数说明:绘制数据集' L3 }3 O6 o' Y
  26. 7 l/ U2 g5 M! c# @8 S- U* @" x
  27. Parameters:+ x/ |4 ]4 y& B* V1 w
  28.     无
    . x7 v8 T2 X9 [* e* m
  29. Returns:! }( O7 L8 d  v
  30.     无5 b: _: O# P& t9 d/ T
  31. """
    1 `% e. o4 `1 B
  32. def plotDataSet():6 k2 u& f2 D$ e& L
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集$ o- B# z5 s* F5 d: [* V0 D* S
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组( l  w3 {: a/ C" {  d
  35.     n = np.shape(dataMat)[0]                                            #数据个数+ I8 P$ j1 i6 c4 r- N. U
  36.     xcord1 = []; ycord1 = []                                            #正样本8 I4 P$ ?5 O. ^9 D: ~( u& H& _1 U: p
  37.     xcord2 = []; ycord2 = []                                            #负样本. c; h( _% |& ]) m
  38.     for i in range(n):                                                    #根据数据集标签进行分类7 y) `3 f0 `7 D: z7 r& P
  39.         if int(labelMat[i]) == 1:
    * U" Y" z& y7 S" W& |; A% }4 w
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本3 Y3 [  a3 p+ Z3 s# V; B
  41.         else:, Q% y$ X! P' ]6 ?) r2 L9 w  {8 d
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本0 S9 U7 r/ V4 g+ M8 ~
  43.     fig = plt.figure()
    / W: C: n% U& N6 u; m% p
  44.     ax = fig.add_subplot(111)                                            #添加subplot6 w% m' S8 r9 u! }  K! b/ v0 h
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
    $ R& H5 ]  N- V/ y( y" O
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
    ' m1 D2 A7 F9 n  U# n( F# w
  47.     plt.title('DataSet')                                                #绘制title% S9 l: o+ V7 R* ?
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label
    0 z& x6 u# a: `$ a+ X
  49.     plt.show()                                                            #显示5 g- L& p: s, c2 b- r
  50. - x( u) J0 ~5 L& m( w( Z; J
  51. if __name__ == '__main__':
    $ g  d1 m# O+ o+ {8 n
  52.     plotDataSet()
    2 W% u4 O% I0 B$ i# i" B2 Z
复制代码
VeryCapture_20231130171817.jpg
6 c. c! m1 x( K% ~从上图可以看出数据的分布情况。假设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 np6 X; e+ o' h" d0 F( j1 V
  2.   |7 b& T! K. i; I, w1 @
  3. """3 U* o& @& j1 t' H% |( T  I2 P* x2 N4 z
  4. 函数说明:加载数据1 [. U8 O8 V( k8 c

  5. ! U' V! D% L% \) m- t1 L
  6. Parameters:
    0 v3 }0 q( ?1 _% t$ b
  7.     无4 W# X) B+ I8 V" F0 _" F
  8. Returns:
    : ^" t' X+ [+ g5 f" q+ q5 m, Q
  9.     dataMat - 数据列表5 j9 r; f! _& y: e' {$ e9 H5 `/ g' O3 E
  10.     labelMat - 标签列表
    % d9 J. B! A% B1 f' @* m! I% G
  11. """
    " u! v/ P1 o, [8 N9 {
  12. def loadDataSet():
    9 I" N% \: u9 O' }
  13.     dataMat = []                                                        #创建数据列表
    # M3 [* e. ?4 {/ M$ l- }# `
  14.     labelMat = []                                                        #创建标签列表
    9 ]' a: g; R: t- L2 X- O
  15.     fr = open('testSet.txt')                                            #打开文件   
    ; O. I) c* `( n+ h1 p
  16.     for line in fr.readlines():                                            #逐行读取6 W6 {: E2 T' d7 ]1 E3 e
  17.         lineArr = line.strip().split()                                    #去回车,放入列表) o- p7 J/ m) v; [  L" ^
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据2 b% M9 u% A8 j5 a& {; \' V
  19.         labelMat.append(int(lineArr[2]))                                #添加标签
    . [$ e% S- ?4 p! }6 m
  20.     fr.close()                                                            #关闭文件
    + l0 u" i9 W+ [  U3 V& m) a( F" o
  21.     return dataMat, labelMat                                            #返回
    ) m* R1 j  Y3 O

  22. 8 ]' N$ `/ d% I* g' ]6 i# A8 v4 m3 m
  23. """" d/ X: ~  l8 d! I- b4 k# i& l
  24. 函数说明:sigmoid函数
    1 u! }, X4 ~  e  C# s3 r

  25. ) ]6 E, `- m6 n/ e4 Y1 z; g
  26. Parameters:
    / }# u9 b1 ]- [* w2 P
  27.     inX - 数据
    ; ]$ f  \5 D8 E1 K1 b
  28. Returns:3 o; u9 V2 T( i+ Z
  29.     sigmoid函数. Q3 K% U! e6 |. P) t2 g) j1 t
  30. """
    6 Y: p% n' X9 y8 R4 D7 d+ m
  31. def sigmoid(inX):+ ~- d" a' r* C
  32.     return 1.0 / (1 + np.exp(-inX))
    ( ^9 i. J6 k  H4 N

  33. ; v3 M# B6 m( u( [

  34. ! b, z. n! ^! ~
  35. """3 i( o: k7 b; y1 f  H
  36. 函数说明:梯度上升算法1 l: [7 Y1 Y+ l* z8 n% }" S

  37. ( d2 k+ f3 R3 _1 f7 \7 N( }! j
  38. Parameters:
    $ u+ P2 y0 }* w. P9 M
  39.     dataMatIn - 数据集+ c) z" @* t* d7 f$ U
  40.     classLabels - 数据标签
    4 a6 X) L& n; b# I, c" |# K
  41. Returns:
    ! D1 S  ]) f! C* o6 v1 p
  42.     weights.getA() - 求得的权重数组(最优参数)
    # Z, Y0 H+ A  K1 Q4 C& y/ G0 c; U7 o
  43. """
    5 |, {0 X  l7 e9 g* I! n
  44. def gradAscent(dataMatIn, classLabels):0 k/ |! w9 @2 [# Y/ R1 c
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat4 p! ]# G& `& `8 t* T+ B
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置0 m5 t/ e+ w* R# u8 }5 ?3 i; N5 ~
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。
    * @6 z9 V; |. G$ @
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。5 O: x0 f7 c5 B; [
  49.     maxCycles = 500                                                        #最大迭代次数
    2 E, T* e5 k* D. M: O: E2 P. i- c$ N
  50.     weights = np.ones((n,1))
      R. N3 o. H- F( i/ L) M8 R, K
  51.     for k in range(maxCycles):
    " D  O) |: P# w$ C! w0 c
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式
    ' }5 `8 Z* c% c8 p% A
  53.         error = labelMat - h2 j' B+ N. |. {) E* {- r9 J
  54.         weights = weights + alpha * dataMatrix.transpose() * error
    0 [% r) c# M. y; P
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组
    9 z& i- O5 t9 x+ E2 ^8 V! `$ H/ ~' p- D
  56. 6 P3 P" N1 t$ t" ]' d6 V7 e
  57. if __name__ == '__main__':
    % {3 f  Y9 `! P# q6 U* f
  58.     dataMat, labelMat = loadDataSet()           
    $ K' l/ }8 Z3 d
  59.     print(gradAscent(dataMat, labelMat))
    . M8 @3 G# }. H1 V
复制代码
运行结果
  1. [[ 4.12414349]" s  Y/ Y, _! y7 }' o/ u8 [
  2. [ 0.48007329]4 s( Z/ g  F+ ]6 x* B/ E7 l; K7 d
  3. [-0.6168482 ]]# Z1 R& S5 u8 f% J3 Z
复制代码

* K  J$ V" w# e+ F1 B3 C




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