【统计学习方法】感知机

1 基本概念

1.1 向量点乘

向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。

向量\LARGE a=(a{_1},a{_2},a{_3}...)

向量\LARGE b=(b{_1},b{_2},b{_3}...)

则a,b点乘 \LARGE a\cdot b = a{_1}b{_1} +a{_2}b{_2} +a{_3}b{_3} ...

点乘的几何意义是可以用来表征或计算两个向量之间的夹角,以及在b向量在a向量方向上的投影

\LARGE a\cdot b = |a||b|cos\theta

1.2 点到直线距离公式

直线公式\LARGE Ax+By+C = 0,直线外一点\LARGE (x{_0},y{_0}),则点到直线的距离公式为:

\LARGE d =\left | \frac{Ax{_0}+By{_0}+C}{\sqrt{A^2+B^2}}\right |

1.3 超平面

而d维空间中的超平面由下面的方程确定:\large w^Tx + b =0,其中,w与x都是d维列向量\large x=(x{_1},x{_2},x{_3}...)^T为平面上的点, \large w=(w{_1},w{_2},w{_3}...)^T为平面的法向量。b是一个实数, 决定平面与原点之间的距离(其他文章说是远点到平面的距离,其实是不对的).

平面外一点到平面的距离\LARGE d = \left | \frac{w\cdot x+b}{\left \| w \right \|} \right |,是点到直线距离的延伸,

原点为(0,0,0...),所以原点到平面距离\LARGE d{_0} = \left | \frac{b}{\left \| w \right \|} \right |

 

1.4 感知机

感知机是二分类的的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1二值。

\large f(x) = sign(w\cdot x + b)

其中w和b为感知机的模型参数,w是权值向量,b叫做偏置,\large w\cdot x叫是w和x的的內积,sign为符号函数,当右边表达式值大于0时,函数值为1,当右边表达式小于0时,函数值为-1.

 

2 感知机的损失函数

2.1 误分类点到超平面总距离和损失函数

误分类点到平面的距离总和为:\large d(x) = \frac{1}{\left \| w \right \|}\sum \left | w\cdot x{_i} + b \right | (x{_i} \in M)M为误分类点的集合,

对于误分类的数据\large (x{_i},y{_i})来说,\large -y{_i}(w\cdot x{_i}+b) > 0, 因为\large w\cdot x{_i}+b > 0时,\large y{_i} = -1,\large w\cdot x{_i}+b) < 0时,\large y{_i} = 1,所以

\large d(x) =- \frac{1}{\left \| w \right \|}\sum y{_i}(w\cdot x{_i} + b) (x{_i} \in M)

忽略\large \frac{1}{\left \| w \right \|},则损失函数为\large L(x) =- \sum y{_i}(w\cdot x{_i} + b) (x{_i} \in M)感知机中的损失函数中的分母为什么可以不考虑

2.2 梯度下降法优化

对于\large L(w,b) = -y{_i}(w \cdot x{_i}+b),\large L(w,b)的梯度如下:

\large \Delta wL(w,b) = -y{_i}x{_i}

\large \Delta bL(w,b) = -y{_i}

极小化的过程不是一次使M中的所有误分类点的梯度下降,而是随机选取一个误分类点使其梯度下降。

3 感知机代码实现(

import random
import numpy as np
import matplotlib.pyplot as plt
import time


class percePtron:
    # 初始化w向量和截距b,注意初始化为浮点类型
    def __init__(self):
        self.weight = [0.0, 0.0]
        self.bias = 0.0

    def draw(self, x1, x2, y1, y2):
        plt.scatter(x1, y1, label="y = 1")
        plt.scatter(x2, y2, label="y = -1")
        plt.legend()
        plt.xlabel('X1')
        plt.ylabel('X2')
        label_x = np.linspace(0, 4, 20)
        # print(-(self.bias + self.weight[0] * label_x) / self.weight[1])
        plt.plot(label_x, -(self.bias + self.weight[0] * label_x) / self.weight[1])
        plt.show()

    #  learning_rate=0.1表示为步长为0.1,step表示为训练次数,data为样本集
    def train(self, data, learning_rate=0.01, step=1000):
        self.weight = np.array(self.weight)
        for i in range(step):

            randomindex = random.randint(0, len(data) - 1)
            #随机选取样本点
            randomData = data[randomindex]
            # 如果y(wx + b) <= 0,则表明这个点为误分类点
            if randomData[2] * (self.weight[0] * randomData[0] + self.weight[1] * randomData[1] + self.bias) <= 0:
                # 此处为梯度下降算法更新w和b
                self.weight[0] = self.weight[0] + randomData[2] * randomData[0] * learning_rate
                self.weight[1] = self.weight[1] + randomData[2] * randomData[1] * learning_rate
                self.bias = self.bias + randomData[2] * learning_rate
                print("weight : ", self.weight)
                print("bias : ", self.bias)


if __name__ == "__main__":
    data = [[1, 4, 1], [0.5, 2, 1], [2, 2.3, 1], [1, 0.5, -1], [2, 1, -1],
            [4, 1, -1], [3.5, 4, 1], [3, 2.2, -1], [4, 2.2, -1], [5, 2.2, -1], [6, 2.2, -1]]
    x1 = []
    y1 = []
    x2 = []
    y2 = []
    for p in data:
        if p[2] > 0:
            x1.append(p[0])
            y1.append(p[1])
        else:
            x2.append(p[0])
            y2.append(p[1])
    x1 = np.array(x1)
    x2 = np.array(x2)
    y1 = np.array(y1)
    y2 = np.array(y2)
    model = percePtron()
    model.train(data)
    model.draw(x1, x2, y1, y2)

 

 

参考:

1 《统计学方法》

2  https://blog.csdn.net/lilong117194/article/details/78209862

3  https://blog.csdn.net/red_stone1/article/details/80491895

4  https://blog.csdn.net/dcrmg/article/details/52416832

5  https://www.cnblogs.com/BlueBlueSea/p/10059529.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值