- 在线时间
- 480 小时
- 最后登录
- 2026-6-1
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7823 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2934
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1174
- 主题
- 1189
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
- """
) d2 U, Q' c( t* D; @, B& c: c - 函数说明:梯度上升算法测试函数
. \' @) a3 K0 R# d4 r6 W
) r( s$ B8 U' c) N$ A! \( G/ H! H- 求函数f(x) = -x^2 + 4x的极大值) p2 V: M2 @& A- n) o
, W0 ]\" r. O' h9 v6 H0 y$ E* G/ J- Parameters:
`6 S1 q7 I' U0 t- N4 ?& `' b' Z - 无+ D' y: V# M0 ~' ]# W7 T* H
- Returns:. X2 g8 a* v$ P$ a' u8 ~( e5 {
- 无- T% v6 T: R( A\" H8 e( P. N
- """
5 g) r2 I8 Y8 ~* y$ Y* m Z: S9 K - def Gradient_Ascent_test():
, Q- U. z- x3 S5 W5 Z - def f_prime(x_old): #f(x)的导数1 C) G& N, R- `6 }. @
- return -2 * x_old + 4, w4 Z! u- L! E% |. z0 j
- x_old = -1 #初始值,给一个小于x_new的值
\" N\" @\" g( {6 M1 r2 Z/ z+ F: E, ` - x_new = 0 #梯度上升算法初始值,即从(0,0)开始
, V& H+ E/ E5 Z( e2 X. T - alpha = 0.01 #步长,也就是学习速率,控制更新的幅度
1 [, }: F( I3 }1 d) k0 ?! o' j - presision = 0.00000001 #精度,也就是更新阈值* ?% d3 T3 \5 A9 e
- while abs(x_new - x_old) > presision:0 n0 \4 u+ a8 l. ]2 ]
- x_old = x_new: E- J6 w0 z9 t9 @* e
- x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
0 b- d0 u+ i3 F% N - print(x_new) #打印最终求解的极值近似值
. {$ O4 Y' g- p* M& P& K3 l9 S
( P2 P1 z& a( y: f- if __name__ == '__main__':
# F4 F0 l. O# r\" i/ S - Gradient_Ascent_test()/ q1 b+ V; x1 V2 e$ f6 S! p
复制代码 运行实例:- 1.999999515279857$ Y# e\" j' O2 e3 ?5 B! a
复制代码 案例数据集下载:https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt- -0.017612 14.053064 0: `- E/ U6 C) O% E! V
- -1.395634 4.662541 1
\" A7 I$ y7 e; `! I; R) Y - -0.752157 6.538620 0
. J% ]8 \' J6 `/ S; M - -1.322371 7.152853 0
\/ \1 e( j% h6 s! w - 0.423363 11.054677 0
1 H0 M+ n# i. t) v* O( e2 E - 0.406704 7.067335 16 `$ R/ ^; {8 k5 J. `, |# p% {
- 0.667394 12.741452 0- V- }+ ?3 H; {' p4 @
- -2.460150 6.866805 1( S8 k+ g/ c% M1 }
- 0.569411 9.548755 0/ j/ w5 ~0 }! F# K6 ^( B/ ~) `
- -0.026632 10.427743 0
! E3 ]- _$ v: _6 x9 _) R
复制代码 这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。- import matplotlib.pyplot as plt& _) s* x4 N& x% Z( o
- import numpy as np
: r5 V; Y6 U/ x5 N - 9 g; @' f3 o, F; U5 E9 L
- """
, [# i. H: v0 b q, N3 o - 函数说明:加载数据, f/ I) {+ E1 h\" D0 c
- $ D' k3 @' H\" _8 s
- Parameters:
# E- S; i& s2 |0 i. u+ W6 I - 无2 |* r% X( M5 o' V
- Returns:( v/ P+ z- W. f0 |3 R3 [
- dataMat - 数据列表
# D% u2 B+ J! \2 z g4 N - labelMat - 标签列表
) g; A5 L. h; u* x0 h3 n% d$ i - """- v6 l, \8 Q' i% s# \3 |& i
- def loadDataSet():
4 N4 b, i% |7 N9 l; J - dataMat = [] #创建数据列表
4 N2 X |' H: g4 K\" W& \; x - labelMat = [] #创建标签列表
/ n# a\" H; W: h - fr = open('testSet.txt') #打开文件
1 N6 E5 H$ }& {8 ~* i2 b& i - for line in fr.readlines(): #逐行读取- q/ J2 j\" g\" B9 _% E9 F/ r
- lineArr = line.strip().split() #去回车,放入列表
_* p9 K$ H8 i7 D, X/ A+ n - dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据4 k; Z$ C* O( ]8 i/ P& p
- labelMat.append(int(lineArr[2])) #添加标签 W1 w+ ^+ g! |7 v. [
- fr.close() #关闭文件* S. B1 g- k1 v3 e
- return dataMat, labelMat #返回
( D& p X6 ~9 k5 A( M
: V8 Q2 g6 E, P8 N\" x; r4 s. `+ m- """$ b/ M6 F8 Q) X1 s5 R! n
- 函数说明:绘制数据集5 X: h8 q: f3 }( j7 \( L
0 j6 m6 W- S) S8 y4 w* r- Parameters:# Y$ ]- a# U6 [; a3 K5 o
- 无
' h# E! t0 V# e. ` - Returns:
* [6 k: l/ A3 s( N4 a6 j7 \: O9 ^ - 无* a( e1 E9 e0 K4 Q; J8 I2 U
- """
/ i( E) ~* `& i1 ` W - def plotDataSet():9 Y' _; n1 I, Z6 ?0 Z. r0 a6 D4 @
- dataMat, labelMat = loadDataSet() #加载数据集) A\" t) k3 ` M0 l8 |, c
- dataArr = np.array(dataMat) #转换成numpy的array数组7 M' x; j; S; h
- n = np.shape(dataMat)[0] #数据个数
}/ R B+ F! K - xcord1 = []; ycord1 = [] #正样本. V& O4 J0 w3 T& ?\" g3 A
- xcord2 = []; ycord2 = [] #负样本
+ K0 @/ K/ O- B$ N - for i in range(n): #根据数据集标签进行分类
! A: w8 X3 F0 K+ H7 G - if int(labelMat[i]) == 1:
( `, a) x: A6 h: v+ w l - xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本6 |\" z- h# Z$ c! b3 `
- else:* n' L0 w, `; t3 ?) A# k! a
- xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
2 B% \% P: ]0 b' u - fig = plt.figure()6 B1 `6 W; ^4 c+ j) `/ G% p
- ax = fig.add_subplot(111) #添加subplot
/ S: \6 ^4 H7 a& W' i0 i - ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本% } f4 @0 K, v3 Y
- ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
\" N; { }! Q( D, b2 ~\" p/ } - plt.title('DataSet') #绘制title
7 w9 ~# ^ O$ u4 d$ \+ g9 l1 s - plt.xlabel('x'); plt.ylabel('y') #绘制label# n+ y1 N5 `$ e- |3 c {* A1 \
- plt.show() #显示
8 G: P# d1 p6 I, k5 p3 a( x - + ~; l# Q2 U7 ]4 ^& w1 e
- if __name__ == '__main__':7 Z, r1 m: P# ?. e `9 G8 V
- plotDataSet()
f8 @& {: k7 S& c
复制代码
? I3 o4 i" s2 ?! g2 r) 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/ T4 t3 K8 A% |2 W6 H4 C: Z5 |
- 6 }& k\" ^* c0 y! C
- """9 M0 J' x) o) b\" ]3 ]
- 函数说明:加载数据' j. Q$ R5 d3 n/ [
- \" {3 U( ^$ `: P. z) c' |5 ]
- Parameters:
0 L$ K/ G5 r, W( s1 A - 无: |% I6 ^* g& f+ _* z
- Returns:\" U5 ?4 M. d# V6 e8 }2 ]4 c
- dataMat - 数据列表 A. d* k; W; }3 Z# {! _
- labelMat - 标签列表 g# E/ e A4 o( `
- """
9 g% D) \( p; C4 T - def loadDataSet():
2 i4 `- p+ o, {. i0 K! a - dataMat = [] #创建数据列表 w, r/ |1 i) m. a3 f3 h% C- m
- labelMat = [] #创建标签列表; H# x* k8 Y1 O# n' Z
- fr = open('testSet.txt') #打开文件 1 ~, |$ N\" k7 H* W
- for line in fr.readlines(): #逐行读取' c5 _ Q) h7 v# e# _
- lineArr = line.strip().split() #去回车,放入列表; ^+ O5 ~\" e6 {7 o/ c
- dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据5 ~: G& f' O\" \) \$ N' c
- labelMat.append(int(lineArr[2])) #添加标签: ~% c' `! S6 F3 T: h0 k
- fr.close() #关闭文件& x* P& v& Y$ `* }
- return dataMat, labelMat #返回
+ A) H- _4 [6 @6 o8 V* o
: t4 D\" w( J+ n; f4 c2 ~ g- """
1 R) F: R m' n9 x j6 I+ O - 函数说明:sigmoid函数, l! \( [4 \+ U( M
- ( [ {1 a5 M3 t( |0 ^3 a
- Parameters:
6 `& Z\" a2 e) }+ P - inX - 数据: G7 n4 p9 ^- C4 I
- Returns:
4 k. c/ o5 t9 O! N - sigmoid函数5 k5 G3 n( x) q
- """
2 V\" m; {! q\" y2 z+ M2 a& \ - def sigmoid(inX):
4 d6 M ?. @/ N. v4 B: @ - return 1.0 / (1 + np.exp(-inX))
3 i& j+ p' X) o$ J6 W0 `
& R6 X1 @' v% ?
- e- H; E/ u, a& O0 b- """; A\" ~5 d% d/ T$ e
- 函数说明:梯度上升算法: p- f7 ~9 k4 L. h5 N0 T
- 0 F) |2 w1 r% k2 C1 ~& z# j+ o
- Parameters:3 W4 [* Z0 J+ {\" m
- dataMatIn - 数据集; ]$ c! C; [' g! s2 M7 a\" ^& a: B
- classLabels - 数据标签
6 W, v5 N5 h8 B; l - Returns:
3 H; u. o/ _& ~$ Z- ~& t/ k9 @) G - weights.getA() - 求得的权重数组(最优参数): ~# |4 j- u3 F: `5 \: H) M
- """
& T7 O\" M; |: J\" l9 I2 N - def gradAscent(dataMatIn, classLabels):
, I\" p% S' V2 r9 D - dataMatrix = np.mat(dataMatIn) #转换成numpy的mat$ s3 L- `: g: T: P9 x v& I- d, F
- labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
- @8 o% |/ a! r: o - m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。
: ]% {- }! p6 g; x) S! m) k: { - alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。
+ M9 Z/ v o& I2 w; M - maxCycles = 500 #最大迭代次数+ s% \( ], |# s; i* `9 T) ?\" O: d
- weights = np.ones((n,1))
5 P+ ?, u4 X3 |/ a- |, e. ]& y9 x y7 e; O - for k in range(maxCycles):
* {9 i; x. j# A3 G, {. s - h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式# b7 n- n7 w2 S\" o7 o4 N
- error = labelMat - h+ K; }7 X `4 {+ P) x
- weights = weights + alpha * dataMatrix.transpose() * error9 R7 \ P; N# v/ E: P
- return weights.getA() #将矩阵转换为数组,返回权重数组
! X/ k& |# J( _. @3 u1 v
6 C# |3 U' D6 P, E& ~* e- if __name__ == '__main__':4 `6 R2 m/ _9 H# [8 J; i7 e6 k3 J C
- dataMat, labelMat = loadDataSet() $ G( @( M3 }0 [% u( G
- print(gradAscent(dataMat, labelMat))
, n/ I9 k4 U, {$ o* d2 o& E8 ]
复制代码 运行结果- [[ 4.12414349]/ A\" n\" ~/ V, i+ E% d2 L
- [ 0.48007329]' y4 h u& E\" [/ C: x5 x; u
- [-0.6168482 ]]' X0 |& U\" o# |( M2 _& v/ v
复制代码
7 z( Z' v( h( |3 Y2 s" M' h" d( c |
zan
|