统计学习方法读书笔记5-感知机代码实现

本文介绍了如何使用Python实现感知机算法,详细讲解了感知机的代码实现过程。
摘要由CSDN通过智能技术生成

1.感知机代码实现

# 随机梯度下降
import time
import numpy as np
# 显示进度条
from tqdm import tqdm


# mnist数据集将数据集做一个首尾拼接,28*28=784
def loaddata(filename):
    """
    加载mnist数据集
    :param filename: 要加载的数据集路径
    :return: list形式的数据集及标签
    """
    print('start to read data')
    # 存放数据
    dataArr = []
    labelArr = []
    # 打开文件
    fr = open(filename, 'r')
    # 将文件进行按行读取
    for line in tqdm(fr.readlines()):
        # 将读取后的每一行按切割符切割,并返回字段列表
        curline = line.strip().split(',')

        # 存放标记
        # Mnsit有0-9是个标记,由于是二分类任务,所以将>=5的作为1,<5为-1
        if int(curline[0]) >= 5:
            labelArr.append(1)
        else:
            labelArr.append(-1)

        # 归一化-遍历每一行除了第一个元素外的所有元素,并归一化
        # 列表推导式
        dataArr.append([int(num) / 255 for num in curline[1:]])

    # 返回data和label
    return dataArr, labelArr


def perceptron(dataArr, labelArr, iter=50):
    """
    感知机训练过程
    :param dataArr: 训练集的数据
    :param labelArr: 训练集的标签
    :param iter: 迭代次数
    :return: 训练好的w和b
    """
    print('strat to train')
    # 将数据转换成矩阵形式,矩阵可以并行计算,方便运算
    dataMat = np.mat(dataArr)
    # 将标签转换成矩阵后,在进行转置
    # 转置是因为运算中需要单独取label中的某一个元素
    labelMat = np.mat(labelArr).T
    # 获取数据矩阵的shape,m*n
    m, n = np.shape(dataMat)
    # 创建初始权重w,初始值全为0。
    w = np.zeros((1, n))
    # 初始化偏置b为0
    b = 0
    # 初始化步长η,即学习率,控制梯度下降速率
    η = 0.001

    # 迭代计算
    for k in range(iter):
        # 采用随机梯度下降-计算一个样本,就针对该样本做一个梯度下降
        for i in range(m):
            # 获取当前样本的向量及标签
            xi = dataMat[i]
            yi = labelMat[i]
            # 判断是否为误分类样本,如果为误分类样本,则进行梯度更新
            # 误分类样本特征:-1 * yi * (w * xi.T + b) >= 0
            if -1 * yi * (w * xi.T + b) >= 0:
                w = w + η * yi * xi
                b = b + η * yi

        # 打印训练进度
        print('Round %d : %d training' % (k, iter))
    return w, b


def model_test(dataArr, labelArr, w, b):
    """
    测试准确率
    :param dataArr:测试数据集
    :param labelArr: 测试标签
    :param w: 权重
    :param b: 偏置
    :return: 测试集的准确率
    """
    print('start to test')
    dataMat = np.mat(dataArr)
    labelMat = np.mat(labelArr).T

    m, n = np.shape(dataMat)
    errornum = 0

    for i in range(m):
        xi = dataMat[i]
        yi = labelMat[i]

        result = -yi * (w * xi.T + b)

        # 如果result >= 0,说明被错误分类
        if result >= 0:
            errornum += 1

    # 正确率 = 1 - 错误率
    accurRate = 1 - (errornum / m)

    return accurRate


if __name__ == '__main__':
    # 获取当前时间
    start = time.time()

    # 加载数据集
    trainData, trainLabel = loaddata('data/mnist_train.csv')
    testData, testLabel = loaddata('data/mnist_test.csv')

    # 获取训练后的权重
    w, b = perceptron(trainData, trainLabel)
    # 进行测试获得准确率
    accurRate = model_test(testData, testLabel, w, b)

    # 获取当前时间,作为结束时间
    end = time.time()
    # 显示正确率
    print('accuracy rate is:', accurRate)
    # 显示用时时长
    print('time span:', end - start)

start to read data
100%|██████████| 60000/60000 [00:11<00:00, 5247.08it/s]
start to read data
100%|██████████| 10000/10000 [00:01<00:00, 5326.08it/s]
strat to train
Round 0 : 50 training
Round 1 : 50 training
Round 2 : 50 training
Round 3 : 50 training
Round 4 : 50 training
Round 5 : 50 training
Round 6 : 50 training
Round 7 : 50 training
Round 8 : 50 training
Round 9 : 50 training
Round 10 : 50 training
Round 11 : 50 training
Round 12 : 50 training
Round 13 : 50 training
Round 14 : 50 training
Round 15 : 50 training
Round 16 : 50 training
Round 17 : 50 training
Round 18 : 50 training
Round 19 : 50 training
Round 20 : 50 training
Round 21 : 50 training
Round 22 : 50 training
Round 23 : 50 training
Round 24 : 50 training
Round 25 : 50 training
Round 26 : 50 training
Round 27 : 50 training
Round 28 : 50 training
Round 29 : 50 training
Round 30 : 50 training
Round 31 : 50 training
Round 32 : 50 training
Round 33 : 50 training
Round 34 : 50 training
Round 35 : 50 training
Round 36 : 50 training
Round 37 : 50 training
Round 38 : 50 training
Round 39 : 50 training
Round 40 : 50 training
Round 41 : 50 training
Round 42 : 50 training
Round 43 : 50 training
Round 44 : 50 training
Round 45 : 50 training
Round 46 : 50 training
Round 47 : 50 training
Round 48 : 50 training
Round 49 : 50 training
start to test
accuracy rate is: 0.8141
time span: 111.59057807922363
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值