数学建模社区-数学中国

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

作者: 2744557306    时间: 2023-11-30 17:30
标题: Logistic回归--实例
VeryCapture_20231130171540.jpg
  1. """
    0 f0 {* N0 r/ {" L9 V
  2. 函数说明:梯度上升算法测试函数
    # B) }$ v" v4 K" ~

  3. ! R3 Z, |& P0 c: Q% ~
  4. 求函数f(x) = -x^2 + 4x的极大值& K6 e2 b; J  N
  5.   s; S9 h6 j8 _" j
  6. Parameters:
    7 f  F! [* H, w1 c  I
  7.     无' O( P9 O& I& j4 G1 q1 c! F, s
  8. Returns:4 O2 ]+ X2 F+ Q$ N  m2 e/ w9 H
  9.     无
    9 ^: a. Y: X, z2 \+ F
  10. """
    ; B" w! h" y% r6 o5 s
  11. def Gradient_Ascent_test():; e. H* o: M( s! E3 e- G- j
  12.     def f_prime(x_old):                                    #f(x)的导数
    . j: o( Y0 G, e. A% C: e7 ?
  13.         return -2 * x_old + 4& L/ O8 U! i0 f) W* c, ~+ x; @2 S
  14.     x_old = -1                                            #初始值,给一个小于x_new的值
    * c# r; ]) ]9 A3 \+ K
  15.     x_new = 0                                            #梯度上升算法初始值,即从(0,0)开始
    $ p1 {) U- b9 b2 [) U
  16.     alpha = 0.01                                        #步长,也就是学习速率,控制更新的幅度& a0 r8 }, T6 d+ l
  17.     presision = 0.00000001                                #精度,也就是更新阈值* G9 Z6 x! n& k: m
  18.     while abs(x_new - x_old) > presision:$ r3 _7 _2 w, n! j- f& g. {
  19.         x_old = x_new
    6 l5 M6 f. s- W6 K) s) N
  20.         x_new = x_old + alpha * f_prime(x_old)            #上面提到的公式4 d* l3 `6 y7 l( _; r. Z
  21.     print(x_new)                                        #打印最终求解的极值近似值* q  Y1 U" H2 O  W
  22. % H. B+ L+ V1 H' Z$ B
  23. if __name__ == '__main__':
    : `- b+ H) s: G% ]1 V3 M
  24.     Gradient_Ascent_test()" K! f( x; d/ z/ K2 ]; }# K
复制代码
运行实例:
  1. 1.999999515279857
    % k2 Z3 e7 i$ e, F- @- B3 c
复制代码
案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
  1. -0.017612  14.053064  0
    * `  Z& @7 c; ?/ q
  2. -1.395634  4.662541  10 x) N6 F$ C6 f& V, |  A! [/ M* |
  3. -0.752157  6.538620  0" p0 h$ F$ G) V; K; P" _6 i
  4. -1.322371  7.152853  0
    6 j# k& ^  h& P2 \7 R
  5. 0.423363  11.054677  0. K0 c0 }7 g3 T8 n
  6. 0.406704  7.067335  1
    - Q3 w) l1 q/ [1 [: {, J5 C
  7. 0.667394  12.741452  0
    " S  T" ?0 u4 Y9 @
  8. -2.460150  6.866805  16 e; }# P  T# U& e# O
  9. 0.569411  9.548755  09 i3 M  k+ a" A/ V0 Y
  10. -0.026632  10.427743  07 t3 s, p0 d9 F( V" B2 O) |
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
  1. import matplotlib.pyplot as plt5 e' u. Q0 f" X/ Z$ y2 W. q- s/ e( C
  2. import numpy as np# ^. }% W( p/ _& k6 [3 E
  3. . a  V. Q9 E& ], V- E
  4. """/ G5 ]7 O5 `) H7 k) A# R
  5. 函数说明:加载数据
    ( h0 y& N! @+ c: I7 k( o2 Y
  6. " U! E% ?, |: s- }  _
  7. Parameters:' c/ A& h1 q# E! b% ^+ n' T! E
  8.     无. D' @& K6 r7 E$ ~
  9. Returns:
    3 m8 I' X, n1 i! O: F: W
  10.     dataMat - 数据列表
    9 Z: Y2 ^$ u  P$ a
  11.     labelMat - 标签列表
    ) G( {. Y. }- P. @6 ~8 J- u
  12. """
    & j* d+ ?8 p0 @
  13. def loadDataSet():% q" Z7 [" n0 A* C. e8 @
  14.     dataMat = []                                                        #创建数据列表  j. r& k" y  q' x  E' \& f6 T- f' d
  15.     labelMat = []                                                        #创建标签列表
    / v+ ^& [/ U7 d" v4 M2 ?9 `
  16.     fr = open('testSet.txt')                                            #打开文件   / W9 X" M3 g( ]7 V# _- g2 a
  17.     for line in fr.readlines():                                            #逐行读取
    $ {1 C" I8 o& d, D; i0 h9 h6 f
  18.         lineArr = line.strip().split()                                    #去回车,放入列表
    1 `& O; Z, B) r, n7 {
  19.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    ' k$ `$ q' U& e/ a
  20.         labelMat.append(int(lineArr[2]))                                #添加标签
    ' C% j4 J  i' b1 M7 ^" c6 E
  21.     fr.close()                                                            #关闭文件
    ( k8 J& V, Y: |; x% G9 c
  22.     return dataMat, labelMat                                            #返回
    9 h  ?; O1 F) g8 v' j5 U
  23. " o) Z1 ~4 Z' O$ E& }
  24. """+ f$ T+ J$ c* H( e. H
  25. 函数说明:绘制数据集' d+ {4 p  i0 B
  26. . o& x- d  ]8 V% N: z6 ~
  27. Parameters:' `: p, Z1 W+ C9 I
  28.     无! M% D" x3 f/ z4 M5 q& v
  29. Returns:
    6 U6 `" z5 V! n6 a
  30.     无; U$ b; T. u5 S  z
  31. """. o/ O3 X. f6 w8 H2 A
  32. def plotDataSet():
    / M3 ?. [- I7 l) C! h
  33.     dataMat, labelMat = loadDataSet()                                    #加载数据集
    + v# |) U; u7 e/ \, @* p
  34.     dataArr = np.array(dataMat)                                            #转换成numpy的array数组4 T. [% o; m+ I  W
  35.     n = np.shape(dataMat)[0]                                            #数据个数- a% E8 O; y4 a1 S- P
  36.     xcord1 = []; ycord1 = []                                            #正样本
    / w2 _- y% h4 ], B1 R* c5 s9 z! ?4 g! w
  37.     xcord2 = []; ycord2 = []                                            #负样本
    $ [% d) g4 k; G- j
  38.     for i in range(n):                                                    #根据数据集标签进行分类. ?: I3 L2 N7 y' `3 `
  39.         if int(labelMat[i]) == 1:- z6 v2 Z8 c6 C& a: E, T5 C
  40.             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])    #1为正样本" k* q: x1 b* m3 w
  41.         else:
    % |: N0 o& y6 P% |0 k, [/ ^( j2 y
  42.             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本
    4 I- F. r) t' D( S- W5 h
  43.     fig = plt.figure()
    % d/ ]7 Y9 l6 L" S% g5 D
  44.     ax = fig.add_subplot(111)                                            #添加subplot
    6 U1 X% G) \' y$ p" |
  45.     ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
    " D* A, R5 j5 p
  46.     ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本) o% U+ C6 s5 P
  47.     plt.title('DataSet')                                                #绘制title
    - L6 U% v8 @* v- n/ U8 u. h, m
  48.     plt.xlabel('x'); plt.ylabel('y')                                    #绘制label
    6 H9 E5 C' ]) W5 o2 H9 N: \  R
  49.     plt.show()                                                            #显示
    : A; F* L4 ]! C( f3 y/ m% B, q

  50. / S, G& `1 _9 Q! j
  51. if __name__ == '__main__':8 _, m: Q9 W  {; |
  52.     plotDataSet()
    1 R/ c; M5 D! ~2 ]0 F, s
复制代码
VeryCapture_20231130171817.jpg
: m1 t. F" x2 x从上图可以看出数据的分布情况。假设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
    * `# h4 r2 A4 U% i
  2. % n: M: S# b2 e, U+ h
  3. """8 i0 W! O3 l: C6 N) e( \7 s
  4. 函数说明:加载数据
    % n4 ~" ?" {" h" `

  5. 0 ~( N& S( q8 I( c
  6. Parameters:
    4 w4 W- \4 S) j- K6 ]: k8 d" ^
  7.     无
    + e4 G2 k9 U9 E8 p: X
  8. Returns:
    7 }! u: F4 D/ t; E1 K' h
  9.     dataMat - 数据列表
    & I* V; {: B7 E
  10.     labelMat - 标签列表
    ) G4 o2 e& a) I7 d2 h& i
  11. """+ {0 f- K6 W: b# T
  12. def loadDataSet():
    8 X3 S: R5 |9 N. e3 |4 C! X
  13.     dataMat = []                                                        #创建数据列表
    " i& _: A5 R- [. ^
  14.     labelMat = []                                                        #创建标签列表
    4 @! [9 k+ r9 W
  15.     fr = open('testSet.txt')                                            #打开文件   
    , [0 B( b. M9 i: M; V3 l
  16.     for line in fr.readlines():                                            #逐行读取
    2 U& e, V! n7 ]8 q! ~
  17.         lineArr = line.strip().split()                                    #去回车,放入列表7 R! L* K( k" [# M6 Y
  18.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])        #添加数据
    9 T  g  n, i6 b' h& ]% k" t
  19.         labelMat.append(int(lineArr[2]))                                #添加标签7 N6 E) n% t3 o
  20.     fr.close()                                                            #关闭文件! h7 ^, }7 H  b
  21.     return dataMat, labelMat                                            #返回4 S3 M; `( |/ S

  22. ! H8 D3 ?5 _8 K5 n
  23. """
    * Y  S( }4 _' R- K0 s; I+ {/ K
  24. 函数说明:sigmoid函数
    % U+ a1 x' j% W  U3 t9 W
  25. . u& M5 c, G7 q
  26. Parameters:
    , U* S# o3 j5 d$ Y. ?4 M- _
  27.     inX - 数据
    1 \: F  A& f# o
  28. Returns:
    3 U; p( g" o3 [7 D5 a) S
  29.     sigmoid函数5 e. _3 s+ ]2 O7 p4 m' u( z
  30. """
    7 \, \/ h; d: x9 z, a/ u$ P
  31. def sigmoid(inX):
    - z0 t9 n  M6 R$ |1 ]
  32.     return 1.0 / (1 + np.exp(-inX))
    4 l6 i5 D  G; u
  33. ( T$ I6 o* x; r6 V2 i
  34. 4 b: H$ Y4 g& C
  35. """
    ) o" A+ M1 H0 l& ^
  36. 函数说明:梯度上升算法
    1 v$ [( e4 p$ O

  37. : F  d& A: I& G: O5 K
  38. Parameters:
    " h5 p: V; ?. m: o6 T. d: j
  39.     dataMatIn - 数据集9 Q" Z# f6 s+ C, g  `/ E0 W+ `
  40.     classLabels - 数据标签
    ' ?* u& G+ W% Y4 f  P6 E! o/ L5 D
  41. Returns:# z8 K( |9 }5 R/ D0 A( A0 m( ~$ Z
  42.     weights.getA() - 求得的权重数组(最优参数). d0 J1 _3 ^2 J7 r
  43. """
    $ ~. Z, c; O3 e( ?8 b% i
  44. def gradAscent(dataMatIn, classLabels):
    % H+ X3 B$ o: t
  45.     dataMatrix = np.mat(dataMatIn)                                        #转换成numpy的mat
    8 x9 i% `/ x0 b4 @5 I! R
  46.     labelMat = np.mat(classLabels).transpose()                            #转换成numpy的mat,并进行转置
    3 K7 I- E0 S6 Y9 Y& p8 ~1 ?* g+ a6 X
  47.     m, n = np.shape(dataMatrix)                                            #返回dataMatrix的大小。m为行数,n为列数。
    5 S# Z$ g6 Y& E1 D; x- }
  48.     alpha = 0.001                                                        #移动步长,也就是学习速率,控制更新的幅度。: a: @# l6 A% B
  49.     maxCycles = 500                                                        #最大迭代次数
    ; t( w, X, `: a8 j
  50.     weights = np.ones((n,1))
    " |( u0 h0 q3 }3 O
  51.     for k in range(maxCycles):
    1 B, _7 E' u% x5 `3 g9 P, U
  52.         h = sigmoid(dataMatrix * weights)                                #梯度上升矢量化公式- R4 f) i3 x$ ?! I5 l" Y9 K% r7 [& S
  53.         error = labelMat - h- f) _/ c3 z+ O! U% d/ O
  54.         weights = weights + alpha * dataMatrix.transpose() * error
    # v7 Q  I! g+ z+ q/ L, q
  55.     return weights.getA()                                                #将矩阵转换为数组,返回权重数组" g. q4 ~" J- m" m  Y

  56. ! ?/ L# p( m4 S9 [
  57. if __name__ == '__main__':
    : c, h- P7 S/ V4 L: ?1 V! e% c
  58.     dataMat, labelMat = loadDataSet()           
    / o7 a4 W$ x3 H8 y
  59.     print(gradAscent(dataMat, labelMat))
    ' Q$ x0 C" I. Y. F5 {- K
复制代码
运行结果
  1. [[ 4.12414349]
    7 s! p/ ~8 g6 E3 @. q
  2. [ 0.48007329]  k! \/ _/ p+ P! Q3 C- W5 M
  3. [-0.6168482 ]], q3 S$ v8 U$ g1 l6 L9 Q9 R
复制代码

: ^$ R  I' K; C( }% G! X! g' I& e8 W




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