数学建模社区-数学中国
标题:
Logistic回归--实例
[打印本页]
作者:
2744557306
时间:
2023-11-30 17:30
标题:
Logistic回归--实例
2023-11-30 17:26 上传
下载附件
(79.88 KB)
"""
5 w' x3 n9 T/ ?: A: S5 U2 j
函数说明:梯度上升算法测试函数
8 f2 ~8 O9 S- a/ V( _
! J; L; G0 }* F. m9 A6 a
求函数f(x) = -x^2 + 4x的极大值
, S* H& ^; d, |0 m- ?0 P
, Y) X9 M' `- F/ x" o9 Y4 w* _
Parameters:
7 Z7 q- Z9 K; a! y/ l
无
/ ~0 i& \; b( {# q8 X9 R4 l# S* v
Returns:
5 {8 Q# I. U' p6 p8 m
无
. r$ G6 E, O* v" j
"""
4 p! J; i4 g/ |2 i, t
def Gradient_Ascent_test():
3 `+ g' V! h9 E. I. ]$ K
def f_prime(x_old): #f(x)的导数
9 e4 |% Y, ~( i. [
return -2 * x_old + 4
* L X3 p6 c( \+ d8 d
x_old = -1 #初始值,给一个小于x_new的值
2 C- B8 f/ G% W5 A* c' j. x
x_new = 0 #梯度上升算法初始值,即从(0,0)开始
# e$ ?6 d a, D, j/ _. l4 k
alpha = 0.01 #步长,也就是学习速率,控制更新的幅度
6 Y! P" K6 c' }
presision = 0.00000001 #精度,也就是更新阈值
2 m" F7 [* z2 ]6 D
while abs(x_new - x_old) > presision:
+ e( t) s) x6 A
x_old = x_new
6 I {4 |) I* M; Z. h$ z
x_new = x_old + alpha * f_prime(x_old) #上面提到的公式
0 _# |3 `- x8 o+ x4 H1 u( m+ w
print(x_new) #打印最终求解的极值近似值
) V" M3 D+ o2 |. q* O
" M' R; b& Q" t& C* E4 |
if __name__ == '__main__':
. L0 l% ~3 r; x: L
Gradient_Ascent_test()
4 |+ O( p% f* r# y! S5 n
复制代码
运行实例:
1.999999515279857
& b0 }9 ]4 u) v- X
复制代码
案例
数据集下载:
https://github.com/Jack-Cherish/Machine-Learning/blob/master/Logistic/testSet.txt
-0.017612 14.053064 0
_0 N4 C" D. S2 v0 f% H
-1.395634 4.662541 1
; `) r8 P! f) T* i: A
-0.752157 6.538620 0
: M5 h3 f m+ D% G! F
-1.322371 7.152853 0
& |7 G# W' f+ k2 A% M
0.423363 11.054677 0
5 p+ L( H: T3 U% c
0.406704 7.067335 1
+ D; N) H4 }1 S0 u) k' o
0.667394 12.741452 0
+ v# [' n$ R& P; E9 {6 R# Z; _
-2.460150 6.866805 1
3 u2 F- _' Y( V' j# I4 k: ]* B
0.569411 9.548755 0
+ E, i4 h0 x, b) I( S* C' M
-0.026632 10.427743 0
& H h4 h" s# L6 j8 b
复制代码
这个数据有两维特征,因此可以将数据在一个二维平面上展示出来。我们可以将第一列数据(X1)看作x轴上的值,第二列数据(X2)看作y轴上的值。而最后一列数据即为分类标签。根据标签的不同,对这些点进行分类。
import matplotlib.pyplot as plt
4 G, {* n8 `+ X* b" z6 i
import numpy as np
, T9 W5 f9 M z u8 ^
. B' i- |# b [
"""
; p: B3 w+ T+ |$ w9 P! n
函数说明:加载数据
m( I) r7 J6 j( d7 f
, x6 s" F8 ~9 w9 ]; a
Parameters:
9 @0 Y7 ~% }8 ^5 O5 \, L! z
无
: a: I( N, y3 s: ?1 w
Returns:
' C) H/ C, u# S5 d' T
dataMat - 数据列表
7 ]+ e( B4 d6 k* m
labelMat - 标签列表
5 ~2 j4 _$ v8 {2 j" C# i7 a, R
"""
) @* F; i$ r6 f+ r% M9 C! b& M* j
def loadDataSet():
" E x. [0 v5 d7 l( T2 b9 i* f) y
dataMat = [] #创建数据列表
+ m5 v8 T2 e! C. ]( r6 U( }, I, \5 S
labelMat = [] #创建标签列表
& e( N& a8 a) g1 c! @- S8 ~! M
fr = open('testSet.txt') #打开文件
0 t# B8 b# H) `0 ^- d* P
for line in fr.readlines(): #逐行读取
/ _& P Z6 c" b
lineArr = line.strip().split() #去回车,放入列表
( s' g+ M; m3 x \7 _' T2 y
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
. a7 l/ J$ }# \
labelMat.append(int(lineArr[2])) #添加标签
, W( P& Z4 [' F; e; {1 ~/ w7 i
fr.close() #关闭文件
+ ^7 l. A3 f' j( x" O4 _
return dataMat, labelMat #返回
( S6 i7 s5 E; Y Y
9 z3 S3 u4 [$ w
"""
5 o' O, R! ~# t$ G# V
函数说明:绘制数据集
' L3 }3 O6 o' Y
7 l/ U2 g5 M! c# @8 S- U* @" x
Parameters:
+ x/ |4 ]4 y& B* V1 w
无
. x7 v8 T2 X9 [* e* m
Returns:
! }( O7 L8 d v
无
5 b: _: O# P& t9 d/ T
"""
1 `% e. o4 `1 B
def plotDataSet():
6 k2 u& f2 D$ e& L
dataMat, labelMat = loadDataSet() #加载数据集
$ o- B# z5 s* F5 d: [* V0 D* S
dataArr = np.array(dataMat) #转换成numpy的array数组
( l w3 {: a/ C" { d
n = np.shape(dataMat)[0] #数据个数
+ I8 P$ j1 i6 c4 r- N. U
xcord1 = []; ycord1 = [] #正样本
8 I4 P$ ?5 O. ^9 D: ~( u& H& _1 U: p
xcord2 = []; ycord2 = [] #负样本
. c; h( _% |& ]) m
for i in range(n): #根据数据集标签进行分类
7 y) `3 f0 `7 D: z7 r& P
if int(labelMat[i]) == 1:
* U" Y" z& y7 S" W& |; A% }4 w
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) #1为正样本
3 Y3 [ a3 p+ Z3 s# V; B
else:
, Q% y$ X! P' ]6 ?) r2 L9 w {8 d
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #0为负样本
0 S9 U7 r/ V4 g+ M8 ~
fig = plt.figure()
/ W: C: n% U& N6 u; m% p
ax = fig.add_subplot(111) #添加subplot
6 w% m' S8 r9 u! } K! b/ v0 h
ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
$ R& H5 ] N- V/ y( y" O
ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5) #绘制负样本
' m1 D2 A7 F9 n U# n( F# w
plt.title('DataSet') #绘制title
% S9 l: o+ V7 R* ?
plt.xlabel('x'); plt.ylabel('y') #绘制label
0 z& x6 u# a: `$ a+ X
plt.show() #显示
5 g- L& p: s, c2 b- r
- x( u) J0 ~5 L& m( w( Z; J
if __name__ == '__main__':
$ g d1 m# O+ o+ {8 n
plotDataSet()
2 W% u4 O% I0 B$ i# i" B2 Z
复制代码
2023-11-30 17:29 上传
下载附件
(43.58 KB)
6 c. c! m1 x( 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
6 X; e+ o' h" d0 F( j1 V
|7 b& T! K. i; I, w1 @
"""
3 U* o& @& j1 t' H% |( T I2 P* x2 N4 z
函数说明:加载数据
1 [. U8 O8 V( k8 c
! U' V! D% L% \) m- t1 L
Parameters:
0 v3 }0 q( ?1 _% t$ b
无
4 W# X) B+ I8 V" F0 _" F
Returns:
: ^" t' X+ [+ g5 f" q+ q5 m, Q
dataMat - 数据列表
5 j9 r; f! _& y: e' {$ e9 H5 `/ g' O3 E
labelMat - 标签列表
% d9 J. B! A% B1 f' @* m! I% G
"""
" u! v/ P1 o, [8 N9 {
def loadDataSet():
9 I" N% \: u9 O' }
dataMat = [] #创建数据列表
# M3 [* e. ?4 {/ M$ l- }# `
labelMat = [] #创建标签列表
9 ]' a: g; R: t- L2 X- O
fr = open('testSet.txt') #打开文件
; O. I) c* `( n+ h1 p
for line in fr.readlines(): #逐行读取
6 W6 {: E2 T' d7 ]1 E3 e
lineArr = line.strip().split() #去回车,放入列表
) o- p7 J/ m) v; [ L" ^
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
2 b% M9 u% A8 j5 a& {; \' V
labelMat.append(int(lineArr[2])) #添加标签
. [$ e% S- ?4 p! }6 m
fr.close() #关闭文件
+ l0 u" i9 W+ [ U3 V& m) a( F" o
return dataMat, labelMat #返回
) m* R1 j Y3 O
8 ]' N$ `/ d% I* g' ]6 i# A8 v4 m3 m
"""
" d/ X: ~ l8 d! I- b4 k# i& l
函数说明:sigmoid函数
1 u! }, X4 ~ e C# s3 r
) ]6 E, `- m6 n/ e4 Y1 z; g
Parameters:
/ }# u9 b1 ]- [* w2 P
inX - 数据
; ]$ f \5 D8 E1 K1 b
Returns:
3 o; u9 V2 T( i+ Z
sigmoid函数
. Q3 K% U! e6 |. P) t2 g) j1 t
"""
6 Y: p% n' X9 y8 R4 D7 d+ m
def sigmoid(inX):
+ ~- d" a' r* C
return 1.0 / (1 + np.exp(-inX))
( ^9 i. J6 k H4 N
; v3 M# B6 m( u( [
! b, z. n! ^! ~
"""
3 i( o: k7 b; y1 f H
函数说明:梯度上升算法
1 l: [7 Y1 Y+ l* z8 n% }" S
( d2 k+ f3 R3 _1 f7 \7 N( }! j
Parameters:
$ u+ P2 y0 }* w. P9 M
dataMatIn - 数据集
+ c) z" @* t* d7 f$ U
classLabels - 数据标签
4 a6 X) L& n; b# I, c" |# K
Returns:
! D1 S ]) f! C* o6 v1 p
weights.getA() - 求得的权重数组(最优参数)
# Z, Y0 H+ A K1 Q4 C& y/ G0 c; U7 o
"""
5 |, {0 X l7 e9 g* I! n
def gradAscent(dataMatIn, classLabels):
0 k/ |! w9 @2 [# Y/ R1 c
dataMatrix = np.mat(dataMatIn) #转换成numpy的mat
4 p! ]# G& `& `8 t* T+ B
labelMat = np.mat(classLabels).transpose() #转换成numpy的mat,并进行转置
0 m5 t/ e+ w* R# u8 }5 ?3 i; N5 ~
m, n = np.shape(dataMatrix) #返回dataMatrix的大小。m为行数,n为列数。
* @6 z9 V; |. G$ @
alpha = 0.001 #移动步长,也就是学习速率,控制更新的幅度。
5 O: x0 f7 c5 B; [
maxCycles = 500 #最大迭代次数
2 E, T* e5 k* D. M: O: E2 P. i- c$ N
weights = np.ones((n,1))
R. N3 o. H- F( i/ L) M8 R, K
for k in range(maxCycles):
" D O) |: P# w$ C! w0 c
h = sigmoid(dataMatrix * weights) #梯度上升矢量化公式
' }5 `8 Z* c% c8 p% A
error = labelMat - h
2 j' B+ N. |. {) E* {- r9 J
weights = weights + alpha * dataMatrix.transpose() * error
0 [% r) c# M. y; P
return weights.getA() #将矩阵转换为数组,返回权重数组
9 z& i- O5 t9 x+ E2 ^8 V! `$ H/ ~' p- D
6 P3 P" N1 t$ t" ]' d6 V7 e
if __name__ == '__main__':
% {3 f Y9 `! P# q6 U* f
dataMat, labelMat = loadDataSet()
$ K' l/ }8 Z3 d
print(gradAscent(dataMat, labelMat))
. M8 @3 G# }. H1 V
复制代码
运行结果
[[ 4.12414349]
" s Y/ Y, _! y7 }' o/ u8 [
[ 0.48007329]
4 s( Z/ g F+ ]6 x* B/ E7 l; K7 d
[-0.6168482 ]]
# Z1 R& S5 u8 f% J3 Z
复制代码
* K J$ V" w# e+ F1 B3 C
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5