【python机器学习】感知器算法(基于鸢尾花数据集实现)

写在前面

感知器是一种人工神经网络,其模拟生物上的神经元结构
感知器是一个二分类器,净输入为:
z = W.T*X = w0 + w1x1 + w2x2 + w3x3 + … + wnxn

然后通过激活函数将z映射[-1,1] (与阈值theta比较)

算法内部只用梯度下降

数据集资源

本文基于鸢尾花 数据集实现
数据集:数据集网盘下载
提取码:p2v9

读取数据集&数据集处理

data = pd.read_csv(r"dataset/iris.arff.csv")
# data.head()
# 删除重复记录
data.drop_duplicates(inplace=True)
# 特征映射 便于后面感知器预测
# Iris-versicolor Iris-virginica Iris-setosa
data["class"] = data["class"].map({"Iris-versicolor":0,"Iris-virginica":1,"Iris-setosa":-1})
# 数据筛选 感知器是一个二分类器 保留类别-1 和 1的数据
data = data[data["class"] != 0]
len(data)

在这里插入图片描述

感知器算法实现

class Perceptron:
    """使用python语言实现感知器算法,实现二分类"""
    
    def __init__(self,alpha,times):
        """初始化方法。
        
        参数:
        alpha:int
               学习率
        times:int
              最大迭代次数
        
        """
        self.alpha = alpha
        self.times = times
        
    def step(self,z):
        """阶跃函数。
        
        参数:
        z:数组类型(或者是标量类型)
           阶跃函数的参数,可以将z映射为1或-1。(实现二分类)
           
        返回值:
        value:int
            如果z>=0 返回1;否则,返回-1
        """
        return np.where(z>=0,1,-1)
    
    def fit(self,X,y):
        """根据提供的训练数据,对模型进行训练。
        
        
        参数:
        X:类数组类型,形状为:[样本数量,特征数量]
          待训练的样本特征(属性)
        y: 类数组类型,形状为:[样本数量]
           每个样本的目标值(标签)。
        """
        #将X,y转换成ndarray数组类型
        X = np.asarray(X)
        y = np.asarray(y)
        # 创建权重向量,初始值为1,长度比特征多1(多出的1个是截距)
        self.w_ = np.zeros(1 + X.shape[1])
        # 创建损失列表,用来保存每次迭代后的损失值
        self.loss_ = []
        # 循环指定得的次数
        for i in range(self.times):
            # 感知器与逻辑回归的区别:逻辑回归中使用所有样本计算梯度,然后更新权重;
            # 而感知器中使用单个样本,依次计算梯度,更新权重。
            loss = 0
            for x,target in zip(X,y):
                # 计算预测值
                y_hat = self.step(np.dot(x,self.w_[1:]) + self.w_[0])
                loss += y_hat != target
                # 更新权重
                # 更新公式:w(j) = w(j) + 学习率*(真实值-预测值)*x(j)
                self.w_[0] += self.alpha*(target - y_hat)*1
                self.w_[1:] += self.alpha*(target - y_hat)*x
            # 将循环累计的误差值增加到误差列表中
            self.loss_.append(loss)
            
    def predict(self,X):
        """根据传入的样本,对样本数据进行预测(-1 or 1)
        
        参数:
        X:类数组类型,形状为:[样本数量,特征数量]
          待预测的样本特征(属性)
        
        返回值:
        result:数组类型
             预测的分类(-1 or 1)
        """
        
        return self.step(np.dot(X,self.w_[1:]) + self.w_[0])

构建训练集&测试集

t1 = data[data["class"] == 1]
t2 = data[data["class"] == -1]
t1 = t1.sample(len(t1),random_state=0)
t2 = t2.sample(len(t2),random_state=0)
train_X = pd.concat([t1.iloc[:40,:-1],t2.iloc[:40,:-1]],axis=0)
train_y = pd.concat([t1.iloc[:40,-1],t2.iloc[:40,-1]],axis=0)
test_X = pd.concat([t1.iloc[40:,:-1],t2.iloc[40:,:-1]],axis=0)
test_y = pd.concat([t1.iloc[40:,-1],t2.iloc[40:,-1]],axis=0)

模型训练&查看模型参数

p = Perceptron(alpha=0.1,times=10)
p.fit(train_X,train_y)
result = p.predict(test_X)
display(result)
display(test_y.values)
display(p.w_)
display(p.loss_)

【python机器学习】感知器算法(基于鸢尾花数据集实现)_第1张图片

可视化

import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False 
plt.figure(figsize=(10,8))
# 绘制真实值
plt.plot(test_y.values,"go",ms=15,label="真实值")
# 绘制预测值
plt.plot(result,"rx",ms=15,label="预测值")
plt.title("感知器二分类")
plt.xlabel("样本序号")
plt.ylabel("类别")
plt.legend()
plt.show()

【python机器学习】感知器算法(基于鸢尾花数据集实现)_第2张图片

# 绘制目标函数损失值
plt.plot(range(1,p.times+1),p.loss_,"o-")
plt.title("感知器二分类损失值")
plt.xlabel("迭代次数")
plt.ylabel("目标函数损失值")
plt.show()

【python机器学习】感知器算法(基于鸢尾花数据集实现)_第3张图片

你可能感兴趣的:(机器学习&数据科学,Python,python,机器学习,感知器)