数学建模社区-数学中国
标题:
Logistic回归--实例
[打印本页]
作者:
2744557306
时间:
2023-11-30 17:30
标题:
Logistic回归--实例
2023-11-30 17:26 上传
下载附件
(79.88 KB)
"""
9 j) v, @" v- }
函数说明:梯度上升算法测试函数
r4 {0 v! G0 Z A" b% }/ h6 y
( Y; t: o' e, d/ \
求函数f(x) = -x^2 + 4x的极大值
& E1 m( i# l4 N/ a. t, e
, [6 F4 C1 N, F; K+ V
Parameters:
" l/ Y) b) `$ W0 W) J6 \
无
6 M. s) U# @" j- F& X
Returns:
2 N" ?# @' e w& q
无
$ O# y. U) A+ O. R0 b* z, O
"""
6 s* E: o3 A! z6 ]: g2 J6 D6 S
def Gradient_Ascent_test():
% B S9 r2 p0 e( ^9 F
def f_prime(x_old): #f(x)的导数
2 G5 }) ]0 x$ u
return -2 * x_old + 4
" l3 a9 |4 J4 L0 P/ q/ i/ j: l
x_old = -1 #初始值,给一个小于x_new的值
/ J% c- R# J4 w! q# g+ ^
x_new = 0 #梯度上升算法初始值,即从(0,0)开始
; Q, x0 a6 l" m
alpha = 0.01 #步长,也就是学习速率,控制更新的幅度
- |( n4 @2 D& r( i: U- ~% I2 N2 ^6 g
presision = 0.00000001 #精度,也就是更新阈值
& X/ _. @- e* K/ ^$ P, `
while abs(x_new - x_old) > presision:
% v# v' c: Z6 w4 o
x_old = x_new
" @8 c; j% C* y5 u
x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
9 [2 w$ W0 g% t
print(x_new) #打印最终求解的极值近似值
$ J/ Y+ d) Z8 \ K
: d# Y! X- W$ a8 V
if __name__ == '__main__':
8 N# q( [/ V" b ?; c; ?3 {# [
Gradient_Ascent_test()
, R6 \+ j: i5 j6 o# Z2 }8 L
复制代码
运行实例:
1.999999515279857
9 T1 C$ _& B) ]; G3 M$ ]+ p7 D8 j
复制代码
案例
数据集下载:
https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
-0.017612 14.053064 0
9 @$ `6 D7 S3 W# A% v. ^
-1.395634 4.662541 1
0 m+ _7 N3 F7 z; m: ?! V
-0.752157 6.538620 0
" V: b& s/ l2 [3 Z6 d- H
-1.322371 7.152853 0
1 G/ ?0 Y1 S0 }. F" r- ]9 D. G! x
0.423363 11.054677 0
# X3 N! g; T- u! J
0.406704 7.067335 1
. s. ~4 W/ H% ?8 A3 F0 r
0.667394 12.741452 0
; c! E" G( d1 A/ f q1 o8 ^& J
-2.460150 6.866805 1
; B4 k( Q! H+ F+ {6 k% l4 L- ^
0.569411 9.548755 0
6 h/ q4 S9 E1 v. S7 q: q9 t
-0.026632 10.427743 0
- |* \0 W. }1 E5 A
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
import matplotlib.pyplot as plt
# D8 r+ U% q) C8 t+ w3 l" Q
import numpy as np
7 c6 }' [) J2 f
; i9 I' o9 \9 ~! W8 C- x4 t- D! s
"""
( T% f2 u3 w i3 K2 M
函数说明:加载数据
- x+ n4 _# s- m# Y- Z3 |! H' q" M, k
% N5 W5 B; y9 b: {
Parameters:
) @# `' o& i8 |; b- k- L
无
, B1 ^" y& }& Z) S$ F! q
Returns:
3 x% J' d9 H$ R+ ~+ M
dataMat - 数据列表
0 A, @" I# ]- G* M( |+ m( Z. O
labelMat - 标签列表
. F ^0 {) z7 h2 t/ M9 `
"""
1 u/ t- n# c5 r, x) L# d L
def loadDataSet():
; j7 d; l' s5 O/ D7 }& b
dataMat = [] #创建数据列表
4 R7 Q- U, L4 V1 B% e! w7 l
labelMat = [] #创建标签列表
4 s+ N/ K3 S& H5 e
fr = open('testSet.txt') #打开文件
( {4 q- e/ q! C7 a* i! o" M: [
for line in fr.readlines(): #逐行读取
! e7 Y2 ^5 ]; n* d7 _% J- q
lineArr = line.strip().split() #去回车,放入列表
) b) o- q5 y- p C
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
. t9 Y' l! p0 N. ?+ F9 x0 N
labelMat.append(int(lineArr[2])) #添加标签
4 `' T' P$ [, Z0 J* o; E
fr.close() #关闭文件
* P% A4 B- W) ^2 J- [) T7 S% ]
return dataMat, labelMat #返回
1 Q4 F' E7 k7 X k6 j- V! U
* R. F4 Q7 B+ y- Z2 N* K
"""
0 H, P, }5 n( y4 y
函数说明:绘制数据集
& m4 C) M' U& ~$ E6 f
! U* ^, U2 q9 k M
Parameters:
4 }) y: A. S t+ [% p* M4 }, m6 r
无
1 O+ S; p p8 E
Returns:
* K' d( I) _ o* Y* T( ^8 Y% ?
无
4 k: U, y2 Y. n! d
"""
' B3 ^6 {* Y) O$ J* [
def plotDataSet():
: z: V8 Q8 s/ }3 n2 [/ G
dataMat, labelMat = loadDataSet() #加载数据集
* I0 b# Q6 [, F7 K1 V2 T- i$ t
dataArr = np.array(dataMat) #转换成numpy的array数组
+ ^! ]3 F( t0 p- Z5 n' ^- R
n = np.shape(dataMat)[0] #数据个数
0 K: D* [2 T, }. G$ E( j
xcord1 = []; ycord1 = [] #正样本
4 N% x _% v, `, Z% c7 D) `
xcord2 = []; ycord2 = [] #负样本
% W9 U4 a6 ^0 W( `
for i in range(n): #根据数据集标签进行分类
! V: Z( q7 d5 {9 |0 x
if int(labelMat[i]) == 1:
0 K4 N8 E o% K8 I5 N
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本
: ~, h0 b( @5 L/ X/ I9 R. p7 V
else:
4 B% }1 W' E& h: @7 M/ w
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
# P; P" z4 g' c+ |; U/ R
fig = plt.figure()
- Y" E$ y- Z$ m9 r! K" y/ _
ax = fig.add_subplot(111) #添加subplot
, ]+ O [6 i# \' d; ^2 I) l
ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
# k( H" c* v$ w* m1 d; j" A6 p
ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
c5 l5 @4 Y$ Y: F& P; T3 M' \
plt.title('DataSet') #绘制title
; l" N9 G" e+ Q% p0 F% {* g y
plt.xlabel('x'); plt.ylabel('y') #绘制label
9 p) H: ?! _9 r
plt.show() #显示
% J+ M" V9 W3 B ? G% S9 F
8 S8 h0 c& P/ \" T+ F- ]: u: j3 d
if __name__ == '__main__':
9 o$ {; P( f$ o& u
plotDataSet()
- d. r: J! ?; b8 o0 Y" ?
复制代码
2023-11-30 17:29 上传
下载附件
(43.58 KB)
9 l4 \3 K1 Z( B; N/ ^" a4 \
从上图可以看出数据的分布情况。假设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
, Y: ~! {$ w1 W
2 V6 f: ` o0 ~- z0 L
"""
1 _" ^1 |, w; O# C( _
函数说明:加载数据
8 ]% X, ^( h$ t( g1 x$ K3 r
) b: ^: L; b$ x/ V5 }( W
Parameters:
$ e! K9 S. ~: b; ~6 g+ N
无
# N' z/ \! P% g5 u% w; C* T) E
Returns:
$ L6 s! s6 c5 p4 P6 I, }. E" P, W$ y
dataMat - 数据列表
. B' d- W" U! v/ e
labelMat - 标签列表
8 r2 B, N) I6 b6 t" ]- N
"""
& w3 I% l$ u+ @/ Q4 r' X; d- I& U
def loadDataSet():
* d6 ~- A" M4 k! P
dataMat = [] #创建数据列表
* G7 h5 b- W3 C; w& \ f( h% r
labelMat = [] #创建标签列表
3 x" L0 L/ m, P0 ?9 \8 u
fr = open('testSet.txt') #打开文件
7 g' [; C3 X* Q
for line in fr.readlines(): #逐行读取
' z5 S' F+ |1 }8 E4 T/ Y7 L5 V1 n
lineArr = line.strip().split() #去回车,放入列表
3 K( q, s5 {( r2 ?8 T6 a6 e7 V
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
3 N, K6 q6 Y8 K, l' B
labelMat.append(int(lineArr[2])) #添加标签
[2 \5 a: Q: ]; R
fr.close() #关闭文件
1 F7 g. U/ x0 ?5 V
return dataMat, labelMat #返回
+ Q8 _3 y- V: M7 w/ s+ N
: h' r: k/ W4 m+ p1 \
"""
s* _2 O6 B6 Q- `* D* D) O
函数说明:sigmoid函数
, o4 L5 x! G1 t3 r9 \1 Z( B9 j
- {' _3 B9 U4 g) g6 ?
Parameters:
8 w7 o' m# N' n
inX - 数据
6 g+ O0 G* ?, q6 m: ~2 {3 E( r6 f
Returns:
5 n/ i- u* Y, s4 H' c" @
sigmoid函数
- b1 j4 e9 r* u- N/ H/ r
"""
2 l6 A0 _2 U5 g/ e& s; Z9 u! g6 |
def sigmoid(inX):
! m+ L+ N# b; [* H3 S$ i% r
return 1.0 / (1 + np.exp(-inX))
# ~, f/ @& X+ j+ S Y( o( B
, h9 y' r: B; \, K q, b8 I1 @
9 X5 t' E- }! k6 k6 h6 {, m1 b, T
"""
) F; b4 u/ z; {( i! T. v# @
函数说明:梯度上升算法
" F# l9 b- Y+ ^
, U& p1 B- Y2 @1 p* X
Parameters:
' m: X$ k" ~2 q9 r9 Z, E
dataMatIn - 数据集
. _8 C5 g1 E! |; F9 ~3 ~' m
classLabels - 数据标签
, t4 \" b5 g8 x6 a" z+ V) Z
Returns:
: k0 W2 F7 W6 [( j, s
weights.getA() - 求得的权重数组(最优参数)
2 t: \: i! } j$ ?8 h
"""
+ v5 C6 |" m7 V8 q! S u
def gradAscent(dataMatIn, classLabels):
' v% l- ?# U% ^3 ]
dataMatrix = np.mat(dataMatIn) #转换成numpy的mat
3 _1 b- M# _3 i2 O* A( P
labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
3 K5 J6 O4 x3 L. L, z
m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。
9 J5 c% D$ n( F+ M: g* W) O+ m
alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。
$ l5 |+ r5 q4 a6 i; L- s
maxCycles = 500 #最大迭代次数
; o, `+ M& r) o$ b$ E$ D
weights = np.ones((n,1))
q ]8 s' R" T" r6 ` m9 R4 J
for k in range(maxCycles):
9 Z7 s# B+ F# |, P+ f
h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式
7 ?; {1 ?1 Z1 v% N
error = labelMat - h
5 }* P8 n5 z6 x. W- j
weights = weights + alpha * dataMatrix.transpose() * error
8 o+ Z' H7 ^5 I% z. N1 r5 x
return weights.getA() #将矩阵转换为数组,返回权重数组
" K6 h7 ]( B! ]% \$ n* s# _, n7 v
) z# P# ]& _, z1 r1 ?( V
if __name__ == '__main__':
& J" Y' P- \7 ]& {2 W8 o5 G
dataMat, labelMat = loadDataSet()
; z# u9 W8 V" }: I
print(gradAscent(dataMat, labelMat))
$ Y0 P# U( p- S
复制代码
运行结果
[[ 4.12414349]
/ G* q) `- ~6 |, K; T" o6 @0 n/ w
[ 0.48007329]
% W4 O5 n1 |& O, _
[-0.6168482 ]]
/ K- o1 N* G" ^0 e _" ?$ `$ u
复制代码
$ X, m9 Z' f2 L1 N. n$ s3 T
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5