学习机器学习-二分类问题分类器,梯度下降法,代码展示。

要求:自己生成一个样本总数为20的两类数据集,每类分别为10个样本。实现线性分类器。

基础知识参考了这份博客,它是我找到的最详细的一篇讲解。

神经网络系列之五 -- 线性二分类的方法与原理

另外附上GitHub地址:https://github.com/microsoft/ai-edu

这份作业快到截止时间了,我还没学会神经网络,又没有找到相关代码,于是自己用笨办法写了一下代码来实现线性分类器。

import matplotlib.pyplot as plt
import numpy as np

#样本特征值
def randrange(n, vmin, vmax):
    return (vmax - vmin)*np.random.rand(n) + vmin


x1_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100)))
x2_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100)))
#标签值
list_y=[]

for i in range(20):
    if(i/10<1):
        list_y.append(0)
    else:
        list_y.append(1)
y_data = np.asarray(list_y)
x_train = np.stack((x1_data,x2_data,y_data))
print(x_train)

这里生成两类数据集做训练用,在生成时要附上标签值,用来判断其为哪一类数据。

数据集展示
[[23.56666375 25.09075631 47.12803743  5.8850233  39.49089641 16.8659462
   9.44996442 10.05850374 36.45182739 11.74453997 78.19518409 99.49470411
  66.32145363 73.78367965 57.99214184 62.30056474 97.47532927 75.63052221
  62.84388756 66.49887471]
 [37.35435583 26.14989834  1.75216991 26.70968015  1.33685583 23.60078884
  24.64790623 47.900654   30.20381661 22.00034265 75.20267327 57.68395067
  65.05356895 59.25574098 86.86977068 94.68262277 68.93671045 89.87274462
  78.86753854 65.03568956]
 [ 0.          0.          0.          0.          0.          0.
   0.          0.          0.          0.          1.          1.
   1.          1.          1.          1.          1.          1.
   1.          1.        ]]
#展示样本数据集
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()

这里可视化了生成的数据集。

数据集

#初始化参数
W=np.array([1,1])
rate=0.01              #学习速率
B=40
temp=1000              #学习次数  

这一步是初始化训练相关的参数,在神经网络的介绍里也能看到对应的值,犹豫我还不会神经网络,所以我将其提出来直接使用。



#训练函数
def training(W,B,rate,temp):
    for j in range(temp):
        for i in range(20): 
            Z=np.dot(x_train[0:2,i],W)+B
            a =1.0 / (1.0 + np.exp(-Z))
            loss=a-x_train[2,i]
            W=W-np.dot(x_train[0:2,i],loss)*rate
            B=B-loss*rate
    #         print(x_train[0:2,i])
    #         print("W=",W)
    #         print("B=",B)
    #         print(Z)
    #         print(a)
    #         print(x_train[2,i])
    #         print(loss)
    print("W=",W)
    print("B=",B)
    return(W,B)
#验证函数
def verify(x):
    Z=np.dot(x,W)+B
    a =1.0 / (1.0 + np.exp(-Z))
    if (a<0.5):
        print(a)
        return 0
    else:
        print(a)
        return 1

这里定义了两个函数

 for i in range(20): 
            Z=np.dot(x_train[0:2,i],W)+B
            a =1.0 / (1.0 + np.exp(-Z))
            loss=a-x_train[2,i]
            W=W-np.dot(x_train[0:2,i],loss)*rate
            B=B-loss*rate

训练函数里这一段算是主要函数,在我开头提到的博客中有介绍这些公式是怎么产生的,以及其意义是什么。

在我的理解中,Z即分类的直线,a即物体所属的分类,W,B按照loss函数的结果与rate的值进行更新。

后面验证时算出物体的a的值,即可知道其属于哪一类。

#训练过程展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
for i in range(20):
    x1 = np.linspace(0, 100, 100)
    W,B=training(W,B,rate,temp)
    y1=-(W[0]*x1+B)/W[1]
    plt.plot(x1, y1)    

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()
W,B的值随训练的变化情况

W= [0.35948076 0.1748828 ]
B= 13.26780449826064
W= [0.77210068 0.75313404]
B= -6.3703509972183925
W= [0.14469182 0.10921083]
B= -10.477108967713642
W= [0.15191845 0.11642575]
B= -11.117629746272264
W= [0.15417136 0.12109126]
B= -11.661601613466757
W= [0.15539298 0.12437233]
B= -12.108067343382372
W= [0.15685185 0.12712868]
B= -12.481884452303593
W= [0.15848816 0.12957921]
B= -12.803578372149296
W= [0.16017228 0.13179975]
B= -13.08645575299053
W= [0.16183213 0.13383368]
B= -13.339239644353153
W= [0.16343551 0.1357114 ]
B= -13.567933719883142
W= [0.16497061 0.13745581]
B= -13.776863359466688
W= [0.16643522 0.13908479]
B= -13.969261581756376
W= [0.16783145 0.14061275]
B= -14.147615946501244
W= [0.16916313 0.14205153]
B= -14.313885256376384
W= [0.17043466 0.14341102]
B= -14.469641425088682
W= [0.17165047 0.14469957]
B= -14.616166033139798
W= [0.17281475 0.14592431]
B= -14.754518171875178
W= [0.17393139 0.14709136]
B= -14.88558338672208
W= [0.17500392 0.14820602]
B= -15.010109775334383

训练过程

#训练结果展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)    

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()

结果展示

以上出现的展示代码多是重复的,建议去学习一下matplotlib的画图操作,自己按需更改代码。

#验证一个点(55,55)的分类
x=[55,55]

print(verify(x))

fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
ax.scatter(x[0], x[1], marker="^")

x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)   

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()
0.9408349606570592
1

 分类验证

绿色三角点,即x点,为自己选择验证那个点。也可以用上测试集来验证。

 

关于训练函数部分开头给出的博客讲的比我清楚,我便不再赘述,代码不分,我也不是最好的,但自认为适合初学者参考来理解数学原理与代码的结合。

其他部分代码都可简单搜出,不懂可留言讨论。

posted on 2022-04-22 16:35  wxy1567  阅读(239)  评论(0编辑  收藏  举报