- 在线时间
- 478 小时
- 最后登录
- 2026-4-9
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7788 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2922
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1171
- 主题
- 1186
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
- """! ?2 T; a9 v; x* n
- 函数说明:梯度上升算法测试函数' h; \6 n( W- T( O( |
- % I, n5 L6 S4 b- L
- 求函数f(x) = -x^2 + 4x的极大值
; L, [$ L6 p4 {1 ^: o$ m
1 c! O- l4 s9 q+ S3 g9 Y- Parameters:4 u; s7 X3 `' s. s3 c
- 无
8 s6 v6 Q* K+ y2 L - Returns:& i5 W& f; u% ?7 l; m) D. H8 Z
- 无+ g$ W+ M! D) B
- """8 [4 C\" r6 A# k3 E9 J, A: S) @
- def Gradient_Ascent_test():
' r\" f% D! e, Y - def f_prime(x_old): #f(x)的导数' }/ \* r0 J$ N
- return -2 * x_old + 4
- H5 D9 v- y7 r- k, Q/ V - x_old = -1 #初始值,给一个小于x_new的值
0 \1 Z\" F& Z! U+ ^! e9 g - x_new = 0 #梯度上升算法初始值,即从(0,0)开始6 v C$ K5 |( o\" o6 W# l0 o
- alpha = 0.01 #步长,也就是学习速率,控制更新的幅度
5 @) I! E' {2 v4 @* f3 S - presision = 0.00000001 #精度,也就是更新阈值7 J5 `1 ?/ E( P- @8 g0 }
- while abs(x_new - x_old) > presision:
9 J* _4 ?! L2 R6 f- X# J: T$ O - x_old = x_new
]( F: { E# |/ F9 ~# Y - x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
2 [\" n9 p/ G- f6 u) y( m- w - print(x_new) #打印最终求解的极值近似值$ l/ C. x* U& M5 t\" A
- ! n* K/ q' B+ t; n( q8 v
- if __name__ == '__main__':4 S a# E/ b: R! P% U6 Q! o
- Gradient_Ascent_test()& s\" B7 s+ L: r+ A* t
复制代码 运行实例:- 1.999999515279857
; Y# V1 `7 ^1 _4 ]0 k; L: p8 ~# H
复制代码 案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt- -0.017612 14.053064 0
. g; I$ w9 X) D4 r# V, D - -1.395634 4.662541 16 C; V3 E. u2 d( P) f9 X; }# r
- -0.752157 6.538620 02 R$ b% n0 f9 }# T3 r
- -1.322371 7.152853 0
5 s0 Z' _\" v+ A, Q - 0.423363 11.054677 0- @3 Q1 j- G0 ]! A
- 0.406704 7.067335 18 d0 ^5 X: O2 Z3 n) g$ p\" h
- 0.667394 12.741452 0
/ o* P* i+ m6 N( O - -2.460150 6.866805 1( P, l- A) x' o; x! _ H
- 0.569411 9.548755 0% ^- Q) B, M2 d1 h3 W7 y* o F
- -0.026632 10.427743 0
8 H4 j\" |) j% m9 K
复制代码 这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。- import matplotlib.pyplot as plt
7 G# V c+ Q! F - import numpy as np
2 C\" V; b/ g) a& ]
6 S- t4 c/ `2 [\" e) T) b7 g- """
\" \% E5 o3 k: L\" @8 @$ R - 函数说明:加载数据
8 _/ t6 u6 i- f5 b5 a5 v! D - \" m+ n& v3 p, i9 i5 O
- Parameters:# `. F! d$ F G, A! {: w- _
- 无
/ j. m- Q\" _5 s: c* r - Returns:
4 x+ X% L* Y! x+ u - dataMat - 数据列表
% U9 m# J. R& R- y- U( t; { - labelMat - 标签列表
/ P( v# k5 [3 {! X% x - """
% l3 E+ B+ Q8 ] - def loadDataSet():
) O9 [/ z: V- Z+ X- k: P0 [9 j* w: @ - dataMat = [] #创建数据列表. X! z% \0 | d* b3 X
- labelMat = [] #创建标签列表
) l4 t( `6 k$ M0 e - fr = open('testSet.txt') #打开文件 % `1 ]: Z: O0 j+ q) f) C6 ^
- for line in fr.readlines(): #逐行读取5 O' B) u* I+ x\" X\" l& }
- lineArr = line.strip().split() #去回车,放入列表
u' a\" l2 R\" L - dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据: ~& N# {( f! B) P& `# r
- labelMat.append(int(lineArr[2])) #添加标签\" v: k/ W; T0 l
- fr.close() #关闭文件7 u. Y& A6 t; C
- return dataMat, labelMat #返回6 H; S3 F6 Y- n3 u2 g/ s2 H
( K3 b! s2 N& r M5 F4 \. P- """. J8 C) J6 l- T! ` ?
- 函数说明:绘制数据集
8 N' l. O: Q5 d$ n
/ u6 j8 d. y; ?- `\" y- c- Parameters:
: x0 ]$ k- J% E; [ ] - 无' M7 ^3 _/ _. B! c
- Returns:
/ m: e# V# ]0 [ - 无\" U4 c- O8 E! [$ E. y
- """
: Q, w\" n# }/ V/ ?% e: C - def plotDataSet():* f3 a2 P9 `! J! p
- dataMat, labelMat = loadDataSet() #加载数据集- x- |3 }. u; r
- dataArr = np.array(dataMat) #转换成numpy的array数组
% W% h: p% \9 Q% L# d0 N* M - n = np.shape(dataMat)[0] #数据个数7 _4 D7 Y q+ b5 O: b7 @1 |- q
- xcord1 = []; ycord1 = [] #正样本
9 z7 w: N5 ]# _9 c+ R0 D - xcord2 = []; ycord2 = [] #负样本
( W% ]5 c/ M0 } - for i in range(n): #根据数据集标签进行分类\" Y# A/ \) T+ ?& X8 _% y
- if int(labelMat[i]) == 1:7 `- s4 t2 f) j9 V- ?! q\" k
- xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本
7 h& N2 g7 _3 p+ m - else:5 A' |( Y# N O6 A. u- }
- xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本0 v4 l& R0 ]/ W4 }
- fig = plt.figure()
# t0 w r- r/ H9 D$ h - ax = fig.add_subplot(111) #添加subplot
' O- G. D; Y5 i2 u - ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本 J7 S) m0 P\" z0 M: U
- ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
T+ E& F- W% M1 T! T - plt.title('DataSet') #绘制title; T0 v; q6 J5 E$ b& [! v
- plt.xlabel('x'); plt.ylabel('y') #绘制label7 {! r- M2 U7 v: t
- plt.show() #显示
/ l0 n P& k* B% M4 q' l. }
1 p! t& n3 @! E; E5 c- if __name__ == '__main__':7 f4 g4 I) C! N' a& G4 x8 X
- plotDataSet()
0 i; T' m5 q* w# U( b# x
复制代码
$ S: H; T h0 F2 k
从上图可以看出数据的分布情况。假设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
9 g/ Y0 E, I' B2 ? - ' O\" C0 _* j2 }: ^
- """\" l+ Y2 S. z# w% w6 |5 P1 B
- 函数说明:加载数据' c- I\" k( F7 v: J9 t; m
- 8 h8 K1 {; E; N. u1 R: A
- Parameters:- l+ n* m\" }: D2 l, n% L) F( y
- 无
; Q6 V' h9 z' S2 J - Returns:' `% [& P# _6 b2 }5 a0 D. _
- dataMat - 数据列表 n: S9 S5 [+ \: z+ {- i7 r
- labelMat - 标签列表. L8 m- F. W7 m# k4 @; Y; {
- """+ u, u- I. O; [
- def loadDataSet():/ B8 B$ d- F5 m4 _$ }( k
- dataMat = [] #创建数据列表
+ @5 a# t3 O1 }; [ - labelMat = [] #创建标签列表
2 I* ]. b9 V& @+ R4 S3 W - fr = open('testSet.txt') #打开文件 3 S- v+ W v0 V2 ?8 W1 G/ Z0 x: t
- for line in fr.readlines(): #逐行读取
3 ]0 g- C\" V' |4 Y ~/ s - lineArr = line.strip().split() #去回车,放入列表) q- r- X, g0 Y1 s& r' G' O
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
! r: f+ h F6 M0 ~ - labelMat.append(int(lineArr[2])) #添加标签
+ P8 D% x3 L, F, U/ { - fr.close() #关闭文件
2 J5 U5 C; b# ~% x - return dataMat, labelMat #返回8 X Z* Q$ C9 X; g6 e( b
^% W\" A' W% T( h/ t3 }7 g4 {- """
+ R3 T# q& A2 a- G% Z/ m - 函数说明:sigmoid函数
% g/ b$ K% P) A9 N+ l/ k; Y' ~ - ! B5 V9 Q9 {& ^1 Q- [
- Parameters:
: ^& E: i5 o. ^0 Q0 y l - inX - 数据
9 Z+ k: g; L& N - Returns:1 c' u\" Y3 }+ f$ I2 [
- sigmoid函数& e1 X) K. q0 b- b6 \
- """/ M# ] o. y. |8 G) I3 h: P
- def sigmoid(inX):6 n. c9 x' H3 P; u
- return 1.0 / (1 + np.exp(-inX))
) D/ w. S% z/ F! i: X; o3 v# a
$ u; n2 Q/ _* G7 R8 H/ H+ J
\" h% F+ s3 K2 Q) Z+ M3 d; v( Y- """5 w: G+ f; G, c, ^1 L4 e8 Q
- 函数说明:梯度上升算法7 _& L4 r% }! x2 Q! u2 N
- 3 x3 Q+ h4 D& c2 _/ r1 Z
- Parameters:4 A6 F( J. z7 [9 ~2 D( z
- dataMatIn - 数据集* j; l: w% a! r3 O/ ?; P0 g! r
- classLabels - 数据标签4 P! [' W* }9 G, @2 b7 o
- Returns:9 h( A\" b$ ^# `' g* e9 f1 s
- weights.getA() - 求得的权重数组(最优参数)
- G+ Z7 m1 V+ E. y5 P - """
: R3 S1 @+ A5 \+ c& o - def gradAscent(dataMatIn, classLabels):
% ]4 _0 E! A# J& C' {7 `$ x) d - dataMatrix = np.mat(dataMatIn) #转换成numpy的mat
# G* Y7 \1 P% R' N5 \\" I - labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
' ?' R: d. t9 Z7 r G - m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。0 m4 r; z' L6 l% t4 }7 I
- alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。2 W1 h9 ~+ }$ W+ F
- maxCycles = 500 #最大迭代次数7 ^7 @2 }+ g( r3 ~
- weights = np.ones((n,1))
- P1 z$ ]: R* Z+ z/ p - for k in range(maxCycles):# ~' ?) @6 Q, p6 k* a0 S
- h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式
# L4 b# C- |3 W; e0 p) C - error = labelMat - h; A) H+ V; |\" d# W( n5 }. x
- weights = weights + alpha * dataMatrix.transpose() * error
. @! _3 X) D6 m8 l - return weights.getA() #将矩阵转换为数组,返回权重数组 g# l0 t& A* b; P6 S- t
8 @& C0 l+ E/ @9 s- if __name__ == '__main__':) k O8 r* b0 V7 q5 @+ d7 z m
- dataMat, labelMat = loadDataSet()
# o% i0 w8 M# U1 V - print(gradAscent(dataMat, labelMat))
! p! b# Z2 G; t% E
复制代码 运行结果- [[ 4.12414349]
& W$ J' K! ^$ D$ R, J. H) w8 r0 T - [ 0.48007329]
0 k+ v6 {/ b/ H - [-0.6168482 ]]8 p* v$ j* A* I6 _, }
复制代码 x) s$ b- m7 {2 v1 }- V- _, s
|
zan
|