【机器学习】周志华西瓜书第八章集成学习习题8.3--编程实现AdaBoost模型,以不剪枝决策树为基学习器,在西瓜数据集3.0a上训练一个AdaBoost集成,并与教材图8.4进行比较

2023-05-16

1)问题理解与分析

编程实现AdaBoost模型,不剪枝决策树为基学习器,在西瓜数据集3.0a上训练一个AdaBoost集成,并与教材图8.4进行比较。

 

2AdaBoost算法原理阐述

集成学习是一种通过构建并结合多个学习器来完成学习任务的机器学习方法。同质集成中的个体学习器亦称“基学习器”。集成学习通过将多个学习器进行结合,常可获得比单一学习器显著优越的泛化性能。根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即个体学习器间存在强依赖关系、必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系、可同时生成的并行化方法;前者的代表是Boosting,后者的代表是Bagging和随机森林。

22b755442d4845c68c6c70533ecde285.png

Boosting是一族可将弱学习器提升为强学习器的算法。这族算法的工作机制类似可描述为:先从初始训练集训练出一个基学习器,再根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续受到更多关注,然后基于调整后的样本分布来训练下一个基学习器;如此重复进行,直至基学习器数目达到事先指定的值T,最终将这T个基学习器进行加权结合。

 

00bd52719b6c4185b64e9f5ef2644ae3.png

3AdaBoost算法设计思路

根据上面的数学推导,已经得出了基学习器的权重更新公式,于是可以得出AdaBoost的算法步骤:

379222b9d943427e862eff3de906740d.png

 

c915c62f44404a38a91bb66063213986.png

4AdaBoost实验流程分析

AdaBoost算法的核心思想是前向分布求解,即每一轮只学习一个弱学习器及它的权重。通俗来讲,AdaBoost算法分为三步:

首先初始化训练数据的权值分布,如果有m个样本,则每一个训练样本最开始时都被赋予相同的权值1/m。

之后训练弱分类器,具体训练过程中,如果某个样本点已经被准确地分类,那么在构造下一个训练集中,它的权重就被降低,而如果某个样本点没有被准确地分类,那么它的权值就得到提高,权值更新过的样本集被用于训练下一个分类器,整个训练过程如此迭代地进行下去。

最后将各个训练得到的弱分类器组合成强分类器,各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。

把以上过程绘制成流程图如下:

81eb08870b084881be546992c8121b9f.png

 

5实验数据的选择(训练集和测试集划分)、实验结果展示、优化与分析

本实验使用的数据集是西瓜数据集3.0,只使用连续型属性。当基学习器数量为3时,我的结果与周志华《机器学习》(西瓜书)对比如下:

6e781f65463b47d6a3f91fca3f94b4a4.pngf6c0f824b94845158cd17ee1d4b123d1.png

前者17个样本预测正确12个,正确率为70.6%;后者17个样本预测正确16个,正确率94.1%。

当基学习器数量为5时,我的结果与周志华《机器学习》(西瓜书)对比如下:

 

c7608200c0f341cdb05660fdc3cb76b0.png  f8c1de153a5b43fb9ecfae41bcf84fa5.png

前者17个样本预测正确15个,正确率为88.2%;后者17个样本预测正确16个,正确率94.1%。

当基学习器数量为11时,我的结果与周志华《机器学习》(西瓜书)对比如下:

 

c529256aae4f495fa0ab0a6788f13ba2.png  107e1b7ea6124e42845a369d1c902734.png

前者17个样本预测正确17个,正确率为100%;后者17个样本预测正确17个,正确率100%。

6)代码结构注释、核心源代码简要分析

本次实验的核心函数就是AdaBoost,其输入为数据集dataSet和基学习器T,输出是保存分类器的字典G和样本权重列表D。它的基本思想是,首先初始化权重,每个样本的初始化权重相同,之后对每一个分类器都根据样本权重D建立决策树桩,并根据其错误率确定该学习器在总学习器中的权重(正确率越高,权重越大)和调整训练样本的权重(被该学习器错误分类的数据提高权重,正确分类的降低权重)。

