人工智能神经网络(Artificial intelligence neural network)之感知器算法

通俗来讲,感知器算法可以完成如下这类线性可分的二分类分类任务。即找出一条超平面,将两类数据进行划分。在输入特征为二维的数据集中,即一条直线。现在自动生成一组数据,并且简单二分,运用算法判断是否线性可分,并且实现感知器算法寻找此条直线,并求解直线相关参数。

感知器算法是一种用于二进制分类的监督学习算法,可以预测数字向量所表示的输入是否属于特定的类。在机器学习的术语中,分类被认为是监督学习的实例,即,其中可观测得到正确识别的训练集,可将之用于训练学习。相应的无监督过程被称为聚类或聚类分析,并且涉及基于固有相似性(例如,被视为多维向量空间中的向量的实例之间的距离)的某种度量将数据分组到类别中。在人工神经网络领域中,感知机也被指为单层的人工神经网络,以区别于较复杂的多层感知机(Multilayer Perceptron)。作为一种线性分类器,(单层)感知机可说是最简单的前向人工神经网络形式。尽管结构简单,感知机能够学习并解决相当复杂的问题。感知机主要的本质缺陷是它不能处理线性不可分问题。我用sklearn.datasets.make_classification 生成了大小为 100的数据集,并在其中按照 8 : 2 的比例随机拆分为了训练集和验证集。在训练过程中,发现可能是因为由 make_classification 生成的数据集太理想,在学习率固定为 0.01 ,通过随机梯度下降进行 1个 epoch 的训练,即可得到非常好的效果,事实上,在 epoch为1,l_rate 为 0.01 时得到准确率为 90% 已经是我多次测试得到最好的结果。

实验结果:

w = [0.81072587, 1.85426] b= 0.04000000000000001

运行步骤:

运行环境:pycharm

运行代码:

'''
JOEY 感知器
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
#100个样本点
x, y = make_classification(n_samples=100, n_features=2, n_redundant=0, n_informative=1, n_clusters_per_class=1)
X_train,X_test,y_train,y_test = train_test_split(x,y,test_size = 0.2,random_state = 2)
# numpy to pandas
X_train = pd.DataFrame(X_train)
X_test = pd.DataFrame(X_test)
y_train = pd.DataFrame(y_train)
y_test = pd.DataFrame(y_test)
y_train[y_train[0] == 0] = -1
y_test[y_test[0] == 0] = -1
# n_samples:生成样本的数量

# n_features=2:生成样本的特征数,特征数=n_informative() + n_redundant + n_repeated,2类

# n_informative:多信息特征的个数

# n_redundant:冗余信息,informative特征的随机线性组合

# n_clusters_per_class :某一个类别是由几个cluster构成的
# 绘图显示

#感知器实现算法
class f(object):
    def __init__(self, w_dim, b0=0, l_rate=0.01, epoch=200):
        self.w = np.ones(w_dim, dtype=np.float32)  # w_dim = len(X_train.columns)
        self.b = b0
        self.l_rate = l_rate  # 先固定学习率
        self.epoch = epoch
        self.accuracy = []

    def sign(self, x, w, b) -> int:  # 定义符号函数
        y = np.dot(x, w) + b
        y = float(y)
        if y >= 0:
            return 1
        else:
            return -1

    def Weighted_sum(self, x, w, b) -> float:
        y = np.dot(x, w) + b
        return y

    def fit(self, x_train, y_train):
        #
        self.accuracy.clear()
        accuracy_temp = 0
        for iter_ in range(self.epoch):
            for i in range(len(x_train)):
                xi = x_train.iloc[i]
                yi = y_train.iloc[i]
                accuracy_temp += float(yi) * float(self.Weighted_sum(xi, self.w, self.b))
                # SGD
                # if  self.sign(xi, self.w,self.b) < 0: // 我发现没有这个条件训练的更快,甚至效果更好
                self.w += np.dot(xi, float(yi)) * self.l_rate
                self.b += yi * self.l_rate
            self.accuracy.append(float(accuracy_temp))
            if iter_ %10 == 0:
                print("实验结果:")
                print('w = ',list(self.w),'b=',float(self.b))
            accuracy_temp = 0
    def predict(self,x_test):
        y = []
        for i in range(len(x_test)):
            xi = x_test.iloc[i]
            y.append(self.sign(xi, self.w,self.b))
        return y.copy()

    def score(self,y,label):
        accuracy = 0
        for i in range(len(y)):
            if  y[i] == label.iloc[i][0]:
                accuracy += 1
        return accuracy / len(label)

    pass
#主函数
if __name__ == '__main__':
    perceptron = f(len(X_train.columns),epoch= 10,l_rate= 0.01)
    perceptron.fit(X_train, y_train)
    y_predict = perceptron.predict(X_test)
    # 可视化
    #绘图显示
    mistake_f1_pre = [X_test.iloc[i][0] for i in range(len(X_test)) if y_predict[i] != y_test.iloc[i][0]]
    mistake_f2_pre = [X_test.iloc[i][1] for i in range(len(X_test)) if y_predict[i] != y_test.iloc[i][0]]
    fig = plt.figure(num=1,figsize=(14,6))
    ax1 = fig.add_subplot(111)

    ax1.scatter(x[y==0, 0], x[y==0, 1],c = 'red')
    ax1.scatter(x[y==1, 0], x[y==1, 1],c = 'blue')

    line_x = np.linspace(-3,3,100)  # 这里的范围,方便显示可以自己调

    line_w = -1*(perceptron.w[0]/perceptron.w[1])
    line_b = -1*(float(perceptron.b)/perceptron.w[1])

    line_y = list(map(lambda x : x*line_w + line_b ,line_x))

    ax1.plot(line_x,line_y,c = 'orange')
    print(line_w,line_b)
    plt.show();
    print("实验数据:")
    print(x)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joey.Chao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值