机器学习--感知机实践

文章转自(有图)http://burningcloud.cn/article/105/index.html

机器学习 | 感知机实践

各位读者好,之前两周我们学习了感知机的理论知识,这次我们就来手动实现感知机的代码。我计划使用两种方式来实现感知机算法,一种是按照原理手动实现,一种是使用sklearn库来实现。

手动实现

首先来看代码:

from matplotlib import pyplot as plt
from matplotlib import animation
import copy

trainSet = [[(3, 3), 1], [(4, 3), 1], ([1, 1], -1)] #数据集
w = [0, 0] #初始化w
b = 0 #初始化b
learning_rate = 1 #学习率为1
historyDataPoint = [] #记录每个改变w和b的值的误分类点
history_w_b = [] #记录每次w和b变化后的值

'''
用来更新w和b的值,更新方式可以见《机器学习--感知机理论知识(一)》中的感知机原始算法
'''
def update(point):
    global w, b, history_w_b, historyDataPoint
    w[0] += learning_rate * point[1] * point[0][0]
    w[1] += learning_rate * point[1] * point[0][1]
    b += learning_rate * point[1]
    historyDataPoint.append(copy.copy(point)) #记录每个改变w和b的值的误分类点
    history_w_b.append([copy.copy(w), b]) #记录每次w和b变化后的值

'''
计算数据点到感知机的距离
'''
def distance(point):
    ans = 0
    for i in range(len(point[0])):
        ans += point[0][i] * w[i]
    ans += b
    ans *= point[1]
    return ans

'''
观察是否已经没有误分类点,如果有误分类点则执行w和b的更新
'''
def ifRight():
    flag = False
    for point in trainSet:
        if distance(point) <= 0:
            flag = True
            update(point)
    if not flag:
        print("得到最终的感知机参数为:w:" + str(w) + "b:" + str(b))
    return flag

'''
可执行程序
'''
if __name__ == "__main__":
    for i in range(1000):
        if not ifRight(): break  # 如果已经完全正确划分数据集,则结束算法迭代
    # 以下代码是将迭代过程可视化
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
    line, = ax.plot([], [], 'g', lw=2)
    label = ax.text([], [], '')


    def init():
        line.set_data([], [])
        x, y, x_, y_ = [], [], [], []
        for p in trainSet:
            if p[1] > 0:
                x.append(p[0][0])
                y.append(p[0][1])
            else:
                x_.append(p[0][0])
                y_.append(p[0][1])
        plt.plot(x, y, 'bo', x_, y_, 'rx')
        plt.axis([-6, 6, -6, 6])
        plt.grid(True)
        plt.xlabel('x1')
        plt.ylabel('x2')
        plt.title('Perceptron Algorithm')
        return line, label

    def animate(i):
        global history_w_b, ax, line, label
        w = history_w_b[i][0]
        b = history_w_b[i][1]
        if w[1] == 0: return line, label
        x1 = -7
        y1 = -(b + w[0] * x1) / w[1]
        x2 = 7
        y2 = -(b + w[0] * x2) / w[1]
        line.set_data([x1, x2], [y1, y2])
        x1 = 0
        y1 = -(b + w[0] * x1) / w[1]
        label.set_text(history_w_b[i])
        label.set_position([x1, y1])
        return line, label


    print("参数w,b更新过程:", history_w_b)
    print("与之对应选取的误分类点为:", historyDataPoint)
    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(history_w_b), interval=1000, repeat=True,
                                   blit=True)
    anim.save('result.gif')
    plt.show()

运行结果为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7o6lZ9e-1602304696625)(normal捕获.PNG)]

根据这一过程绘制出的动态图如下(感知机参数w = [1, 1],b = -3时为终结态):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9fSHf9hC-1602304696630)(normalResult.gif)]

sklearn实现

先来看代码:

import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import Perceptron
from matplotlib import pyplot as plt

#生成感知机分类的数据集
x, y = make_classification(n_samples=100,
                           n_features=2,
                           n_redundant=0,
                           n_informative=1,
                           n_clusters_per_class=1)

#分割出训练集和测试集
x_data_train = x[:80,:]
x_data_test = x[80:,:]
y_data_train = y[:80]
y_data_test = y[80:]

#正实例点和负实例点
positive_x1 = [x[i,0] for i in range(100) if y[i] == 1]
positive_x2 = [x[i,1] for i in range(100) if y[i] == 1]
negetive_x1 = [x[i,0] for i in range(100) if y[i] == 0]
negetive_x2 = [x[i,1] for i in range(100) if y[i] == 0]

#构建感知机
clf = Perceptron(fit_intercept=False,shuffle=False)

#训练感知机
clf.fit(x_data_train, y_data_train)
#得到结果
print(clf.coef_) #结果权重矩阵
print(clf.intercept_) #结果截距

#通过对测试集的预测观察模型的效果如何
acc = clf.score(x_data_test, y_data_test)
print(acc)

#绘制结果图
plt.scatter(positive_x1,positive_x2,c='red')
plt.scatter(negetive_x1,negetive_x2,c='blue')

line_x = np.arange(-4,4)
line_y = line_x * (-clf.coef_[0][0] / clf.coef_[0][1]) - clf.intercept_
plt.plot(line_x,line_y)
plt.show()

得到的超平面的参数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vuJv5LLZ-1602304696633)(w和b捕获.PNG)]

得到的超平面用图像显示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iA13kFWU-1602304696637)(sklearn捕获.PNG)]

  • clf.intercept_
    plt.plot(line_x,line_y)
    plt.show()

得到的超平面的参数:

[外链图片转存中...(img-vuJv5LLZ-1602304696633)]

得到的超平面用图像显示:

[外链图片转存中...(img-iA13kFWU-1602304696637)]



感知机的学习到这里就告一段落啦!大家可以根据代码注释好好看看代码,也可以自己动手写写感知机的实现,以加深自己的印象,更好地掌握感知机,谢谢大家的观看!

猜你喜欢

转载自blog.csdn.net/weixin_43800131/article/details/108994766