def AdaBoost(dataSet, T):
    m, n = dataSet.shape # 17,3

    D = np.ones((1, m)) / m         。

    classLabel = dataSet[:, -1].reshape(1, -1)   # 数据的类标签。

    G = {}      # 保存分类器的字典
    H=[]
    for t in range(T):                        
        stump ,h= buildStump(dataSet, D)     
        err = stump["err"]
        H.append(h)
        alpha = np.log((1 - err) / err) / 2    # 第t个分类器的权值
        # 更新训练数据集的权值分布
        pre = np.zeros((1, m))
        for i in range(m):
            pre[0][i] = predict(dataSet[i], stump)

        a = np.exp(-alpha * classLabel * pre)
        D = D * a / np.dot(D, a.T)

        G[t] = {}
        G[t]["alpha"] = alpha
        G[t]["stump"] = stump

    H = np.array(H)
    return G,H,D

buildStump函数用于建立错误率最小的决策树桩,其基本思想就是对每个特征下的数值,以一定的步长进行遍历(取决于设置的步数),对比移动到哪个位置的时候错误率最低,于是就能得到该数据集下的最优单层决策树。  

 

def buildStump(dataSet, D):
    m, n = dataSet.shape  # (17,3)

    bestErr = np.inf
    bestStump = {}
    h=[]
    numSteps = 16.0  # 每个特征迭代的总步数
    for i in range(n-1):                    # 对第i个特征
        rangeMin = dataSet[:, i].min()
        rangeMax = dataSet[:, i].max()  # 每个属性列的最大最小值
        stepSize = (rangeMax - rangeMin) / numSteps  # 每一步的长度
        for j in range(m):                  # 对第j个样本
            threVal = rangeMin + float(j) * stepSize  # 每一步划分的阈值
            for inequal in ['lt', 'gt']:    # 对于大于或等于符号划分。
                err = calErr(dataSet, i, threVal, inequal, D)  # 错误率
                if err < bestErr:           # 如果错误更低,保存划分信息。
                    bestErr = err
                    bestStump["feature"] = i
                    bestStump["threshVal"] = threVal
                    bestStump["inequal"] = inequal
                    bestStump["err"] = err

    h.append(bestStump["feature"])
    h.append(bestStump["threshVal"])
    if bestStump["inequal"]=='lt':
        h.append(-1)
        h.append(1)
    if bestStump["inequal"]=='gt':
        h.append(1)
        h.append(-1)
    return bestStump,h

7)本次实验解决的主要问题、在理论学习与动手编程上的主要收获

要想顺利完成本次实验,必须深入理解AdaBoost算法的步骤及集成思想。AdaBoost算法可分为3个步骤,首先初始化训练数据的权值分布,每一个训练样本最开始时,都会被赋予相同的权值;之后训练弱分类器,如果某个训练样本点,被弱分类器准确地分类,那么再构造下一个训练集中,它对应的权值要减小,而如果某个训练样本点被错误分类,那么它的权值就应该增大,权值的更新过的样本被用于训练下一个弱分类器,整个过程如此迭代下去;

最后,将各个训练得到的弱分类器组合成一个强分类器。各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。

通过本次实验,我认识到AdaBoost提供了一种框架,在框架内可以使用各种方法构建子分类器,可以使用简单的弱分类器,不用对特征进行筛选,也不存在过拟合的现象。同时AdaBoost算法不需要弱分类器的先验知识,最后得到的强分类器的分类精度依赖于所有弱分类器。无论是应用于人造数据还是真实数据,AdaBoost都能显著的提高学习精度。另外AdaBoost算法不需要预先知道弱分类器的错误率上限,且最后得到的强分类器的分类精度依赖于所有弱分类器的分类精度,可以深挖分类器的能力。最后,AdaBoost可以根据弱分类器的反馈,自适应地调整假定的错误率,执行的效率高。但不能忽视的是,在训练过程中,AdaBoost会使得难于分类样本的权值呈指数增长,训练将会过于偏向这类困难的样本,导致AdaBoost算法易受噪声干扰。此外,AdaBoost依赖于弱分类器,而弱分类器的训练时间往往很长。

 

