zoukankan      html  css  js  c++  java
  • 实验一 感知器及其应用

    【实验目的】

    1. 理解感知器算法原理,能实现感知器算法;
    2. 掌握机器学习算法的度量指标;
    3. 掌握最小二乘法进行参数估计基本原理;
    4. 针对特定应用场景及数据,能构建感知器模型并进行预测。

    【实验内容】

    1. 安装Pycharm,注册学生版。
    2. 安装常见的机器学习库,如Scipy、Numpy、Pandas、Matplotlib,sklearn等。
    3. 编程实现感知器算法。
    4. 熟悉iris数据集,并能使用感知器算法对该数据集构建模型并应用。

    【感知机定义】

    1.感知机是根据输入实例的特征向量(x)对其进行二类分类的线性分类模型:

    [f(x)=operatorname{sign}(w cdot x+b) ]

    感知机模型对应于输入空间(特征空间)中的分离超平面(w cdot x+b=0)
    2.感知机学习的策略是极小化损失函数:

    [min _{w, b} L(w, b)=-sum_{x_{i} in M} y_{i}left(w cdot x_{i}+b ight) ]

    损失函数对应于误分类点到分离超平面的总距离。
    3.感知机学习算法是基于随机梯度下降法的对损失函数的最优化算法,有原始形式和对偶形式。算法简单且易于实现。原始形式中,首先任意选取一个超平面,然后用梯度下降法不断极小化目标函数。在这个过程中一次随机选取一个误分类点使其梯度下降。
    4.当训练数据集线性可分时,感知机学习算法是收敛的。感知机算法在训练数据集上的误分类次数(k)满足不等式:

    [k leqslantleft(frac{R}{gamma} ight)^{2} ]

    当训练数据集线性可分时,感知机学习算法存在无穷多个解,其解由于不同的初值或不同的迭代顺序而可能有所不同。

    【二分类模型基本实现】

    (f(x) = sign(wcdot x + b))
    (operatorname{sign}(x)=left{egin{array}{ll}{+1,} & {x geqslant 0} \ {-1,} & {x<0}end{array} ight.)
    给定训练集:
    (T=left{left(x_{1}, y_{1} ight),left(x_{2}, y_{2} ight), cdots,left(x_{N}, y_{N} ight) ight})
    定义感知机的损失函数
    (L(w, b)=-sum_{x_{i} in M} y_{i}left(w cdot x_{i}+b ight))

    随即梯度下降法 Stochastic Gradient Descent

    随机抽取一个误分类点使其梯度下降。

    (w = w + eta y_{i}x_{i})

    (b = b + eta y_{i})

    当实例点被误分类,即位于分离超平面的错误侧,则调整(w), (b)的值,使分离超平面向该无分类点的一侧移动,直至误分类点被正确分类
    拿出iris数据集中两个分类的数据和[sepal length,sepal width]作为特征

    import pandas as pd
    import numpy as np
    from sklearn.datasets import load_iris
    import matplotlib.pyplot as plt
    %matplotlib inline
    # load data
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)
    df['label'] = iris.target
    df.columns = [
        'sepal length', 'sepal width', 'petal length', 'petal width', 'label'
    ]
    df.label.value_counts()
    plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
    plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend()
    

    data = np.array(df.iloc[:100, [0, 1, -1]])
    X, y = data[:,:-1], data[:,-1]
    y = np.array([1 if i == 1 else -1 for i in y])
    
    # 数据线性可分,二分类数据
    # 此处为一元一次线性方程
    class Model:
        def __init__(self):
            self.w = np.ones(len(data[0]) - 1, dtype=np.float32)
            self.b = 0
            self.l_rate = 0.1
            # self.data = data
    
        def sign(self, x, w, b):
            y = np.dot(x, w) + b
            return y
    
        # 随机梯度下降法
        def fit(self, X_train, y_train):
            is_wrong = False
            while not is_wrong:
                wrong_count = 0
                for d in range(len(X_train)):
                    X = X_train[d]
                    y = y_train[d]
                    if y * self.sign(X, self.w, self.b) <= 0:
                        self.w = self.w + self.l_rate * np.dot(y, X)
                        self.b = self.b + self.l_rate * y
                        wrong_count += 1
                if wrong_count == 0:
                    is_wrong = True
            return 'Perceptron Model!'
    
        def score(self):
            pass
    
    perceptron = Model()
    perceptron.fit(X, y)
    
    x_points = np.linspace(4, 7, 10)
    y_ = -(perceptron.w[0] * x_points + perceptron.b) / perceptron.w[1]
    plt.plot(x_points, y_)
    
    plt.plot(data[:50, 0], data[:50, 1], 'bo', color='blue', label='0')
    plt.plot(data[50:100, 0], data[50:100, 1], 'bo', color='orange', label='1')
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend()
    

    scikit-learn实现

    import sklearn
    from sklearn.linear_model import Perceptron
    clf = Perceptron(fit_intercept=True, 
                     max_iter=1000, 
                     shuffle=True)
    clf.fit(X, y)
    # Weights assigned to the features.
    print(clf.coef_)
    # 截距 Constants in decision function.
    print(clf.intercept_)
    # 画布大小
    plt.figure(figsize=(10,10))
    
    # 中文标题
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.title('鸢尾花线性数据示例')
    
    plt.scatter(data[:50, 0], data[:50, 1], c='b', label='Iris-setosa',)
    plt.scatter(data[50:100, 0], data[50:100, 1], c='orange', label='Iris-versicolor')
    
    # 画感知机的线
    x_ponits = np.arange(4, 8)
    y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]
    plt.plot(x_ponits, y_)
    
    # 其他部分
    plt.legend()  # 显示图例
    plt.grid(False)  # 不显示网格
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend()
    

    tol 参数规定了如果本次迭代的损失和上次迭代的损失之差小于一个特定值时,停止迭代。所以我们需要设置 tol=None 使之可以继续迭代:

    clf = Perceptron(fit_intercept=True, 
                     max_iter=1000,
                     tol=None,
                     shuffle=True)
    clf.fit(X, y)
    
    # 画布大小
    plt.figure(figsize=(10,10))
    
    # 中文标题
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.title('鸢尾花线性数据示例')
    
    plt.scatter(data[:50, 0], data[:50, 1], c='b', label='Iris-setosa',)
    plt.scatter(data[50:100, 0], data[50:100, 1], c='orange', label='Iris-versicolor')
    
    # 画感知机的线
    x_ponits = np.arange(4, 8)
    y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]
    plt.plot(x_ponits, y_)
    
    # 其他部分
    plt.legend()  # 显示图例
    plt.grid(False)  # 不显示网格
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend()
    

    【实验小结】

    我理解了感知器算法及其原理基本实现感知器算法。并掌握机器学习算法的度量指标。了解最小二乘法进行参数估计基本原理。针对特定应用场景及数据,能构建感知器模型并进行预测。

  • 相关阅读:
    51nod 1087 1 10 100 1000(找规律+递推+stl)
    51nod 1082 与7无关的数 (打表预处理)
    51 nod 1080 两个数的平方和
    1015 水仙花数(水题)
    51 nod 1003 阶乘后面0的数量
    51nod 1002 数塔取数问题
    51 nod 1001 数组中和等于K的数对
    51 nod 1081 子段求和
    51nod 1134 最长递增子序列 (O(nlogn)算法)
    51nod 1174 区间中最大的数(RMQ)
  • 原文地址:https://www.cnblogs.com/smallsung/p/14703412.html
Copyright © 2011-2022 走看看