统计学习二:2.感知机代码实现

通过上文可知感知机模型的基本原理,以及算法的具体流程。本文实现了感知机模型算法的原始形式,通过对算法的具体实现,我们可以对算法有进一步的了解。具体代码可以在我的github上查看。

代码

#!/usr/bin/python3
# -*- coding:utf-8 -*-

import copy
import numpy as np

# learning step 
ETA = 1 

weight  = [1, 2]
bias    = -1000

training_data = []
testing_data  = []

def general_data(count):
    ''' 
    随机生成数据点及标签,选择80%的数据为训练数据,20%的数据为测试数据
    param: count: total data count
    return: nothing
    '''
    # 用于生成标签使用的weight和bias值,实际在训练后得到的weight和bias值可能和它们不同
    weight_correct = [3, 5]
    bias_correct = -1000

    # 随机生成count个点,点横纵坐标的值在[0, 300]之间
    tmparray = np.random.randint(low = 0, high = 300, size = (count, 2)) 
                              
    # 计算和设置标签
    total_data = []
    for x in tmparray:
        y = x[0] * weight_correct[0] + x[1] * weight_correct[1] + bias_correct
        if y > 0:
            total_data.append([[x[0], x[1]], 1]) 
        else:
            total_data.append([[x[0], x[1]], -1])

    # 选择训练数据和测试数据
    global training_data, testing_data
    cnt = int(len(total_data) - (len(total_data) * 0.2))
    training_data = copy.deepcopy(total_data[0:cnt])
    testing_data  = copy.deepcopy(total_data[cnt:len(total_data)])

def update(item):
    ''' 
    利用误分类点进行参数的更新
    param: item: 误分类点
    return: nothing
    '''
    global weight, bias, history
    weight[0] = weight[0] + ETA * item[1] * item[0][0]
    weight[1] = weight[1] + ETA * item[1] * item[0][1]
    bias = bias + ETA * item[1]

def cal(item):
    ''' 
    计算损失,返回结果为正说明分类正确,返回结果为负说明分类错误
    param: item: 一个实例
    return: result: 损失
    '''
    result = 0 
    for i in range(len(item[0])):
        result += weight[i] * item[0][i]
    result += bias
    result *= item[1]

    return result

def check(data):
    '''
    判断传入的数据集中有无误分类点,并进行训练,返回结果标记
    param: data: 训练数据集
    return: flag: True,  训练集中无误分类点
                  False, 训练集中有误分类点
    '''
    flag = True
    for item in data:
        if cal(item) < 0:
            update(item)
            flag = False

    return flag

def train(data):
    '''
    利用训练集训练模型
    param: data: 训练集
    return: noting
    '''
    # 最多利用训练集进行一千次训练
    for i in range(1000):
        if check(data):
            break
        else:
            #显示模型参数更新过程
            print("Training times:", i)
            print(weight, bias)

def test(data):
    '''
    测试模型的分类效果,返回准确率
    param: data: 测试集
    return: accuracy
    '''
    correct = 0
    for item in data:
        if cal(item) > 0:
            correct += 1

    return correct / len(data)
    
if __name__ == "__main__":

    general_data(1000)

    train(training_data)
    accuracy = test(testing_data)

    print("The accuracy is ", accuracy)

测试结果

测试结果
通过测试结果我们可以看到,模型在第484次训练后结束,获得的模型参数与我们生成数据时的参数相差很大。但测试结果为1.0,这说明这个模型同样具有较好的分类效果。

posted @ 2018-08-31 16:19  之语  阅读(467)  评论(0编辑  收藏  举报