完整代码:

# coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from numpy import linspace

def getWatermelonDataSet():
    """
    西瓜数据集3.0alpha。 列:[密度,含糖量,好瓜]
    :return: np数组。
    """
    data = pd.read_csv('D:\学习\专业主干课\机器学习\数据集\\watermalon3.0a.csv')
    data=np.array(data)
    label=data[:,-1]
    return data,label


def getUCIDataSet():
    data=pd.read_excel('D:\学习\专业主干课\机器学习\数据集\\UCI数据集\\iris.xlsx')
    data=np.array(data)
    label=data[:,-1]
    return data,label

def calErr(dataSet, feature, threshVal, inequal, D):
    """
    计算数据带权值的错误率。
    :param dataSet:     [密度,含糖量,好瓜]
    :param feature:     [密度,含糖量]
    :param threshVal:
    :param inequal:     'lt' or 'gt. (大于或小于)
    :param D:           数据的权重。错误分类的数据权重会大。
    :return:            错误率。
    """
    DFlatten = D.flatten()   # 变为一维

    #print(DFlatten)
    errCnt = 0
    i = 0
    if inequal == 'lt':  #如果认为低于阈值为好瓜
        for data in dataSet:
            if (data[feature] <= threshVal and data[-1] == -1) or \
               (data[feature] > threshVal and data[-1] == 1):  #则错误判断 = 低于阈值且为坏瓜 + 高于阈值且为好瓜
                errCnt += 1 * DFlatten[i]  #该样本的权重作为错误率
            i += 1
    else:
        for data in dataSet:
            if (data[feature] >= threshVal and data[-1] == -1) or \
               (data[feature] < threshVal and data[-1] == 1):
                errCnt += 1 * DFlatten[i]
            i += 1

    return errCnt


def buildStump(dataSet, D):
    """
    通过带权重的数据,建立错误率最小的决策树桩。
    """
    m, n = dataSet.shape  # (17,3)

    bestErr = np.inf
    bestStump = {}
    h=[]
    numSteps = 16.0  # 每个特征迭代的总步数
    for i in range(n-1):                    # 对第i个特征
        rangeMin = dataSet[:, i].min()
        rangeMax = dataSet[:, i].max()  # 每个属性列的最大最小值
        stepSize = (rangeMax - rangeMin) / numSteps  # 每一步的长度
        for j in range(m):                  # 对第j个样本
            threVal = rangeMin + float(j) * stepSize  # 每一步划分的阈值
            for inequal in ['lt', 'gt']:    # 对于大于或等于符号划分。
                err = calErr(dataSet, i, threVal, inequal, D)  # 错误率
                if err < bestErr:           # 如果错误更低,保存划分信息。
                    bestErr = err
                    bestStump["feature"] = i
                    bestStump["threshVal"] = threVal
                    bestStump["inequal"] = inequal
                    bestStump["err"] = err

    h.append(bestStump["feature"])
    h.append(bestStump["threshVal"])
    if bestStump["inequal"]=='lt':
        h.append(-1)
        h.append(1)
    if bestStump["inequal"]=='gt':
        h.append(1)
        h.append(-1)
    #print(h)
    return bestStump,h


def predict(data, bestStump):
    """
    通过决策树桩预测数据
    :param data:        待预测数据
    :param bestStump:   决策树桩。
    :return:
    """
    if bestStump["inequal"] == 'lt':
        if data[bestStump["feature"]] <= bestStump["threshVal"]:
            return 1
        else:
            return -1
    else:
        if data[bestStump["feature"]] >= bestStump["threshVal"]:
            return 1
        else:
            return -1


