《统计学习方法》感知机算法的手工搭建 感知机 原始形式 对偶形式

本文介绍了感知机的学习算法,包括原始形式和对偶形式的模型搭建。作为支持向量机和神经网络的基础,感知机是误分类驱动的线性分类模型。文章提供了相关代码实现,并强调了权重和偏置项的更新依赖于训练数据,同时指出对偶形式的权重更新可以视为计数器。作者提醒读者理解Python中的reduce(), map(), copy()函数,并表示代码可能存在小问题,欢迎大家指正。" 81939109,7381118,移动端H5 Picker插件:iosselect,"['iosselect', 'H5开发', '移动端插件', '日期时间选择', '触屏交互']
摘要由CSDN通过智能技术生成

感知机的理论,应用,博客,书籍多的是。 看机器学习算法的时候总是觉得感知机简单,大致粗过一遍就了事。对,我是来交后悔费的!哈。

感知机是支持向量机和神经网络的基础。嗯~~,

前提知识,如果童靴对 python 中的 reduce(),map(),copy() 不是特别了解的话,建议大家先去看一下这些知识。因为下面的感知机算法会用到。

感知机学习算法是误分类驱动,二分类的线性分类的判别模型~,他的学习算法有两种形式,~ 原始形式,对偶形式~

原始形式的感知机学习算法模型搭建

代码奉上~

"""
作者:jsionz
创作时间: 2019/12/14
联系邮箱:jsionz@163.com
希望跟大家一块探讨~~
"""
# 感知机学习算法      《统计学习方法》 李航
from functools import reduce
import copy
class Perceptron:

    def __init__(self,train_set_x,train_set_y,rate):
        """
        感知机初始化
        :param train_set_x: 训练集 features  [[features1(list)],[features2(list)],....]
        :param train_set_y: 训练集 label list  --->[label1,label2,label3,....]
        :param rate: 学习率
        """
        self.weights = [0.0 for _ in range(len(train_set_x[0]))]
        self.bias = 0.0
        self.train_x = copy.copy(train_set_x)
        self.train_y = copy.copy(train_set_y)
        self.rate = copy.copy(rate)

    def model_predict(self,input_vector):
        """
        感知器输出预测结果, y = sign(w*x + b)  sign   >= 0 ---> 1 ;  < 0 ---> -1   激活函数   1 if x>=0 -1
        """
        return 1 if ((reduce(lambda a,b:a+b,map(lambda w,x: w * x,self.weights,input_vector))) + self.bias) >=0 else -1

    def model_train(self):
        """
        模型训练过程
        """
        # 第一次计算
        miss_example_index = []
        for i in range(len(self.train_x)):
            value = (self.train_y[i]) * (reduce(lambda c,d:c + d ,list(map(lambda a,b:a * b,self.weights,self.train_x[i] ))) + self.bias)
            if value <= 0:
                miss_example_index.append(i)

        door = True
        while door:
            if miss_example_index:
                index = miss_example_index[0]
                # w , b 系数更新
                PD_rate = [self.rate * x_feature * self.train_y[index] for x_feature in self.train_x[index]]
                self.weights = list(map(lambda a,b:a + b,self.weights,PD_rate))
                self.bias = self.bias + (self.rate * self.train_y[index])

                while miss_example_index:
                    miss_example_index.pop()
                # 重新计算 误分类点
                for i in range(len(self.train_x)):
                    value = (self.train_y[i]) * (reduce(lambda c, d: c + d, list(
                        map(lambda a, b:
                            a * b, self.weights, self.train_x[i]))) + self.bias)
                    if value <= 0:
                        miss_example_index.append(i)
            else:
                door = False



if __name__ == "__main__":
    test_ex = Perceptron([[3,3],[4,3],[1,1]],[1,1,-1],1)
    test_ex.model_train()
    print(test_ex.model_predict([3,3]))
    print(test_ex.weights)














对偶形式的感知机学习算法模型搭建:

