- 在线时间
- 480 小时
- 最后登录
- 2026-6-1
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7823 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2934
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1174
- 主题
- 1189
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
- """
5 F v2 y# n8 e1 Z! U - 函数说明:梯度上升算法测试函数
3 H* B# }4 ^2 ?* l6 g% O - # o( d2 r; t\" Y0 b\" ~
- 求函数f(x) = -x^2 + 4x的极大值2 v. i4 F5 W/ T6 f/ }# d, X
. P4 H$ W7 E! J1 E. N' y- Parameters:
0 Y, Z0 W W. p, p; H. f8 a) a - 无! c% W: z1 V+ e2 z0 T1 Q6 h9 V3 [
- Returns:
) H# ?7 L2 u: m; e/ ^% _4 _( |/ F' a - 无# k, z: E9 D o2 V, C
- """* j2 l9 Q' l& J2 v4 j
- def Gradient_Ascent_test():# L- K R3 H* H5 ~
- def f_prime(x_old): #f(x)的导数# {+ n# o4 ]\" m* y2 S- l3 E
- return -2 * x_old + 4; D h& ]5 U4 O9 }1 N
- x_old = -1 #初始值,给一个小于x_new的值
: s7 {- n3 m6 ^ - x_new = 0 #梯度上升算法初始值,即从(0,0)开始
) N' p7 K) q% u; l\" C; p; x - alpha = 0.01 #步长,也就是学习速率,控制更新的幅度! U6 O ]% ^3 ^9 n3 O. v
- presision = 0.00000001 #精度,也就是更新阈值; T F0 U* P& u
- while abs(x_new - x_old) > presision:2 @& F7 l5 g6 `0 ^, e% ]
- x_old = x_new
; _6 k3 T, P9 c; G - x_new = x_old + alpha * f_prime(x_old) #上面提到的公式\" i0 \& F; C) \5 w. {\" G! n
- print(x_new) #打印最终求解的极值近似值# w6 ?- u( k1 d0 n1 `: |! ~: V
- 2 m3 M, ]: J& h+ \
- if __name__ == '__main__':
: d& z2 X* Z. F; C$ s - Gradient_Ascent_test()1 H( N9 j6 y7 ]$ g; s4 h0 y
复制代码 运行实例:- 1.9999995152798572 @! p7 _5 `) b6 t( m3 [( F g) v2 F! J
复制代码 案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt- -0.017612 14.053064 0
1 F ~! g f) b) C7 m/ i. x - -1.395634 4.662541 1
3 K6 V* m2 u; F( Q, k - -0.752157 6.538620 0
# f* ^1 s6 _$ }! G! q/ s+ e - -1.322371 7.152853 08 B+ p% X8 e8 D3 O7 k
- 0.423363 11.054677 0$ z0 t; m8 U$ V7 H0 @+ l7 v% h
- 0.406704 7.067335 1; ~6 C8 r3 A4 ]: ]) N) _* e# g
- 0.667394 12.741452 0
; v* x6 J+ C2 s8 ? W* g - -2.460150 6.866805 1& @$ c! S! B; h. f( L2 W; n' p
- 0.569411 9.548755 0$ [8 l9 J9 S; @, z: r8 ^
- -0.026632 10.427743 0
+ X- Q% y: p7 N$ ]. D+ e
复制代码 这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。- import matplotlib.pyplot as plt% I5 A! |% A3 ^1 k3 G
- import numpy as np
/ [2 R- O T/ s9 U7 L7 N; g: Q
\" t( n5 g3 i/ ?8 n- """
8 W; G& E3 m\" n0 {4 v - 函数说明:加载数据* {* ], h1 L\" @+ e* _: P4 @0 W
- : _' y; M5 q; |. L
- Parameters:
; i% R! f' `8 I* J( B) A8 N0 n - 无
4 \( F& Y0 t* f, ]2 F, j - Returns:
- e/ t. @* S\" n# I9 c5 i - dataMat - 数据列表! K- S2 ?/ R: G0 p& x: P/ b/ R% a
- labelMat - 标签列表
/ [* Z9 U5 ]# l2 B' D - """6 H/ h\" n/ o( n\" |; ?
- def loadDataSet():
1 @8 x$ j0 y9 E; F( C - dataMat = [] #创建数据列表. x6 p5 e/ ?: k/ k3 N: `* } c' w
- labelMat = [] #创建标签列表8 m\" l4 l5 j- W( F$ r0 h
- fr = open('testSet.txt') #打开文件
2 ` A$ |- k' R2 ^7 ~ - for line in fr.readlines(): #逐行读取
( f2 a2 B6 t6 h% C3 J8 b9 c - lineArr = line.strip().split() #去回车,放入列表/ M+ }( e& T' {4 ^0 V9 t$ y
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
# v1 K' I) s! j' J( j3 n. J - labelMat.append(int(lineArr[2])) #添加标签9 A/ ?7 H' m$ R/ P w
- fr.close() #关闭文件
: r$ Y; D- C. d$ G6 h4 v - return dataMat, labelMat #返回
5 h2 _. V y\" _5 V- p) n: L - $ Z, x$ B/ G0 N7 V2 p# r/ q
- """# W1 `) K\" R1 K& g4 @5 \
- 函数说明:绘制数据集8 W! {& C; H4 E W) b( o
4 C# t4 l, n8 a) N- Parameters:, w: D1 j, R( A. h( b
- 无\" u I0 v1 M5 a: D
- Returns:
& z5 w7 K/ t. G: i - 无; `; t. k- q, Q3 ~4 k' m. g- |1 k6 H
- """2 ] F0 V' v$ [/ {9 e% C
- def plotDataSet():; q! `3 G* S. U; T, H8 K
- dataMat, labelMat = loadDataSet() #加载数据集! |) _6 n$ ^ b2 R
- dataArr = np.array(dataMat) #转换成numpy的array数组- s+ b$ b) f; G) s
- n = np.shape(dataMat)[0] #数据个数
+ h, [8 l5 x! J7 t2 _6 T. B - xcord1 = []; ycord1 = [] #正样本
! J/ }; B$ `7 Y7 ]( C3 P! Y - xcord2 = []; ycord2 = [] #负样本
7 t% m8 {+ z( k3 X8 w( M - for i in range(n): #根据数据集标签进行分类+ @4 I: `* U/ k( Y6 i+ r h
- if int(labelMat[i]) == 1:5 \3 i; ^* L5 J! F l, e. o
- xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本3 i6 j* e0 ^( i& q6 j% W( T
- else:
2 z3 q, K2 t9 A1 F - xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
\" A\" z6 p# s$ j* w) t, g - fig = plt.figure()* U. Q8 _' D7 A$ ~
- ax = fig.add_subplot(111) #添加subplot4 [$ i/ w) s% G$ w4 @
- ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
0 V. g, V/ W$ ?# O5 E4 `! s - ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本. v6 O$ G7 W3 o
- plt.title('DataSet') #绘制title! @$ K% l1 |# ]( H
- plt.xlabel('x'); plt.ylabel('y') #绘制label
5 x: ?5 J% l n - plt.show() #显示
1 \4 q. E& O; ^6 O$ s
! T) U5 V9 m. @- if __name__ == '__main__':( d% m0 J: ]; q7 p
- plotDataSet()4 s\" i% N& o) n
复制代码
! m* {6 J2 B! F. J6 c* ]& [, I
从上图可以看出数据的分布情况。假设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
8 l+ f+ l& [- P& [$ r, k
7 ?2 H; i3 ^: W- {8 m- """
$ y* |\" Z: J3 j0 F F: b' o4 M. g - 函数说明:加载数据
% d o7 b) [* c8 \: T0 w, o: d# X
g- `; \& t/ R. G! J- Parameters:
\" e4 M. H$ k3 x2 J - 无- r1 f; n2 D9 H+ }3 a7 e# ?! N
- Returns:9 Z/ G$ q) m. T+ Q
- dataMat - 数据列表& q- i2 e8 N3 C9 r8 H8 l6 d$ b* B
- labelMat - 标签列表: M4 B8 J* C4 P- b
- """
2 N1 C$ T6 s0 B5 u - def loadDataSet():% g, _+ n/ q m* a% [8 D' f B ^4 U
- dataMat = [] #创建数据列表& ^. v3 T% ?' |, X f# p
- labelMat = [] #创建标签列表
$ Y\" N( f2 s) E( Q% y - fr = open('testSet.txt') #打开文件 - [5 P) S2 z% h$ t) E4 _& F# Y
- for line in fr.readlines(): #逐行读取
5 X2 F9 M- v( T$ @# s; C- Z - lineArr = line.strip().split() #去回车,放入列表6 B3 N7 o, Z+ B
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
/ `; Z1 l4 b: K. I - labelMat.append(int(lineArr[2])) #添加标签
( r# R! X( H: x! U' | - fr.close() #关闭文件9 v( ^# x) u6 g& I( V( u
- return dataMat, labelMat #返回' E% O* @. {6 _9 c6 P
- 1 P4 x9 E) h) L) K u0 ^% e
- """2 a) y2 E/ s# r& p2 K\" J& O
- 函数说明:sigmoid函数
& a' _) ~7 s$ r7 }' z\" [ - ' k# ~/ F7 c( i3 K1 ~) s
- Parameters:- }9 [& } R! H# E
- inX - 数据
\" _7 `( W5 Q/ G - Returns:
, ^& N. o# c1 Y% V& t - sigmoid函数
9 Y) _5 y9 U2 P. P1 C - """
# d2 }+ s: j5 h) {* g - def sigmoid(inX):/ ]; m: G9 t6 ~3 U/ }5 @
- return 1.0 / (1 + np.exp(-inX))* ~9 ~9 _1 R, X' i\" a a6 P/ O% i# j
- 2 v5 C2 [/ @5 G& @ L7 C9 C
- ; @! {# ]2 q3 |9 h/ F
- """8 n; I3 ^2 r0 h1 J5 z5 }- t* @
- 函数说明:梯度上升算法
& s. o' w R( V
, p0 X- C+ i* H# s- Parameters:
) w$ w' p4 R4 m P- ]% Q - dataMatIn - 数据集\" ]! i% o. ~( `0 [& j1 L! Z
- classLabels - 数据标签) @\" J6 w: ?, ^/ P& {
- Returns:/ z( r6 `6 b. e
- weights.getA() - 求得的权重数组(最优参数)' X8 ?, T+ H% w! k\" @
- """
. o6 f\" s* G/ } - def gradAscent(dataMatIn, classLabels):) F9 H\" Z% c( W \2 }
- dataMatrix = np.mat(dataMatIn) #转换成numpy的mat
/ z2 A$ S/ u4 Q9 h - labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
0 ^0 z4 ^\" D' Q* C - m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。
7 O | `. N: E - alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。
3 n: N8 N' J7 f5 d! x - maxCycles = 500 #最大迭代次数0 T( l4 _) D8 m$ j6 f# B2 X
- weights = np.ones((n,1))
: s2 P. F6 \* K) u( W7 G0 [ - for k in range(maxCycles):( k3 _! ^) t' V: C& a7 w
- h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式
; p% F$ n& ~0 X( e\" c- ` - error = labelMat - h
; G) h2 |8 @2 l4 y7 q - weights = weights + alpha * dataMatrix.transpose() * error/ A5 a* t% T. t% a3 [ P- i: z0 w
- return weights.getA() #将矩阵转换为数组,返回权重数组
6 x Q! c0 v) q- c- `. y! i2 j: V - 4 t5 N0 K; ]# D6 }4 D. C: a
- if __name__ == '__main__':# C6 [0 x; ~4 g6 R5 k, F
- dataMat, labelMat = loadDataSet()
; S' v) d& A: P& F- t2 Y1 f - print(gradAscent(dataMat, labelMat)). ]& n9 k9 a7 Y
复制代码 运行结果- [[ 4.12414349]; a& W% Z* a6 K7 B* H\" l6 _& g! `3 \
- [ 0.48007329]( ~$ _3 O! R) c2 Q
- [-0.6168482 ]]
6 ~# w1 d# h! m% B* P6 a\" [
复制代码
1 k8 e4 S2 r; l1 G |
zan
|