def AdaBoost(dataSet, T):
    """
    每学到一个学习器,根据其错误率确定两件事。
    1.确定该学习器在总学习器中的权重。正确率越高,权重越大。
    2.调整训练样本的权重。被该学习器误分类的数据提高权重,正确的降低权重,
      目的是在下一轮中重点关注被误分的数据,以得到更好的效果。
    :param dataSet:  数据集。
    :param T:        迭代次数,即训练多少个分类器
    :return:         字典,包含了T个分类器。
    """
    m, n = dataSet.shape # 17,3

    D = np.ones((1, m)) / m          # 初始化权重,每个样本的初始权重是相同的。

    classLabel = dataSet[:, -1].reshape(1, -1)   # 数据的类标签。

    G = {}      # 保存分类器的字典,
    H=[]
    for t in range(T):                        # 对每一个分类器
        stump ,h= buildStump(dataSet, D)     # 根据样本权重D建立一个决策树桩
        err = stump["err"]
        H.append(h)
        alpha = np.log((1 - err) / err) / 2    # 第t个分类器的权值
        # 更新训练数据集的权值分布
        pre = np.zeros((1, m))
        for i in range(m):
            pre[0][i] = predict(dataSet[i], stump)

        a = np.exp(-alpha * classLabel * pre)
        D = D * a / np.dot(D, a.T)

        G[t] = {}
        G[t]["alpha"] = alpha
        G[t]["stump"] = stump

    H = np.array(H)
    print(H)
    return G,H,D


def adaPredic(data, G):
    """
    通过Adaboost得到的总的分类器来进行分类。
    :param data:    待分类数据。
    :param G:       字典,包含了多个决策树桩
    :return:        预测值
    """
    score = 0
    for key in G.keys():
        pre = predict(data, G[key]["stump"])  #每个基分类器的预测结果
        score += G[key]["alpha"] * pre        #加权结合后的集成预测结果
    flag = 0
    if score > 0:
        flag = 1
    else:
        flag = -1
    return flag


def plotROC(pred_strengths, class_labels):
    print(pred_strengths)
    # AUC,曲线下的面积
    import matplotlib.pyplot as plt
    cur = (1.0, 1.0)  # cursor  # 起始点
    y_sum = 0.0  # variable to calculate AUC
    num_pos_clas = sum(np.array(class_labels) == 1)  # 正例的数目
    # 这两个是步长
    y_step = 1 / float(num_pos_clas)
    x_step = 1 / float(len(class_labels) - num_pos_clas)
    # 从小到大排列,再得到下标
    sorted_indicies = pred_strengths.argsort()  # get sorted index, it's reverse
    fig = plt.figure()
    fig.clf()  # 清空
    ax = plt.subplot(111)
    # loop through all the values, drawing a line segment at each point
    for index in sorted_indicies.tolist()[0]:  # np对象变成list
        if class_labels[index] == 1.0:
            del_x = 0
            del_y = y_step
        else:
            del_x = x_step
            del_y = 0
            y_sum += cur[1]
        # draw line from cur to (cur[0]-delX,cur[1]-delY)
        ax.plot([cur[0], cur[0] - del_x], [cur[1], cur[1] - del_y], c='b')
        cur = (cur[0] - del_x, cur[1] - del_y)
    ax.plot([0, 1], [0, 1], 'b--')
    plt.xlabel('False positive rate')
    plt.ylabel('True positive rate')
    plt.title('ROC curve for AdaBoost horse colic detection system')
    ax.axis([0, 1, 0, 1])
    plt.show()
    print("the Area Under the Curve is: ", y_sum * x_step)



def calcAcc(dataSet, G):
    """
    计算准确度
    :param dataSet:     数据集
    :param G:           字典,包含了多个决策树桩
    :return:
    """
    rightCnt = 0
    for data in dataSet:
        pre = adaPredic(data, G)
        if pre == data[-1]:
            rightCnt += 1
    return rightCnt / float(len(dataSet))


