数学建模社区-数学中国
标题:
Logistic回归--实例
[打印本页]
作者:
2744557306
时间:
2023-11-30 17:30
标题:
Logistic回归--实例
2023-11-30 17:26 上传
下载附件
(79.88 KB)
"""
* j' f P& k9 I" D7 |7 Y3 b2 D' M
函数说明:梯度上升算法测试函数
# u! {# _0 x& v5 o
# L: L' j3 |4 S) M
求函数f(x) = -x^2 + 4x的极大值
4 k+ I/ r& Z4 `: D x; ?' c% N
' d' T: K4 m a
Parameters:
4 d$ z4 I; ]: T' ~5 u+ o
无
4 n4 O$ B% T/ W0 @4 l9 y
Returns:
' {9 R6 A9 O( Y; }- R
无
) X) x4 L5 C4 }9 [/ p* {- M
"""
, X* c$ T1 U5 {3 q2 U7 ]
def Gradient_Ascent_test():
! k r1 ?- |% E
def f_prime(x_old): #f(x)的导数
- m* r* R# v. _7 E2 x: `8 K# r( W
return -2 * x_old + 4
0 Z9 `/ D% O: D, k& } A. y
x_old = -1 #初始值,给一个小于x_new的值
8 {, C# x: [3 E# Z! q: G
x_new = 0 #梯度上升算法初始值,即从(0,0)开始
$ ?4 l! b* ?" r
alpha = 0.01 #步长,也就是学习速率,控制更新的幅度
( b* p+ I/ j/ v9 _1 W5 f
presision = 0.00000001 #精度,也就是更新阈值
) t6 o: Z! b4 P" d" F
while abs(x_new - x_old) > presision:
. \9 e" o7 j$ y0 P7 L2 V) }
x_old = x_new
+ W0 K! S3 f" q% f7 ]9 f
x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
r% P% h p+ M% ?6 t9 `; s; ^! }
print(x_new) #打印最终求解的极值近似值
) V/ E* b* O. w) U. o
0 t% t: x6 `' x( {: O! ^7 U1 M
if __name__ == '__main__':
1 c/ C* A- }; m z0 H
Gradient_Ascent_test()
! z3 K; y6 r( g6 F* b1 b
复制代码
运行实例:
1.999999515279857
X1 O" P+ J8 B2 S
复制代码
案例
数据集下载:
https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
-0.017612 14.053064 0
# p7 ]# g9 y2 [. b" r. Y4 v) l$ E, [
-1.395634 4.662541 1
6 @- K, m" E7 f2 `5 v, z
-0.752157 6.538620 0
' v% t+ V$ ]0 {1 N9 h, X. ~4 V% R# b
-1.322371 7.152853 0
$ y6 r( [( U" T/ L. E/ c/ b' g
0.423363 11.054677 0
5 J; b. R8 d# T3 | {+ p
0.406704 7.067335 1
5 Q& l {5 _ ~* i- j
0.667394 12.741452 0
1 [" k) }' v; H& t
-2.460150 6.866805 1
9 R3 R' W& R3 g9 V& U" e5 d
0.569411 9.548755 0
6 s/ U" x! v, R- I9 J4 ^5 l) d
-0.026632 10.427743 0
, E0 {( V: @( D
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
import matplotlib.pyplot as plt
) `- u u+ W5 F
import numpy as np
" D. J. L) B$ i3 Z1 v' Y* {
( j+ h2 C" T0 ^# [- |9 ~, U) T
"""
+ c( v7 p. B; N; w
函数说明:加载数据
. k$ a" z. O$ i8 l
; t( `. e" P! a1 @- S; s2 [6 @
Parameters:
! O- @! G' q+ G5 B4 c
无
7 w1 Z0 M: a: X& o/ ~: X
Returns:
. H. ~0 G0 G: M3 u j6 `
dataMat - 数据列表
" ?6 E" ~& I& k1 w- I2 `0 b
labelMat - 标签列表
( \9 B& S5 W. ^0 l5 W
"""
3 Z4 Q3 I$ I- n. R
def loadDataSet():
9 N6 J$ F4 ]1 K( z7 R- L
dataMat = [] #创建数据列表
3 E" {6 ^, s, r# [
labelMat = [] #创建标签列表
8 O" T) ?" t* ~6 \; n' P
fr = open('testSet.txt') #打开文件
" _: g. W& J" V/ n- y
for line in fr.readlines(): #逐行读取
! Y+ x% U7 S/ e' w" X
lineArr = line.strip().split() #去回车,放入列表
, v/ q7 T. { X: L. P' R; N1 X& Q
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
; E, F% |$ x: w4 q" h
labelMat.append(int(lineArr[2])) #添加标签
- G& h2 |* S$ H2 | u7 U; |. D1 S
fr.close() #关闭文件
" C( H% i) M) l4 o2 G
return dataMat, labelMat #返回
3 V7 O* l8 [, |8 F/ t
3 ~, U4 Z+ A4 _! Z( P
"""
; b- M1 x: x+ S" [
函数说明:绘制数据集
0 K; n' u$ N- v) L8 D/ C
+ l% }; f7 b* T' o$ w
Parameters:
3 w$ \: ~: K: R2 H; E* Y
无
6 c* R# }; e1 Y: J" z1 l) V8 Z
Returns:
; ~ Y3 A4 u9 s" \2 ~: R3 c# }
无
0 y4 k7 t9 X( G3 d+ ~; u
"""
& s& g+ N M) Y3 }3 g1 o4 l! N
def plotDataSet():
0 M- s! [2 N J4 Y1 \ G9 R' A3 X
dataMat, labelMat = loadDataSet() #加载数据集
4 d. x. f3 j4 n- T: H: O: f. l
dataArr = np.array(dataMat) #转换成numpy的array数组
0 b9 m ~, w \* f
n = np.shape(dataMat)[0] #数据个数
) d3 X! D7 h; ^% l9 F$ \
xcord1 = []; ycord1 = [] #正样本
, u7 [/ _0 Z; y' k7 t* W
xcord2 = []; ycord2 = [] #负样本
9 E2 G+ Q; y# o: v1 n- M
for i in range(n): #根据数据集标签进行分类
+ u4 S# H: u9 A! l4 i7 @1 ^: e
if int(labelMat[i]) == 1:
2 q/ R! S0 J8 m
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本
/ P6 ]6 ~# B9 X7 m/ z
else:
4 V$ k8 h& B$ y) `2 [0 M
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
/ L% R4 x2 z1 d' q: L) r6 k- T
fig = plt.figure()
5 [( `3 m- y4 o7 Z
ax = fig.add_subplot(111) #添加subplot
" j/ _- Z" n; Z4 }, u
ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
3 ?* c ~% O* i: w/ `
ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
$ o) @5 v! f) U8 S0 E4 G# y( B) A! T
plt.title('DataSet') #绘制title
" I$ K& A6 b J8 V# O. W S" } {
plt.xlabel('x'); plt.ylabel('y') #绘制label
4 q# r* W; A5 b8 n
plt.show() #显示
" E) n5 b% o+ a( |2 ^! k. Y6 {
. c# i/ B: ^$ E# Y; z8 x" T: A; M
if __name__ == '__main__':
: v8 ]: e- D! r. g& ?. x' B+ d+ o
plotDataSet()
$ A% w. d) P; ?, F
复制代码
2023-11-30 17:29 上传
下载附件
(43.58 KB)
5 ]4 z: B* i8 `
从上图可以看出数据的分布情况。假设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
: T& i1 X. K, i2 A h) V3 \( ]
, H: d2 Q# y$ V9 ]% c
"""
; {% ^0 V& v$ d) X: x
函数说明:加载数据
0 ]6 q7 ]! b3 r9 K
J7 x' w5 m8 L8 C. d
Parameters:
! b7 l5 N6 p6 M b r; U* r9 I5 ~
无
4 r" A$ T* b l: O! @% U4 q
Returns:
. R7 h7 `$ F- w- a5 h2 x7 X8 v
dataMat - 数据列表
3 x5 c6 G% Y8 r
labelMat - 标签列表
. u( Q ]( ~; ]5 H6 u" b
"""
4 Q1 J( x+ n5 r; M
def loadDataSet():
" @: j @# w+ g5 O
dataMat = [] #创建数据列表
1 r! E- d% o( {; r5 L$ S8 A6 Z
labelMat = [] #创建标签列表
' q9 P+ O" Q$ e8 {
fr = open('testSet.txt') #打开文件
0 Z" X$ D+ O& @; @3 q5 q) Y4 v
for line in fr.readlines(): #逐行读取
7 v j: }+ b6 L/ m
lineArr = line.strip().split() #去回车,放入列表
- D/ Q3 V2 l/ M6 G. X# ^
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
. _- g/ \% @4 a) a# y
labelMat.append(int(lineArr[2])) #添加标签
- S: q9 o. n, s: Z
fr.close() #关闭文件
# b9 Y; |2 I. H2 l# ]* O, v5 ?
return dataMat, labelMat #返回
: V+ Y9 A! Z, K$ C& j2 @$ m0 i8 h6 B
, V- Y/ n/ A+ q3 F& [( v1 x
"""
& u# T. h* W* I9 a; f% g2 G; ]4 Q% T, b3 E
函数说明:sigmoid函数
* x7 [& C0 F. @) I# l
# B7 V: p, ~* E% e
Parameters:
3 `- ~# o7 H& d# n) i0 ?
inX - 数据
% C$ l8 b8 C! U
Returns:
/ g3 Y4 Q; d3 R# g' N
sigmoid函数
7 i @; h; a' s1 T5 ?, U$ l$ N
"""
- |$ T2 I7 v! Y
def sigmoid(inX):
6 p" H+ ~2 U0 o0 R
return 1.0 / (1 + np.exp(-inX))
: c% f% J5 k2 _- M# `5 _1 [+ y
# v V5 I& `" c6 U# ]6 _# Z: |( x
6 O4 |8 J# I7 S' k' e! V
"""
5 ?% x( X: p! u$ D1 b) |
函数说明:梯度上升算法
/ D1 h, J) W# x( K
0 ?/ W9 z# Y( x/ z/ S. R
Parameters:
8 ^- Y# x1 \7 Y2 C) B# Z
dataMatIn - 数据集
* {( t" I b- H& [+ k
classLabels - 数据标签
0 _5 i% ~* ~. \! R2 b
Returns:
; H2 p7 F/ F1 g
weights.getA() - 求得的权重数组(最优参数)
# S" k" A' _; t" J/ D, C! E7 O
"""
; F5 y' _ A1 X& x) D0 |
def gradAscent(dataMatIn, classLabels):
7 k0 U+ R0 `' R/ d8 E5 W, G/ z
dataMatrix = np.mat(dataMatIn) #转换成numpy的mat
l& a" D" @( E. _0 f
labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
4 Y- |+ l# _3 `
m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。
7 V3 @ a" q1 V: T
alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。
% @0 i/ [# k; E" G$ S3 [! H. i+ D
maxCycles = 500 #最大迭代次数
1 e( }" C" j& _8 R( p" ~
weights = np.ones((n,1))
" C8 Q' Y1 k7 D/ `" b7 g
for k in range(maxCycles):
. p: `' w: W) L$ [5 F6 y) g9 N
h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式
2 q. x; K' L; l. k _. z* b, n
error = labelMat - h
# j; G$ u. k6 p! J1 _' \0 A
weights = weights + alpha * dataMatrix.transpose() * error
. `+ N! y, j: M
return weights.getA() #将矩阵转换为数组,返回权重数组
0 I" }3 y' ]1 m. Y
; n# i1 P. `" N8 o4 t( e( P
if __name__ == '__main__':
" d2 O6 `8 m& `1 e- d2 { k* @
dataMat, labelMat = loadDataSet()
# B7 i; m8 z4 Q( b; U9 m
print(gradAscent(dataMat, labelMat))
+ m& K* {' e; I2 G: V
复制代码
运行结果
[[ 4.12414349]
2 e, |* S/ `. x: F- ]
[ 0.48007329]
- B2 y. G. L& q/ J+ w& k+ g# R
[-0.6168482 ]]
# l; _3 }$ B" ?" X# j
复制代码
4 F9 {3 Z. ^. S7 S) y% h( X, h( j
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5