问题
生活中有各种各样的分类,以下用考试成绩来举例,0到59.99分为不及格,标签打0;60到100分为及格,标签打1。虽然我们可以直接用if语句来进行判断让计算机直接求得结果,但是如果我们不告诉计算机>=60分才算及格,却只给它一些打好标签的数据给它,能否让它自己知道及格分数线呢,答案是肯定的。
方案
训练集x(10000)为0.00到99.99
y(10000)为0或1,其中x(i)>=60时y(i)=1,否则y(i)=0
逻辑回归使用Sigmoid函数
默认训练次数为500,学习率为0.1
训练结束后,取0到99的整数作为验证集【其实这在训练集中已经包括了,可能不太科学,仅作举例方便大家理解算法!】
代码
Option Explicit
Sub Echo(s)
Wscript.Echo s
End Sub
Dim xs(10000),ys(10000)
Dim i,j
Dim length:length=10000
For i=0 To length-1
xs(i)=i/100.0
ys(i)=0
If xs(i)>=60 Then
ys(i)=1.0
End If
Next
Dim k,b
Randomize
k=Rnd()
b=Rnd()
Echo "k="&k
Echo "b="&b
Function Forward(k,b,x)
Forward=1.0/(1+Exp(-k*x-b))
End Function
Dim epoch:epoch=500
Dim yh
Dim ls
Dim kp,bp
Dim lr:lr=0.1
Dim c
Dim p
For i=1 To epoch
Echo "第"&i&"轮训练"
ls=0
kp=0
bp=0
c=0
For j=0 To length-1
yh=Forward(k,b,xs(j))
ls=ls+yh
bp=bp+yh
kp=(yh-ys(j))*xs(j)
Next
ls=-ls/CDbl(length)
Echo "ls="&ls
kp=kp/CDbl(length)
bp=bp/CDbl(length)
k=k-lr*kp
b=b-lr*bp
For j=0 To length-1
yh=Forward(k,b,xs(j))
If yh<0.5 and ys(j)<0.5 or yh>=0.5 and ys(j)>=0.5 Then
c=c+1
End If
Next
p=c*100/CDbl(length)
Echo "训练集拟合度:"&Round(p,2)&"%"
Echo ""
If p>99.99999999 Then
Exit For
End If
Next
Echo "k="&k
Echo "b="&b
c=0
Dim tx
For i=0 To 99
yh=Forward(k,b,i*1.0)
If i<60 and yh<0.5 or i>=60 and yh>=0.5 Then
c=c+1
End If
Next
p=c*1.0
Echo "测试集拟合度:"&Round(p,2)&"%"