def predictt(H, X1, X2):
    # 预测结果
    # 仅X1和X2两个特征,X1和X2同维度
    pre = np.zeros(X1.shape)

    for h in H:
        df, t, lv, rv = h  # 划分特征,划分点,左枝取值,右枝取值
        X = X1 if df == 0 else X2
        pre += (X <= t) * lv + (X > t) * rv
    return np.sign(pre)

# 绘制数据集,clf为获得的集成学习器
def plotData(data, clf,H,t):

    xx1min, xx1max = data[:, 0].min(), data[:, 0].max()
    xx2min, xx2max = data[:, 1].min(), data[:, 1].max()
    xx1 = np.linspace(xx1min - (xx1max - xx1min) * 0.2, xx1max + (xx1max - xx1min) * 0.2, 100)
    xx2 = np.linspace(xx2min - (xx2max - xx2min) * 0.2, xx2max + (xx2max - xx2min) * 0.2, 100)
    XX1, XX2 = np.meshgrid(xx1, xx2)
    Ypre = predictt(H[:t], XX1, XX2)

    plt.contour(XX1, XX2, Ypre, colors='crimson', linewidths=4.7, levels=[0])

    X1, X2 = [], []
    Y1, Y2 = [], []
    datas=data
    labels=data[:,2]

    for data, label in zip(datas, labels):
        if label > 0:
            X1.append(data[0])
            Y1.append(data[1])
        else:
            X2.append(data[0])
            Y2.append(data[1])

    x = linspace(0, 0.8, 100)
    y = linspace(0, 0.6, 100)

    for key in clf.keys():

        z = [clf[key]["stump"]["threshVal"]]*100
        if clf[key]["stump"]["feature"] == 0:
           plt.plot(z, y)
        else:
           plt.plot(x, z)

    plt.scatter(X1, Y1, marker='d', label='好瓜', color='b')
    plt.scatter(X2, Y2, marker='p', label='坏瓜', color='deeppink')

    plt.xlabel('密度')
    plt.ylabel('含糖率')
    plt.xlim(0, 0.8)  # 设置x轴范围
    plt.ylim(0, 0.6)  # 设置y轴范围
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.legend(loc='upper left')

    plt.show()

def main():
    dataSet ,label = getWatermelonDataSet()
    #dataSet,label=getUCIDataSet()
    for t in [3, 5, 11]:   # 学习器的数量
        G,H,D= AdaBoost(dataSet, t)
        print('集成学习器(字典):',f"G{t} = {G}")
        print('准确率=',calcAcc(dataSet, G))
        #绘图函数
        plotData(dataSet,G,H,t)
        #plotROC(D,label)
