• 《机器学习》第一次作业——第一至三章学习记录和心得


    第一章 模式识别基本概念

    1.1 什么是模式识别

    模式识别:根据已有知识的表达,针对待识别模式,判别决策其所属的类别或者预测其对应的回归值。

    • 根据任务,模式识别可以划分为"分类”和"回归”两种形式。

      • 分类(Classification): 输出量是离散的类别表达,即输出待识别模式所属的类别

      • 回归(Regression): 输出量是连续的信号表达(回归值)

    1.2 模式识别数学表达

    • 数学解释:模式识别可以看做一-种函数映射f(x), 将待识别模式x从输入空间映射到输出空间。函数f(x)是关于已有知识的表达。

    以二分类为例

    判别公式:
    ( xin left{ egin{array}{l} C_1 quad if quad f(x)>0 \ C_2 quad if quad f(x)<0 end{array} ight. )
    决策边界:
    ( f(x)=0 )

    • 特征向量

    image-20210502151202391

    1.3 特征向量的相关性

    • 夹角:反映两个向量在方向上的差异性。
      $ cos heta = frac{x^Ty}{Vert xVertVert yVert}$

    • 投影: 向量x到y的投影(projection) :将向量x垂直投射到向量y方向上的长度(标量)。
      (x_0 = Vert x Vert cos heta)

    • 残差向量(residual vector) :向量x分解到向量y方向上得到的投影向量与原向量x的误差。
      (r_x = x-x_0=x-frac{Vert xVert cos heta}{Vert yVert}y)

    1.4 机器学习基本概念

    • 训练样本

      image-20210502152531791

    • 模型

      image-20210502152552786

    • 目标函数

      image-20210502152625857

    • 优化算法

      image-20210502152642086

    机器学习的分类

    • 监督式学习:训练样本及其输出真值都给定情况下的机器学习算法。

    • 无监督式学习:只给定训练样本、没有给输出真值情况下的机器学习算法。

    1.5 模型的泛化能力

    • 泛化能力:训练得到的模型不仅要对训练样本具有决策能力,也要对新的(训练过程中未看见)的模式具有决策能力。

    • 过拟合

      image-20210502153013017

    解决方案

    1. 选择复杂度适合的模型(tradeoff) :模型选择。
    2. 正则化(regularization) : 在目标函数中加入正则项。

    1.6 评估方法与性能指标

    评估方法

    • 留出法(Hold-out):随机划分:将数据集随机分为两组:训练集和测试集。利用训练集训练模型,然后利用测试集评估模型的量化指标。

    • K折交叉验证(K-Folds Cross Validation):将数据集分割成K个子集,从其中选取单个子集作为测试集,其他K - 1个子集作为训练集。

    • 留一验证(leave- one-out cross-validation):每次只取数据集中的一个样本做测试集,剩余的做训练集。

    性能指标

    image-20210502154242692

    • F1-score
      (F_1=frac{2*precision*recall}{precison+recall})

    • 混淆矩阵

      image-20210502154423189

    • P-R曲线

      image-20210502154446059

    • ROC

      image-20210502154507638

    • AUC

      image-20210502154524039

    第二章 基于距离的分类器

    2.1 MED分类器

    • 基于距离的决策:把测试样本到每个类之间的距离作为决策模型,将测试样本判定为与其距离最近的类。

    • 类的原型:用来代表这个类的一个模式或者一组量,便于计算该类和测试样本之间的距离。

    常用原型:均值
    (z_i=mu i=frac{Sigma_{xin C_i}x}{N_i})

    常用距离度量:

    image-20210502155146357

    MED分类器

    • 概念:最小欧式距离分类器(Minimum Euclidean Distance Classifier)
    • 距离衡量:欧式距离
    • 类的原型:均值
    • 决策边界: ((mu_2-mu_1)^T(x-frac{mu_1+mu_2}{2})=0)

    代码见MICD分类器

    2.2 特征白化

    • 特征白化的目的: 将原始特征映射到一个新的特征空间,使得在新空间中特征的协方差矩阵为单位矩阵,从而去除特征变化的不同及特征之间的相关性。

    image-20210502160025548

    步骤

    将特征转换分为两步:先去除特征之间的相关性(解耦, Decoupling),然后再对特征进行尺度变换(白化,Whitening),使每维特征的方差相等。
    (W = W_2W_1)
    解耦:通过(W)实现协方差矩阵对角化,去除特征之间的相关性。
    白化:通过(W_2)对上一步变换后的特征再进行尺度变换,实现所有
    特征具有相同方差。

    转换矩阵(W_1)的求法
    第一步:求解协方差矩阵(Sigma_x)的特征值和特征向量。
    第二步:由特征向量构建转换矩阵(W_1)

    转换矩阵(W_2)的求法

    image-20210502160441363

    2.3 MICD分类器

    • 马氏距离
      (d = (x_1-x_2)^TSigma_x^{-1}(x_1-x_2))

    MICD分类器

    • 最小类内距离分类器(Minimum Intra-class Distance Classifier) ,基于马氏距离的分类器。
    • 距离度量:马氏距离
    • 类的原型: 均值

    实现

    import numpy as np
    from sklearn.datasets import load_breast_cancer
    from sklearn.model_selection import train_test_split
    
    
    # distance传入'mahalanobis'代表马氏距离,其他代表欧式距离
    class MED(object):
        def __init__(self, distance='mahalanobis', prototype='mean'):
            # 实际上可以自己实现不同的distance和prototype函数以实现不同的分类器,目前就实现了一两种,所以这里的赋值作了简化
            # 设置距离度量
            if distance == 'mahalanobis':
                self.__distance = self.__distance_mahalanobis
            else:
                self.__distance = self.__distance_euclidean
            # 设置类的原型
            if True:
                self.__prototype = self.__prototype_mean
            # 是否训练完成
            self.__has_fit = False
            # 存储类的标签
            self.__tag = None
            # 训练集
            self.__train_data = []
            # 协方差矩阵的逆矩阵
            self.__cov_inv = []
            # 类的中心
            self.__center = []
    
        # 马氏距离
        # X_train是 n*m 的矩阵,代表n个元素,m个特征, index代表第几类
        def __distance_mahalanobis(self, X, index):
            return np.dot(np.dot((X - self.__center[index]).T, self.__cov_inv[index]), X - self.__center[index])
    
        # 欧式距离
        # X_train是 n*m 的矩阵,代表n个元素,m个特征, index代表第几类
        def __distance_euclidean(self, X, index):
            return np.dot((X - self.__center[index]).T, X - self.__center[index])
    
        # 均值
        def __prototype_mean(self, X):
            return np.mean(X, axis=0)
    
        # 训练, X_train是 n*m 的矩阵,代表n个元素,m个特征,Y_train为1维列向量,代表标签
        def fit(self, X_train, Y_train):
            self.__tag = np.unique(Y_train)
            for i in range(len(self.__tag)):
                # 划分当前数据
                cur_data = X_train[np.where(Y_train == self.__tag[i])]
                self.__train_data.append(cur_data)
                # 计算中心
                cur_center = self.__prototype(self.__train_data[i])
                self.__center.append(cur_center)
                # 如果距离度量为马氏距离,计算协方差矩阵
                if self.__distance == self.__distance_mahalanobis:
                    cur_cov = np.linalg.pinv(np.cov(self.__train_data[i].T))
                    self.__cov_inv.append(cur_cov)
            self.__has_fit = True
    
        # 预测单个数据 x为n维列向量
        def predict(self, x):
            if not self.__has_fit:
                print("模型还未训练")
                return
            dis = [self.__distance(x, i) for i in range(len(self.__tag))]
            return self.__tag[np.argmin(dis)]
    
        # 评估一组数据 X_test是 n*m 的矩阵,代表n个元素,m个特征,Y_test为1维列向量,代表标签
        def score(self, X_test, Y_test):
            if not self.__has_fit:
                print("模型还未训练")
                return
            if X_test.shape[0] == 0 or X_test.shape[0] != Y_test.shape[0]:
                print("参数不正确")
                return
            # pass
            correct = 0
            total = X_test.shape[0]
            for i in range(X_test.shape[0]):
                cur_tag = self.predict(X_test[i])
                if cur_tag == Y_test[i]:
                    correct += 1
                    # print(cur_tag)
            return correct / total
    
    
    # 使用乳腺癌数据集进行测试
    def main():
        cancer = load_breast_cancer()
        X = cancer.data
        Y = cancer.target
        X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=100)
        # 欧式距离 euclidean; 马氏距离 mahalanobis
        med = MED(distance="mahalanobis")
        med.fit(X_train, Y_train)
    
        print(med.score(X_train, Y_train))
        print(med.score(X_test, Y_test))
    
    
    main()
    

    第三章 贝叶斯决策与学习

    3.1 贝叶斯决策与MAP分类器

    • 基于距离的分类器存在的不足: 仅考虑每个类别各自观测到的训练样本的分布情况,没有考虑类的分布等先验知识

    贝叶斯派的观点

    image-20210502161917751

    决策条件

    image-20210502161930538

    MAP分类器

    • 定义: 最大后验概率(Maximum posterior probability, MAP)分类器:将测试样本决策分类给后验概率最大的那个类。

    • 特点: 给定所有测试样本,MAP分类器选择后验概率最大的类,等于最小化平均概率误差即最小化决策误差!

    3.2 MAP分类器:高斯观测概率

    先验和观测概率的表达方式

    • 常数表达:例如,(P(C_i)=0.2)
    • 参数化解析表达:高斯分布..
    • 非参数化表达:直方图、核密度、蒙特卡洛..

    我们将高斯分布作为观测概率

    image-20210502162509275

    image-20210502162520829

    • (sigma_i=sigma_j)时,决策边界是线性的。在方差相同的情况下,MAP决策边界偏向先验可能性较小的类,即分类器决策偏向先验概率高的类。

    • (sigma_i eqsigma_j)时,决策边界是关于x的二次型函数,分类器倾向于方差较小(紧致)的类。

    3.3 决策风险与贝叶斯分类器

    • 贝叶斯决策不能排除出现错误判断的情况,由此会带来决策风险。
    • 我们定义一个惩罚量,用来表征当前决策动作相对于其他候选类别的风险程度,即损失(loss)。

    image-20210503150756287

    贝叶斯分类器

    定义损失 (R(alpha_i|x)=Sigma_jlambda_{ij}p(C_j|x))

    贝叶斯分类器会选择风险最小的类

    • 期望损失

    image-20210503151102011

    朴素贝叶斯

    • 假设特征之间相互独立

    image-20210503151151385

    实现

    from sklearn.model_selection import train_test_split
    from sklearn.datasets import load_iris
    import numpy as np
    
    
    
    class BayesClassifier(object):
        def __init__(self):
            # 是否训练完成
            self.__has_fit = False
            # 存储类的标签
            self.__tag = None
            # 训练集
            self.__train_data = []
            # 方差
            self.var = []
            # 类的中心
            self.center = []
    
        def Gaussian(self, X, tag):
            on = 1/(np.sqrt(2*np.pi * self.var[tag])*np.exp((X - self.center[tag]) ** 2/(2 * self.var[tag])))
            return np.prod(on)
    
        # 均值
        def __mean(self, X):
            return np.mean(X, axis=0)
    
        def fit(self, X_train, Y_train):
            self.__tag = np.unique(Y_train)
            for i in range(len(self.__tag)):
                # 划分当前数据
                cur_data = X_train[np.where(Y_train == self.__tag[i])]
                self.__train_data.append(cur_data)
                # 计算中心
                cur_center = self.__mean(self.__train_data[i])
                self.center.append(cur_center)
                # 计算方差
                cur_var = np.var(self.__train_data[i].T, axis=1)
                self.var.append(cur_var)
            self.__has_fit = True
    
        # 预测单个数据 x为n维列向量
        def predict(self, x):
            if not self.__has_fit:
                print("模型还未训练")
                return
            dis = [self.Gaussian(x, i) for i in range(len(self.__tag))]
            # print(dis)
            return self.__tag[np.argmax(dis)]
    
        # 评估一组数据 X_test是 n*m 的矩阵,代表n个元素,m个特征,Y_test为1维列向量,代表标签
        def score(self, X_test, Y_test):
            if not self.__has_fit:
                print("模型还未训练")
                return
            if X_test.shape[0] == 0 or X_test.shape[0] != Y_test.shape[0]:
                print("参数不正确")
                return
            # pass
            correct = 0
            total = X_test.shape[0]
            for i in range(X_test.shape[0]):
                cur_tag = self.predict(X_test[i])
                if cur_tag == Y_test[i]:
                    correct += 1
                    # print(cur_tag)
            return correct / total
    
    # 使用乳腺癌数据集进行测试
    def main():
        cancer = load_iris()
        X = cancer.data
        Y = cancer.target
        X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=100)
        # 欧式距离 euclidean; 马氏距离 mahalanobis
        bayes = BayesClassifier()
        bayes.fit(X_train, Y_train)
    
        print(bayes.score(X_train, Y_train))
        print(bayes.score(X_test, Y_test))
    
    main()
    
    

    3.4 最大似然估计

    常用的参数估计方法

    1. 最大似然估计
    2. 贝叶斯估计

    极大似然估计(具体可参考概率论相关教材)

    image-20210503151452680

    • 之后,对参数求偏导,并令偏导为0即刻得到解

    3.5 最大似然的估计偏差

    • 如果一个参数的估计量的数学期望是该参数的真值,则该估计量称作无偏估计(unbiased estimates)。

    对于高斯分布

    image-20210503151748308

    image-20210503151805320

    • 在实际计算中,可以通过将训练样本的协方差乘以N/(N- 1)来修正协方差的估计值

    3.6&3.7 贝叶斯估计

    • 概率分布中待学习的参数也可以当做随机变量。
    • 贝叶斯估计:给定参数分布的先验概率以及训练样本,估计参数分布的后验概率。

    以高斯分布为例,假设待估计参数( heta)是高斯分布的均值(mu) ,并假设( hetasim N(mu_0, sigma_0^2))

    image-20210503152255576

    经过整理,可以解得

    image-20210503152323050

    将贝叶斯估计用于MAP分类器

    将之前得到的结果带入

    image-20210503152623740

    image-20210503152634156

    极大似然估计与贝叶斯估计的对比

    • 前者将参数视为一个确定值,通过优化技术来求解参数
    • 后者将参数视为随机变量,通过求取边缘概率来得到观测似然

    3.8 KNN估计

    • 如果概率分布形式未知,可以通过无参数(non -parametric)技术来实现概率密度估计。

    image-20210503153006469

    image-20210503153021992

    3.9 直方图与核密度估计

    直方图估计

    knn存在的问题:

    1. 在推理测试阶段,仍然需要存储所有训练样本,因为针对任意一个模式x,需要以其为中心,在训练样本中寻找k个相邻点来估计该模式的概率。
    2. 易受噪声影响。
    • 原理:(p(x)approxfrac{k}{NV})

    image-20210503153314775

    image-20210503153325906

    优点

    1. 不需要存储训练数据
    2. 减小了噪声污染

    核密度估计

    image-20210503153448823

    image-20210503153500823

    常用核函数:高斯分布、均匀分布、三角分布

    优点:

    1. 使用所有训练样本,而不是基于第k个近邻点来估计概率密度,从而克服KNN估计存在的噪声影响。
    2. 如果核函数是连续,则估计的概率密度函数也是连续的。
  • 相关阅读:
    移除中文部分
    将阿拉伯数字转换为语文汉字数字
    Lua 字符串
    json.dump()和json.load()
    json文件为空时读取会报错
    矩阵相加
    python 三维数组找最小值
    python 行列式计算
    python 日期的减法
    python 字典的合并
  • 原文地址:https://www.cnblogs.com/forestj/p/14727570.html
Copyright © 2020-2023  润新知