- 在线时间
- 481 小时
- 最后登录
- 2026-8-25
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7859 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2946
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1177
- 主题
- 1192
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
- """ F+ G1 a+ h& y* x; W x
- 函数说明:梯度上升算法测试函数
( N, @' Y5 s5 ~, P# ]
- A8 _% m# ]( o: I\" }% ~: c- 求函数f(x) = -x^2 + 4x的极大值
& r% Y2 B8 B/ ]% E - 5 U5 s: M5 K* ~1 ~
- Parameters:1 Z$ X- ^1 B/ Z
- 无2 n0 p3 k6 ^) ^, D$ x
- Returns:; R* m% @& v\" Y; U9 @9 X9 d
- 无\" `: z' C* Z; X* _
- """
0 }/ s4 m: X0 B9 Y) y - def Gradient_Ascent_test():$ ^5 g, ~9 H' ]5 F& P1 X\" A
- def f_prime(x_old): #f(x)的导数
. b5 R\" B- m4 _! }# \2 c3 i0 G - return -2 * x_old + 4. |( I& [8 M$ ?# t6 B4 g! m! R
- x_old = -1 #初始值,给一个小于x_new的值
' V$ r6 `* g- ?) q - x_new = 0 #梯度上升算法初始值,即从(0,0)开始
2 }. H\" Y6 M4 b- E, e) G8 U% o+ F! e - alpha = 0.01 #步长,也就是学习速率,控制更新的幅度 T( G' }; T8 q& m0 q4 }; [' Z
- presision = 0.00000001 #精度,也就是更新阈值
8 |$ o8 h% W) W* h - while abs(x_new - x_old) > presision:. e( e6 Q; Z3 m$ l\" ^
- x_old = x_new
_/ B3 O5 ], b% c# B( H$ d% l* Z) @ - x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
( u' ~ A0 @7 h9 O7 |! x - print(x_new) #打印最终求解的极值近似值
+ O& J# M\" F\" ~( g, V - ' ?! J\" a1 ~4 Y7 Z4 C# m8 U9 r
- if __name__ == '__main__':
. d0 N: q1 ~; x% d: W0 \. j - Gradient_Ascent_test()
) B\" }\" l* @) E( c `
复制代码 运行实例:- 1.9999995152798572 x3 @6 Y* o7 I) o
复制代码 案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt- -0.017612 14.053064 0
8 G# u6 G: ~6 h1 C$ T+ A - -1.395634 4.662541 1
\" l. v1 b0 w, n$ S V - -0.752157 6.538620 0
0 X/ M0 \1 N0 C4 o' | - -1.322371 7.152853 0
+ U( m/ o# o* g, f/ Z, i- m - 0.423363 11.054677 0
6 {. P$ E1 h8 @ - 0.406704 7.067335 1
+ N; B0 {& C' w7 r. ]* Z - 0.667394 12.741452 0
' U2 ~5 d8 S. l3 q; L - -2.460150 6.866805 1
% i b# \- d6 P# p( t' @# r - 0.569411 9.548755 04 v# f9 M0 P' V; B& r
- -0.026632 10.427743 0
3 v) c0 n3 L$ V' c0 m* D
复制代码 这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。- import matplotlib.pyplot as plt
& B( y6 z) t! I, [% J- z - import numpy as np3 b. ?/ o+ H! T( ^0 X
- , z9 [$ t: r0 E9 b
- """
+ U. b: u2 F' l: }# O8 e - 函数说明:加载数据
\" T& a1 {0 ?\" H6 x9 R3 L
6 k) ?# F( ]7 |% d4 I- Parameters:
; b6 U. V+ v8 m( O/ d\" q - 无# a: _& D P* j+ j( A ?
- Returns: C( E$ B4 f$ h0 t# h5 r. D
- dataMat - 数据列表
* K) x) J6 x7 A& v - labelMat - 标签列表
4 ^) [1 e& X- e5 _* d, ]\" {* } - """
% o% Q' \5 v. c0 r1 Q - def loadDataSet(): z7 R0 z0 v6 W {
- dataMat = [] #创建数据列表* t1 P$ z% V5 g2 m' n7 D
- labelMat = [] #创建标签列表9 h0 h5 \\" y) s\" j1 \5 X
- fr = open('testSet.txt') #打开文件
; N6 g6 ~' r+ C' f) m - for line in fr.readlines(): #逐行读取
3 t4 |& g7 g9 _ - lineArr = line.strip().split() #去回车,放入列表
' W# b1 d3 W3 ]+ C0 m X - dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
& J* N1 G1 Q) a' B - labelMat.append(int(lineArr[2])) #添加标签- V6 p+ Q, Z6 K. Q! V6 A
- fr.close() #关闭文件5 `( B) A7 C0 S* e( s: J. k6 Q
- return dataMat, labelMat #返回1 _6 [% [, }( X9 i+ E7 `: g
- 1 z. d9 D* Q' S. {
- """
' A- a\" h* O6 }: S3 ^9 o - 函数说明:绘制数据集; Q\" z5 f8 |' e; u
- \" N% ?\" e. B; {; o- m$ @' S5 U; M
- Parameters:
' t$ i) H( }2 G+ n - 无' j; l' B) [\" g, u, i' O
- Returns:6 K- a. [5 i! m1 A
- 无
# \ v$ C l' h/ \% \ - """
- C5 [. [% Y# E: j S\" A. h - def plotDataSet():
\" f) F/ T\" a9 s8 z - dataMat, labelMat = loadDataSet() #加载数据集4 W# P' Z1 E5 x/ d
- dataArr = np.array(dataMat) #转换成numpy的array数组6 m6 A3 T9 K3 y5 U: c
- n = np.shape(dataMat)[0] #数据个数; w# f/ H# @* Q% l- H7 b
- xcord1 = []; ycord1 = [] #正样本; |3 C+ ?/ ~ {
- xcord2 = []; ycord2 = [] #负样本4 t, g d+ L- p\" J/ z8 W/ f* T% W+ {
- for i in range(n): #根据数据集标签进行分类
5 s: @; s2 |4 {: q: \# X5 \% }2 h - if int(labelMat[i]) == 1:
p$ J6 K8 ^) B' D. o3 h - xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本$ D, V8 {* m/ j: ]8 V5 |
- else:* L6 f8 G f1 G* h
- xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
1 P7 e7 {0 {8 l0 L* u - fig = plt.figure()
# ^9 I5 m* \, U - ax = fig.add_subplot(111) #添加subplot& a( s3 @9 Y1 z/ e
- ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本: ]* J; T' s6 U7 K( t
- ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
. q0 c6 |- m4 E - plt.title('DataSet') #绘制title
/ Z1 {; f, T3 K2 X7 c - plt.xlabel('x'); plt.ylabel('y') #绘制label
( S7 `, H! w2 w* i. l/ a\" Q - plt.show() #显示
& F) U' S1 h0 F - 4 P; ` K: \5 ]! z- K
- if __name__ == '__main__':/ I\" J% _+ d6 q8 P5 Q3 d
- plotDataSet()' f1 V. c\" }; N& p; b
复制代码
, q! c2 n5 x# |' I E o
从上图可以看出数据的分布情况。假设Sigmoid函数的输入记为z,那么z=w0x0 + w1x1 + w2x2,即可将数据分割开。其中,x0为全是1的向量,x1为数据集的第一列数据,x2为数据集的第二列数据。另z=0,则0=w0 + w1x1 + w2x2。横坐标为x1,纵坐标为x2。这个方程未知的参数为w0,w1,w2,也就是我们需要求的回归系数(最优参数)。- import numpy as np) z9 H8 I( m, W9 L. I: R( u
\" X: `+ D5 T+ J4 q; H A- """3 Z4 a; z4 L2 ^0 x( z\" k
- 函数说明:加载数据- `% j: e9 K+ O! d' C: c
: g) i1 ]* e }3 T5 f/ Z\" O- Parameters:: a* h: Z6 s. O3 A1 ^
- 无/ J% v9 h4 n7 P% s' s
- Returns:7 }6 q- T8 C; m9 d4 R
- dataMat - 数据列表) Y$ y: n5 Z s1 X0 m' ?1 _; ^\" Y! T. ]
- labelMat - 标签列表: w6 E\" \* w, o\" p
- """
9 Q9 W: W2 y3 u) r3 ] - def loadDataSet():
& w: ]. C5 s* l {+ \4 K - dataMat = [] #创建数据列表7 V- \( `5 S% n D* w
- labelMat = [] #创建标签列表
# \1 Z( f0 ?5 d) d/ j9 F - fr = open('testSet.txt') #打开文件
! z7 }7 ]; f( g0 ~ - for line in fr.readlines(): #逐行读取
1 D, X4 B1 z' S8 K: c - lineArr = line.strip().split() #去回车,放入列表- K! g3 M$ D; H. @( C' {+ s
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
8 X/ |/ k6 y0 g: f- w- I - labelMat.append(int(lineArr[2])) #添加标签
5 ~1 \) g. {/ [, l: F* m5 a - fr.close() #关闭文件
& ^6 {, a6 f+ Q! h: y7 _* G\" i - return dataMat, labelMat #返回
6 ~1 z( H0 [9 D2 \ - ; a- P; Z, `& E5 @
- """ n$ d B; a6 F\" Q
- 函数说明:sigmoid函数! I- G4 s* f2 L
% c+ s: D0 V' L; ?! q5 Y1 G9 ~9 w' [- Parameters:+ h$ p& B: l h
- inX - 数据
\" L' f) H( z5 J6 V1 w, i - Returns:7 N\" x& ?7 v8 ?
- sigmoid函数. N' Y8 ]* v: G/ U. F! N
- """
7 _+ T( W6 [+ M - def sigmoid(inX):
) s! p: T0 d' r5 S0 L# T* }6 U) V - return 1.0 / (1 + np.exp(-inX))
c# l\" R% V0 s- T6 E! r
7 ]' @: d( x$ h; J( P+ o2 E- ) S2 M5 o3 | f( b\" E1 L
- """6 L4 j! _, X) C. V' P
- 函数说明:梯度上升算法6 A/ B3 R# g9 M\" x4 G; Y
- ' r+ R1 o: @8 }
- Parameters:
! L- e8 b& o9 o& I - dataMatIn - 数据集
) e2 k4 j; D: P% D: [7 p7 ^9 } - classLabels - 数据标签
& [' T+ S, W+ V/ Z* x5 d - Returns:1 r( F. u1 J: z
- weights.getA() - 求得的权重数组(最优参数)$ @0 d' j+ O$ p0 o
- """4 g5 b2 n4 f% b& H2 F$ K8 i
- def gradAscent(dataMatIn, classLabels):
- u5 x( L; l$ g- J; ?( V - dataMatrix = np.mat(dataMatIn) #转换成numpy的mat1 ~& u2 Y7 `/ [6 a8 C. }& s, N
- labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置, b* D& g O# E) {# i
- m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。) W/ t: `3 m3 T( J' l\" ?# o, B1 I9 e
- alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。 ~7 I: W0 N! h0 h/ Y
- maxCycles = 500 #最大迭代次数/ _! s/ h) r- ] T. \# |8 n
- weights = np.ones((n,1))' ~3 N9 @5 t' B! }6 y
- for k in range(maxCycles):+ t+ f) K( i- E# I, V
- h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式. b5 y+ v; n6 K, R# T& l
- error = labelMat - h3 G3 W2 {, G4 `* L
- weights = weights + alpha * dataMatrix.transpose() * error* F; {7 N* ?, ~3 M
- return weights.getA() #将矩阵转换为数组,返回权重数组/ X5 E( {: S8 {, C0 S
; @! S! Y2 T5 S( u1 z' `, W1 j- if __name__ == '__main__':7 `. I( i9 z0 F9 @
- dataMat, labelMat = loadDataSet()
% D, G- x, t\" P; a9 A - print(gradAscent(dataMat, labelMat))
. |\" w4 {! Z0 z% [, P+ r
复制代码 运行结果- [[ 4.12414349]
8 o2 W8 D2 B! s5 m+ w - [ 0.48007329]- F/ K4 l2 r( q& B\" U* g; t( X% o2 F
- [-0.6168482 ]]* v s4 f6 h\" q: M# ?9 D( d' r8 i
复制代码
8 e R1 U* h, _ |
zan
|