if __name__ == '__main__':
    main()

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器学习】周志华西瓜书第八章集成学习习题8.3--编程实现AdaBoost模型,以不剪枝决策树为基学习器,在西瓜数据集3.0a上训练一个AdaBoost集成,并与教材图8.4进行比较 的相关文章

  • 学习Java的路线

    JavaSE 18 20天 xff09 数据库 xff08 4天 xff09 前端 xff08 7天 xff09 Javaweb xff08 7天 xff09 SSM框架 xff08 9天 xff09 Linux xff08 7天 xff0
  • Java常用类的使用方法小结

    文章目录 前言一 常用类有哪些 xff1f 二 常用类使用方法1 Object类0 xff09 所用的对象1 xff09 getClass方法2 xff09 hasCode方法3 xff09 toString方法4 xff09 equals
  • Java I/O流

    文章目录 前言一 什么是流 xff1f 二 流的分类1 根据流向来分1 xff09 输入流2 xff09 输出流 2 根据单位来分1 xff09 字节流2 xff09 字符流 3 根据功能来分1 xff09 节点流2 xff09 过滤流 三
  • Java 网络编程

    文章目录 前言一 什么是计算机网络 xff1f 二 网络通信的两个重要因素1 通讯双方的地址1 xff09 ip2 xff09 端口号 2 规则 xff1a 网络协议 三 Ip地址1 InetAddress2 Ip的分类1 xff09 ip
  • ScrumMaster的教练职责

    ScrumMaster是Scrum团队的敏捷教练 Ken Rubin说 xff0c 类似于运动团队的教练 xff0c ScrumMaster观察团队使用Scrum的过程 xff0c 帮助团队提高工作绩效 教练不是顾问 xff0c 不提供解决
  • Java多线程

    文章目录 前言一 多线程1 进程 xff0c 线程 xff0c 多线程2 继承Thread类1 xff09 同时下载多个网图通过继承Thread类 3 实现Runnable接口1 xff09 下载多个网图通过实现Runnable接口2 xf
  • MySQL数据库随笔

    提示 xff1a 本文章仅供个人学习使用 xff0c 如有错误请及时私信通知 文章目录 前言一 MySQL的基本操作命令 xff08 1 xff09 连接数据库 xff08 2 xff09 修改用户密码 xff08 3 xff09 刷新权限
  • mybiatis学习笔记

    mybiatis学习笔记参考于尚硅谷mybatis文档 96 提示 xff1a 这如果有错误的地方 xff0c 请联系博主已更正 xff0c 文章目录 mybiatis学习笔记参考于尚硅谷mybatis文档前言一 Mybatits的特性二
  • KVM 介绍及安装

    KVM 安装 KVM KVM 简介 KVM 全称是 Kernel based Virtual Machine 是 Linux 下 x86 硬件平台上的全功能虚拟化解决方案 xff0c 包含一个可加载的内核模块 kvm ko 提供和虚拟化核心
  • 接口(interface)

    目录 一 简介 二 接口的使用 使用interface来定义 在Java中 xff0c 接口和类是两个并列的结构 如何定义接口 xff1a 定义接口中的成员 JDK7以及以前 xff1a 只能定义全局常量和抽象方法 JDK8中 xff1a
  • FileReader && FileWriter && FileInputStream && FileOutputStream

    目录 一 读入数据的基本操作 将day09下的hello txt文件内容读入程序中 xff0c 并输出到控制台 1 步骤 xff1a 2 完整代码 3 异常的处理 xff1a 为了保证流资源一定可以执行关闭操作 xff0c 需要使用try
  • 多表的查询

    目录 一 为什么需要多表查询 xff1f x1f41f 查询一个员工名为 Abel 的人在哪个城市工作 xff1f 二 如何实现多表查询 1 出现笛卡尔积 xff08 交叉连接 xff09 的错误 错误的实现方式 错误的原因 2 多表查询的
  • MySQL数据类型

    目录 一 MySQL中的数据类型 常见数据类型的属性 关于属性 1 创建数据库时指明字符集 2 创建表的时候 xff0c 指明表的字符集 3 创建表 xff0c 指明表中的字段时 xff0c 可以指定字段的字符集 二 整数类型 xff08
  • 批量插入

    目录 一 批量插入数据 JDBC的批量处理语句的方法 二 高效的批量插入 1 举例 xff1a 向goods表中插入20000条数据 goods表的创建 方式一 xff1a 使用Statement 方式二 xff1a 使用PreparedS
  • Gateway新一代网关

    目录 一 概述 1 官网 2 介绍 3 作用 4 微服务架构中网关的位置 5 有Zuul了怎么又出来了gateway 我们为什么选择Gateway xff1f Zuul1 x模型 x1f41f Servlet的生命周期 gateway模型
  • android tensorflow文字识别身份证识别ocr文字识别商用源码

    一 xff0c 文字识别简介 计算机文字识别 xff0c 俗称光学字符识别 xff0c 英文全称是Optical Character Recognition 简称OCR xff0c 它是利用光学技术和计算机技术把印在或写在纸上的文字读取出来
  • idea报错:无法访问org.springframework.web.bind.annotation.RestController和程序包com.sun.org.slf4j.internal不存在

    目录 1 错误具体信息 报错日志 2 原因 3 修改过程 4 程序包com sun org slf4j internal不存在 o 解决 1 错误具体信息 报错日志 INFO INFO maven compiler plugin 3 10
  • Java基础 —— 编程入门

    一 比特 bit 和字节 byte 一个0或者一个1存储为一个比特 bit xff0c 是计算机中最小的存储单位 计算机中是最基本的存储单元是字节 byte 每个字节由8个比特构成 计算机就是一系列的电路开关 每个开关存在两种状态 关 of
  • JDK、JRE、JVM的关系

    参考文章 xff1a 面试官 xff1a JDK JRE JVM 三者什么关系 xff1f 腾讯云开发者社区 腾讯云 tencent com 一 什么是JDK JDK xff1a Java Development Kit的简称 xff0c
  • 问题解决:Mybatis-Plus自增主键超级大!

    1 先瞅瞅是不是自增主键没加注解 xff1f xff08 加了哇 xff0c 没问题哇 xff0c 怎么还那么大呢 xff09 2 奥对 xff0c 看看是不是包导错了 似乎也没问题 再添几条数据试试 xff0c id越来越大 突然想到 x