!在原始形式的感知机学习算法中,可以看到 权重值w和偏置项b的更新依赖于 训练数据。若我们在训练的开始,权重和偏置项初始化时,都为零~,那么,w,b的最终结果也只跟训练集有关~(见李航统计学习方法)

对偶形式就是把在某一刻的误分类点进行的权重跟新累加起来。就是这样~。arfa这个东西是可以看作计数器,只不是乘以了一个学习率。

# 感知机学习算法      《统计学习方法》 李航
from functools import reduce
import copy
class Perceptron:

    def __init__(self,train_set_x,train_set_y,rate):
        """
        感知机初始化
        :param train_set_x: 训练集 features  [[features1(list)],[features2(list)],....]
        :param train_set_y: 训练集 label list  --->[label1,label2,label3,....]
        :param rate: 学习率
        """
        self.weights = [0.0 for _ in range(len(train_set_x[0]))]
        self.bias = 0.0
        self.train_x = copy.copy(train_set_x)
        self.train_y = copy.copy(train_set_y)
        self.rate = copy.copy(rate)
        self.arfa = [0.0 for _ in range(len(train_set_x))]  # 对偶形式 需要用到的 阿尔法 的保存

    def gram_matrix(self):
        """
        感知机对偶形式训练数据用到的Gram矩阵
        :return: 
        """

        gram_matrix = []
        for i in range(len(self.train_x)):
            current_list = []
            for j in range(len(self.train_x)):
                current_list.append(reduce(lambda c,d:c + d,list(map(lambda a,b: a * b,self.train_x[i],self.train_x[j]))))
            gram_matrix.append(current_list)
        return gram_matrix

    def model_train_dualForm(self):
        """
        感知机对偶形式的训练
        :return: 
        """
        gram_matrix_list = self.gram_matrix()
        miss_example_index = []
        for i in range(len(self.train_x)):
            value = self.train_y[i] * reduce(lambda e,f:e + f ,list(map(lambda c,d:c * d,list(map(lambda a,b:a *b,
                    self.arfa,self.train_y)),gram_matrix_list[i])))
            if value <= 0:
                miss_example_index.append(i)

        door = True
        while door:
            if miss_example_index:
                index = miss_example_index[0]
                # arfa , b 系数更新
                self.arfa[index] = self.arfa[index] + self.rate
                self.bias = self.bias + (self.rate * self.train_y[index])

                while miss_example_index:
                    miss_example_index.pop()
                # 重新计算 误分类点
                for i in range(len(self.train_x)):
                    value = self.train_y[i] * reduce(lambda e, f: e + f,list(map(lambda c, d: c * d,
                    list(map(lambda a, b: a * b,self.arfa, self.train_y)),gram_matrix_list[i])))
                    if value <= 0:
                        miss_example_index.append(i)
                print(self.arfa)
                print(self.bias)
            else:
                door = False

    def model_dualForm_predict(self, input_vec):
        """
        对偶形式感知机模型的预测
        :param input_vec: 
        :return: 
        """
        new_list = []
        value_arfXY_list = list(map(lambda a, b: a * b, self.arfa, self.train_y))  # arda * y_i
        # arfa * y_i (n X 1) * train_x(n * 未知列)  见公式
        for i in range(len(self.train_x)):
            proed_list = [value * value_arfXY_list[i] for value in self.train_x[i]]
            new_list.append(proed_list)

        final_list = [0.0 for _ in range(len(new_list[0]))]
        while new_list:
            final_list = list(map(lambda a, b: a + b, final_list, new_list.pop()))

        return reduce(lambda c, d: c + d, list(map(lambda a, b: a * b, input_vec, final_list)))


















终于完结了~!,对偶性时的代码有点问题,但是整体思路,以及代码逻辑是没有问题的~,最近忙着要开题~我还有功夫搞这个~~哈。搞开题去咯,欢迎指正错误之处~   如果代码或者想法对您有帮助~那就谢谢打赏丫

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值