随机推荐

  • FTP匿名登录

    介绍 从一个服务到另一个服务的目标 凭据可能会丢失在可公开访问的文件夹中的某个位置 xff0c 这将允许我们通过一个远程shell登录 xff0c 该shell不受监控 配置错误的服务可能会泄露信息 xff0c 使我们能够模拟受害者的数字身
  • Unable to start ServletWebServerApplicationContext due to missing ServletWeb解决办法

    当在springboot启动项目的时候报这种错误 xff1a 仔细一看 xff0c 报错原因是因为缺少ServletWebServerFactory的bean 既然是跟Servlet有关 xff0c 那么很可能是在web层面出现了问题 那么
  • 数据库锁概述

    行锁和表锁 主要是针对锁粒度划分的 xff0c 一般分为行锁 表锁 库锁 行锁 xff1a 访问数据库的时候 xff0c 锁定整个行数据 xff0c 防止并发错误 表锁 xff1a 访问数据库的时候 xff0c 锁定整个表数据 xff0c
  • Spring 常用注解

    Spring 常用注解 64 Component xff08 任何层 xff09 64 Controller 64 Service 64 Repository xff08 dao xff09 xff1a 用于实例化对象 64 Autowir
  • MyBatis 传递多个参数的4种方式

    MyBatis 传递多个参数的4种方式 方式1 xff1a 顺序传参 xff08 不推荐 xff09 span class token class name Employee span span class token function s
  • Java中String类的常用方法

    文章目录 Java 中 String 类的常用方法一 String 类的概念二 常用的构造方法三 常用方法1 toString 2 length 3 getBytes 4 toCharArray 5 charAt int index 6 i
  • ASR项目实战-数据

    使用机器学习方法来训练模型 xff0c 使用训练得到的模型来预测语音数据 xff0c 进而得到识别的结果文本 xff0c 这是实现语音识别产品的一般思路 本文着重介绍通用语音识别产品对于数据的诉求 对数据的要求 训练集 相关要求 xff0c
  • 如何写一棵简单的二叉查找树

    二叉查找树 完整代码 xff1a https github com problemin Algorithm blob master src Tree BSTree java 二叉排序树 xff08 Binary Sort Tree xff0
  • Redis常见的数据类型命令

    文章目录 Redis 常见的数据类型及命令一 常见的NoSQL二 Redis 简介三 key 键的一些操作命令四 Redis的五种基本数据结构1 String xff08 字符串 xff09 介绍常用命令1 1 set get1 2 app
  • Redis 的主从复制机制

    文章目录 Redis 的主从复制机制主从复制概述主从复制的作用主从复制环境的搭建主从复制的原理 哨兵模式概述哨兵模式的作用哨兵模式环境的搭建哨兵模式的原理 Cluster 模式 Redis 的主从复制机制 主从复制 概述 主从复制 xff0
  • Nginx 详解

    文章目录 Nginx 详解一 简介二 四大应用场景1 HTTP 服务器2 反向代理3 负载均衡4 动静分离 三 Linux 环境下安装Nginx四 Nginx 服务常用命令五 Nginx 配置文件1 全局块1 1 user1 2 worke
  • RabbitMQ 详解

    文章目录 RabbitMQ 详解一 MQ 简介1 MQ优缺点2 MQ应用场景3 AMQP 和 JMS4 常见的 MQ 产品 二 RabbitMQ 工作原理三 Linux环境安装RabbitMQ1 安装 Erlang2 安装 RabbitMQ
  • AndroidStudio卸载删除干净

    文章目录 前言一 卸载AndroidStudio程序二 删除目录 android三 xff0c 删除AndroidStudio xff0c Sdk目录在这里插入图片描述 这样文件目录就删除干净了 xff0c 接下来的教程是将配置删除 xff
  • 视图绑定ActivityMainBinding

    使用视图绑定 xff0c 可以更轻松的写与视图交互的代码 在模块中启动视图绑定之后 xff0c 系统会为每个模块中的每个XML布局文件生成一个绑定类 绑定类的实例包含对在相应布局中具有ID的所有视图的直接引用 可以代替findViewByI
  • 【FTP服务搭建】使用windows虚拟机搭建ftp服务,并能够使用ftp进行传输文件的操作

    参考了两位大佬写的教程 xff0c 自己实践了一下 xff0c 整理了一下操作步骤 使用机器 xff1a win10虚拟机 win7虚拟机 实验准备 win10下载filezilla下载地址 win10虚拟机关闭防火墙 两台机器可以相互 p
  • 操作系统经典问题——消费者生产者问题

    今日在学习操作系统的过程中遇到了这个问题 xff0c 实在是很苦恼一时间对于这种问题以及老师上课根据这个问题衍生的问题实在是一头雾水 在网络上寻找了一些大佬的讲解之后算是暂时有了点茅塞顿开的感觉 首先第一点什么是生产者 消费者问题 xff1
  • jar包的运行结果和源代码运行结果不一样

    问题 xff1a 我的A模块依赖了B模块 xff0c B模块更新了代码之后 xff0c 把A模块打包成jar包 xff0c 但是运行的时候我的B模块还是我修改之前的样子 报错 原因 xff1a 是因为我的B模块在更新了之后没有把它放到mav
  • Tensorflow数据读取篇之一 ——字节与张量的区别

    前言 字节串 xff08 bytes xff09 类型和张量 xff08 tensor xff09 类型是两种不同的数据类型 xff0c 它们在数据类型 内存分配和计算方式等方面有所不同 一 区别 数据类型 xff1a 字节串是一种特殊的不
  • O3DE社区发布2305.0版本

    O3DE社区发布了23年的第一个版本 xff0c 版本号为2305 0 2305 0版本对应的代码标签 xff0c 见链接 2305 0版本发布说明 xff0c 见链接 直接下载标签2305 0对应的源码 xff0c 命令如下 xff1a
  • 【机器学习】周志华西瓜书第八章集成学习习题8.3--编程实现AdaBoost模型,以不剪枝决策树为基学习器,在西瓜数据集3.0a上训练一个AdaBoost集成,并与教材图8.4进行比较

    xff08 1 xff09 问题理解与分析 编程实现AdaBoost模型 xff0c 不剪枝决策树为基学习器 xff0c 在西瓜数据集3 0a上训练一个AdaBoost集成 xff0c 并与教材图8 4进行比较 xff08 2 xff09