机器学习——03决策树算法

news2025/1/13 10:11:22

机器学习——03决策树算法

参考资料

  1. AIlearning
  2. Machine-Learning-in-Action
  3. 庞善民.西安交通大学机器学习导论2022春PPT

具体算法的原理步骤请参考本人的另一篇博文:[机器学习导论]—— 第四课——决策树

一、信息熵与信息增益

🔥信息熵

信息熵使信息得以量化

1948年,香农(ClaudeShannon)在他著名的论文“通信的数学原理”中指出:“信息是用来消除随机不确定性的东西”,并提出了“信息熵”的概念(借用了热力学中熵的概念),来解决信息的度量问题。

一条信息的信息量和它的不确定性有着直接的关系

比如,要搞清楚一件非常不确定的事,或是我们一无所知的事情,就需要了解大量信息。相反,如果我们对某件事已经有了较多了解,那么不需要太多信息就能把它搞清楚

信息熵是消除不确定性所需信息量的度量,也即未知事件可能含有的信息量。需要引入消除不确定性的信息量越多,则信息熵越高,反之则越低。

例如“中国男足进军2022年世界杯决赛圈”,这个因为确定性很高,几乎不需要引入信息,因此信息熵很低。

信息熵的计算

Shannon定义的信息熵的计算公式如下:

image-20220317113414164

其中X表示随机变量,随机变量的取值为{𝑥1,𝑥2,…,𝑥𝑛},𝑃(𝑥𝑖)表示事件𝑥𝑖发生的概率,且有 ∑ 𝑃 ( 𝑥 𝑖 ) = 1 \sum𝑃(𝑥𝑖)=1 P(xi)=1信息熵的单位为比特(bit)

熵越小表示概率分布的纯度越高,反之,熵越大表示概率分布的纯度越低。

数据集的信息熵

设数据集D中有m个不同的类C1,C2,C3,…,Cm

设Di是数据集D中Ci类的样本的集合,|D|和|Di|分别是D和Di中的样本个数

数据集D的信息熵
I n f o ( D ) = − ∑ i = 1 m p i log ⁡ 2 p i Info(D)=-\sum^m_{i=1}p_i\log_2p_i Info(D)=i=1mpilog2pi
其中𝑝𝑖是数据集D中任意样本属于类Ci的概率,用 ∣ D i ∣ ∣ D ∣ \frac{|D_i|}{|D|} DDi估计

使用熵衡量数据纯度

假设有一个数据集合D,其中只有两个类,一个是正例类,一个是负例类。计算D中正例类和负例类在三种不同的组分下熵的变化情况。
(1)D中包含有50%的正例和50%的负例。
I n f o ( D ) = − 0.5 ∗ log ⁡ 2 0.5 − 0.5 ∗ log ⁡ 2 0.5 = 1 Info(D) = -0.5 * \log_20.5 - 0.5 * \log_20.5 = 1 Info(D)=0.5log20.50.5log20.5=1
(2)D中包含有20%的正例和80%的负例。
I n f o ( D ) = − 0.2 ∗ log ⁡ 2 0.2 − 0.8 ∗ log ⁡ 2 0.8 = 0.722 Info(D) = -0.2 * \log_20.2 - 0.8 * \log_20.8 = 0.722 Info(D)=0.2log20.20.8log20.8=0.722
(3)D中包含有100%的正例和0%的负例。
I n f o ( D ) = − 1 ∗ log ⁡ 2 1 − 0 ∗ log ⁡ 2 0 = 0 Info(D) = -1 * \log_21 - 0 * \log_20 =0 Info(D)=1log210log20=0
当数据变得越来越“纯”时,熵的值变得越来越小:当D中正反例比例相同时,熵取最大值;当D中所有数据属于一个类时,熵取最小值。因此,熵可以作为数据纯净度的衡量指标。

信息增益

信息增益可以衡量划分数据集前后数据纯度提升程度。信息增益=原数据信息熵−数据划分之后的信息熵

image-20220317113905578

其中,离散属性𝑎有𝐾个可能的取值{𝑎1,𝑎2,…,𝑎𝐾},其中第𝑘个分支节点包含了𝐷中所有在属性𝑎上取值为 𝑎 𝑘 𝑎^𝑘 ak的样本,记为 𝐷 𝑘 𝐷^𝑘 Dk

image-20220317113946167

二、决策树简介

决策树(Decision Tree)是一种基于树结构的分类预测方法

决策树引入

决策树(Decision Tree)又称为判定树,是用于分类的一种树结构。其中每个内部结点(internal node)代表对某个属性的一次测试,叶结点(leaf)代表某个(class)或者类的分布(class distribution),最上面的结点是根结点

决策树提供了一种展示在什么条件下会得到什么类别的方法。

决策树组成

决策树的基本组成部分:根节点、决策结点、分枝和叶子结点。树是由节点和分枝组成的层次数据结构。

image-20220317112744114

决策树是描述分类过程的一种数据结构,从上端的根节点开始,各种分类原则被引用进来,并依这些分类原则将根节点的数据集划分为子集,这一划分过程直到某种约束条件满足而结束。

决策树基本原理

首先对数据进行处理,利用归纳法生成可读的规则和决策树,然后使用决策对新数据进行分析。

本质上决策树是通过一系列规则对数据进行分类的过程。

决策树技术发现数据模式和规则的核心是采用递归分割的贪婪算法

使用 createBranch() 方法,如下所示:

def createBranch():
    检测数据集中的所有数据的分类标签是否相同:
        If so return 类标签
        Else:
            寻找划分数据集的最好特征(划分之后信息熵最小,也就是信息增益最大的特征)
            划分数据集
            创建分支节点
                for 每个划分的子集
                    调用函数 createBranch (创建分支的函数)并增加返回结果到分支节点中
            return 分支节点

决策树基本流程

1️⃣收集待分类的数据,这些数据的所有属性应该是完全标注的。

2️⃣设计分类原则,即数据的哪些属性可以被用来分类,以及如何将该属性量化。

3️⃣分类原则的选择,即在众多分类准则中,每一步选择哪一准则使最终的树更令人满意。

4️⃣设计分类停止条件,实际应用中数据的属性很多,真正有分类意义的属性往往是有限几个,因此在必要的时候应该停止数据集分裂:

该节点包含的数据太少不足以分裂,

继续分裂数据集对树生成的目标(例如ID3中的熵下降准则)没有贡献,

树的深度过大不宜再分。

决策树开发流程

  • 收集数据: 可以使用任何方法。
  • 准备数据: 树构造算法 (下面案例使用的是ID3算法,只适用于标称型数据,这就是为什么数值型数据必须离散化。 还有其他的树构造算法,比如CART) ,详情参考置顶博客。
  • 分析数据: 可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期。
  • 训练算法: 构造树的数据结构。
  • 测试算法: 使用训练好的树计算错误率。
  • 使用算法: 此步骤可以适用于任何监督学习任务,而使用决策树可以更好地理解数据的内在含义。

决策树算法特点

优点: 计算复杂度不高,输出结果易于理解,数据有缺失也能跑,可以处理不相关特征。

缺点: 容易过拟合。 适用数据类型: 数值型和标称型。

标称型:标称型目标变量的结果只在有限目标集中取值,如真与假(标称型目标变量主要用于分类)

数值型:数值型目标变量则可以从无限的数值集合中取值,如0.100,42.001等 (数值型目标变量主要用于回归分析)

三、决策树项目案例——判断鱼类和非鱼类

ID3算法原理

ID3算法在决策树各个节点上使用信息增益准则选择特征(属性)进行数据划分,从而递归地构建决策树。

具体方法

1️⃣从根节点(rootnode)开始,对节点计算所有可能的特征的信息增益,选择信息增益最大的特征作为节点的特征。

2️⃣由该特征的不同取值建立子节点

3️⃣再对子节点递归的调用以上方法,构建决策树,直到所有特征的信息增益均很小或没有特征可以选择为止,最后得到一个决策树。

选择划分属性示例

以买电脑为例进行决策树划分说明

年龄收入学生信用买了电脑
<30一般
<30
30-40一般
>40中等一般
>40一般
>40
30-40
<30一般
<30一般
>40一般
<30
30-40
30-40一般
>40

1️⃣ 确立初始的信息熵

|D|=14,|D1|=5,|D2|=9,即不买的有5个人,买的有9个人

信息熵如下:
I n f o ( D ) = − 5 14 log ⁡ 2 5 14 − 9 14 log ⁡ 2 9 14 = 0.940 Info(D)=-\frac{5}{14}\log_2\frac{5}{14}-\frac{9}{14}\log_2\frac{9}{14}=0.940 Info(D)=145log2145149log2149=0.940

2️⃣ 确立第一次分裂的属性

🍎 如果按照年龄划分

年龄<30的有5个,其中3个为“否”

年龄30-40的有4个,其中0个为“否”

年龄>40的有5个,其中2个为“否”

image-20220321160449588

🍌 如果按照收入划分

收入=高的有4个,其中2个为“否”

收入=中的有6个,其中2个为“否”

收入=低的有4个,其中1个为“否”

image-20220321161051149

🍑 如果按照学生划分

是学生的有7个,其中1个为“否”

不是学生的有7个,其中4个为“否”

image-20220321161817228

🥝 如果按照信用划分

信用好的有6个,其中3个为“否”

信用一般的有8个,其中2个为“否”

image-20220321161851804

综上,“年龄”属性具有最高信息增益,成为分裂属性

3️⃣ 确立第二次分裂的属性

image-20220321162200499

按照上述方法,可以确定第二次分裂的属性为学生

4️⃣ 划分到不可划分为止

ID3算法总结

算法流程

自上而下贪婪搜索

遍历所有的属性,按照信息增益最大的属性进行分裂

根据分裂属性划分样本

重复上述流程,直至满足条件结束

优点

分类过程和领域知识无关,几乎所有模式和场景都可以得到结果

缺点

ID3算法倾向于选择属性值较多的属性,有些时候不能提供有价值的信息

不适用于连续变量

只能用于分类

一次只用一个特征值进行划分

在样本量较小时,可能会导致过度分类

属性值缺失的情况无法处理

项目概述

根据以下 2 个特征,将动物分成两类: 鱼类和非鱼类。

特征:

  1. 不浮出水面是否可以生存
  2. 是否有脚蹼

开发流程

收集数据

不浮出水面是否可以生存?是否有脚蹼?是🐟吗?
YesYesYes
YesYesYes
YesNoNo
NoYesNo
NoYesNo

使用createDataSet()函数输入数据

def createDataSet():
    dataSet = [[1, 1, '是🐟'], [1, 1, '是🐟'], [1, 0, '不是🐟'], [0, 1, '不是🐟'],
               [0, 1, '不是🐟']]
    labels = ['不浮出水面是否可以生存', '是否有脚蹼']
    return dataSet, labels

准备数据

此处,由于我们输入的数据本身就是离散化数据,所以这一步就省略了。

分析数据

使用如下公式计算计算给定数据集的信息熵:
I n f o ( D ) = − ∑ i = 1 m p i log ⁡ 2 p i Info(D)=-\sum^m_{i=1}p_i\log_2p_i Info(D)=i=1mpilog2pi

def calInfoEntropy(dataSet):
    """计算信息熵  
    Args:
        dataSet 数据集
    Returns:
        返回 每一组feature下的某个分类下的信息熵
    """    
    # 统计标签出现的次数
    label_count = Counter(data[-1] for data in dataSet)
    # 计算概率
    probs = [p[1] / len(dataSet) for p in label_count.items()]
    # 计算香农熵
    infoEntropy = sum([-p * log(p, 2) for p in probs])
    return infoEntropy   

按照给定特征划分数据集

def splitDataSet(dataSet, index, value):
    """就是依据index列进行分类,如果index列的数据等于 value的时候,就要将 index 划分到我们创建的新的数据集中
    Args:
        dataSet 数据集                 待划分的数据集
        index 表示每一行的index列        划分数据集的特征
        value 表示index列对应的value值   需要返回的特征的值。
    Returns:
        index列为value的数据集【该数据集需要排除index列】
    """
    retDataSet = []
    for featVec in dataSet:
        # index列为value的数据集【该数据集需要排除index列】
        # 判断index列的值是否为value
        if featVec[index] == value:
            reducedFeatVec = featVec[:index]
            reducedFeatVec.extend(featVec[index+1:])
            # 收集结果值 index列为value的行【该行需要排除index列】
            retDataSet.append(reducedFeatVec)
    return retDataSet

选择最好的数据集划分方式:具有最高信息增益

def chooseBestFeatureToSplit(dataSet):
    """chooseBestFeatureToSplit(选择最好的特征)
    Args:
        dataSet 数据集
    Returns:
        bestFeature 最优的特征列
    """
    # 求特征数
    numFeatures = len(dataSet[0]) - 1
    # 数据集的原始信息熵
    baseEntropy = calInfoEntropy(dataSet)
    # 最优的信息增益值, 和最优的Featurn编号
    bestInfoGain, bestFeature = 0.0, -1
    # 遍历所有的特征
    for i in range(numFeatures):
        # 获取对应的feature下的所有数据
        featList = [example[i] for example in dataSet]
        # 获取剔重后的集合,使用set对list数据进行去重
        uniqueVals = set(featList)
        # 创建一个临时的信息熵
        newEntropy = 0.0
        # 遍历某一列的value集合,计算该列的信息熵
        # 遍历当前特征中的所有唯一属性值,对每个唯一属性值划分一次数据集
        # 计算数据集的新熵值,并对所有唯一特征值得到的熵求和。
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)
            # 计算概率
            prob = len(subDataSet)/float(len(dataSet))
            # 计算信息熵
            newEntropy += prob * calInfoEntropy(subDataSet)。
        infoGain = baseEntropy - newEntropy
        print('infoGain=', infoGain, 'bestFeature=', i, baseEntropy, newEntropy)
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

训练算法

创建树的函数代码如下:

def majorityCnt(classList):
    """majorityCnt(选择出现次数最多的一个结果)
    Args:
        classList label列的集合
    Returns:
        bestFeature 最优的特征列
    """
    major_label = Counter(classList).most_common(1)[0]
    return major_label
    
def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]
    # 如果数据集的最后一列的第一个值出现的次数=整个集合的数量,也就说只有一个类别,就只直接返回结果就行
    # 第一个停止条件: 所有的类标签完全相同,则直接返回该类标签。
    # count() 函数是统计括号中的值在list中出现的次数
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    # 如果数据集只有1列,那么最初出现label次数最多的一类,作为结果
    # 第二个停止条件: 使用完了所有特征,仍然不能将数据集划分成仅包含唯一类别的分组。
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)

    # 选择最优的列,得到最优列对应的label含义
    bestFeat = chooseBestFeatureToSplit(dataSet)
    # 获取label的名称
    bestFeatLabel = labels[bestFeat]
    # 初始化myTree
    myTree = {bestFeatLabel: {}}
    # 注: labels列表是可变对象,在PYTHON函数中作为参数时传址引用,能够被全局修改
    # 所以这行代码导致函数外的同名变量被删除了元素,造成例句无法执行,提示'no surfacing' is not in list
    del(labels[bestFeat])
    # 取出最优列,然后它的branch做分类
    featValues = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        # 求出剩余的标签label
        subLabels = labels[:]
        # 遍历当前选择特征包含的所有属性值,在每个数据集划分上递归调用函数createTree()
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
        # print ('myTree', value, myTree)
    return myTree

算法得出的决策树如下:

image-20221216120351798

测试算法

def classify(inputTree, featLabels, testVec):
    """classify(给输入的节点,进行分类)

    Args:
        inputTree  决策树模型
        featLabels Feature标签对应的名称
        testVec    测试输入的数据
    Returns:
        classLabel 分类的结果值,需要映射label才能知道名称
    """
    # 获取tree的根节点对于的key值
    firstStr = list(inputTree.keys())[0]
    # 通过key得到根节点对应的value
    secondDict = inputTree[firstStr]
    # 判断根节点名称获取根节点在label中的先后顺序,这样就知道输入的testVec怎么开始对照树来做分类
    featIndex = featLabels.index(firstStr)
    # 测试数据,找到根节点对应的label位置,也就知道从输入的数据的第几位来开始分类
    key = testVec[featIndex]
    valueOfFeat = secondDict[key]
    print('+++', firstStr, 'xxx', secondDict, '---', key, '>>>', valueOfFeat)
    # 判断分枝是否结束: 判断valueOfFeat是否是dict类型
    if isinstance(valueOfFeat, dict):
        classLabel = classify(valueOfFeat, featLabels, testVec)
    else:
        classLabel = valueOfFeat
    return classLabel

def fishTest():
    # 1.创建数据和结果标签
    myDat, labels = createDataSet()
    myTree = createTree(myDat, copy.deepcopy(labels))
    # [1, 1]表示要取的分支上的节点位置,对应的结果值
    print(classify(myTree, labels, [1, 1]))

+++ 不浮出水面是否可以生存 xxx {0: '不是🐟', 1: {'是否有脚蹼': {0: '不是🐟', 1: '是🐟'}}} --- 1 >>> {'是否有脚蹼': {0: '不是🐟', 1: '是🐟'}}  
+++ 是否有脚蹼 xxx {0: '不是🐟', 1: '是🐟'} --- 1 >>> 是🐟
是🐟

使用算法:

此步骤可以适用于任何监督学习任务,而使用决策树可以更好地理解数据的内在含义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中小企业OA系统的设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 模块划分&#xff1a;通知类型模块、通知信息模块、部门模块、员工模块、考勤模块、工资模块、奖惩类型、奖惩信息、请假…

USACO开赛!这份参赛指引必看!

美国信息学奥赛USACO 2022 – 2023赛季首场比赛于明日&#xff08;12月16日&#xff09;开始&#xff01;这份参赛指引&#xff0c;一定要认真看噢~ 第一步&#xff1a;打开 USACO 官网&#xff1a;http://www.usaco.org/&#xff0c;点击【注册新账号】&#xff0c;开始注册账…

宽凳科技完成超亿元B1轮融资 率先突破高精地图量产落地

近日&#xff0c;国内领先的高精地图及其智能应用综合解决方案服务商宽凳科技宣布完成B1轮超亿元融资。本轮融资由聚焦于新能源汽车产业链投资及新兴技术产业投资的紫峰资本与信益资本联合领投&#xff0c;崇业投资跟投&#xff0c;同时本轮资本引入了德清政府战略投资&#xf…

WebDAV之葫芦儿·派盘+Xplore

Xplore 支持WebDAV方式连接葫芦儿派盘。 手机文件太多、太乱,本地目录中找不想要的文件,怎么办?推荐使用Xplore将手机中的文件以不同的文件方式罗列出来,并展示给用户。文件管理器以图片、音乐、视频、文档、压缩包及安装包等类型进行分类,使手机中的文件一目了然的分列…

离线地图开发包

相关教程&#xff1a; 1、如何搭建离线地图开发环境 视频教程 2、下载离线地图数据(金字塔瓦片数据&#xff09; 视频教程 3、下载离线地图地形数据库&#xff08;实现地表高低起伏&#xff09; 4、添加离线地图数据到本地服务器 &#xff08;含3D&#xff09; 视频…

【身份证识别】BP神经网络身份证号码识别【含Matlab源码 1344期】

⛄一、身份证号码识别简介&#xff08;附课题作业报告&#xff09; 1 引言 当今是一个信息高度发达的时代&#xff0c;对于每个公民而言身份证那一连串的数字体现了个人信息的唯一性&#xff0c;出于保障公民合法权益和社会治安的考虑&#xff0c;越来越多的行业都开始建立自己…

数据价值深度挖掘,分析服务上线“探索”能力

近日&#xff0c;华为分析服务6.9.0版本发布&#xff0c;正式上线探索能力。开发者可自由定义与配置分析模型&#xff0c;支持报告实时预览&#xff0c;数据洞察体验更加灵活与便捷。 新上线的探索能力中&#xff0c;有漏斗分析、事件归因、会话路径分析三个高级分析模型。在原…

45-Jenkins-Sidebar Link插件实现添加侧边栏

Sidebar Link插件实现添加侧边栏前言安装插件使用插件自由风格项目使用Pipeline项目使用前言 本篇来学习下使用Sidebar Link插件在项目侧边栏添加自定义功能按钮链接 安装插件 Manage Jenkins --> Mangage Plugins --> 可选插件 --> 输出框输入 Sidebar Links 使…

【猿如意】中的『Bluefish』工具详情介绍

目录 一、工具名称 二、下载安装渠道 2.1 什么是猿如意&#xff1f; 2.2 如何下载猿如意&#xff1f; 2.3 如何在猿如意中下载开发工具&#xff1f; 三、Bluefish工具功能简介 四、Bluefish的下载和安装 4.1下载Bluefish 4.2安装Bluefish 五、Bluefish的基本使用 5.1…

Linux学习02-主机管理与磁盘分区

1 Linux与硬件的搭配 实际上&#xff0c;在Linux服务器中&#xff0c;内存的重要性比CPU重要。因为内存不够就会使用到硬盘的内存交换分区。 显卡对于不需要X-Windows的服务器来哦说&#xff0c;是最不重要的一个组件。 各设备在Linux中的文件命名。 在Linux系统中&#xf…

Linux常用调试工具

编译阶段 Linux入门 nm 获取二进制文件包含的符号信息 strings 获取二进制文件包含的字符串常量 strip 去除二进制文件包含的符号 readelf 显示目标文件详细信息 objdump 尽可能反汇编出源代码 addr2line 根据地址查找代码行 运行阶段 gdb 强大的调试工具 ldd 显示程序需…

大咖说|云端即时渲染:下一代互联网的算力基座?

阿里云【大咖说】子系列【计算讲谈社】第十五讲播出&#xff01; 下一代互联网是什么&#xff1f;其算力基座又是什么&#xff1f; 14:00-15:30 全网播出&#xff1a;【计算讲谈社】第十五讲&#xff0c;蔚领时代创始人兼CEO郭建君、蔚领时代数字人事业部总经理费元华、蔚领时…

云工作站这5大新功能不来体验一下吗?

哈喽&#xff0c;大家周五好哇&#xff01;赞奇云工作站又有更新大动作啦&#xff0c;此次更新包括子账号登录设备限制、内客户端控制台视觉优化、新增子账号删除、客户端支持工作区网络的接入方式、桌面名称功能&#xff0c;下面就一起来看看更新的具体内容吧—— 为了提高企业…

直播弹幕系统(四)- 发送弹幕校验登录整合JWT

直播弹幕系统&#xff08;四&#xff09;- 发送弹幕校验登录整合JWT前言一. 整合JWT1.1 改造Socket服务1.2 测试前言 上一篇文章 直播弹幕系统&#xff08;三&#xff09;- 直播在线人数统计 主要讲了利用Redis对一个直播间的在线用户做出统计。那么这篇文章&#xff0c;就要对…

为什么量子力学需要大修? - 易智编译EaseEditing

圣安东尼奥——量子力学是科学的政治两极分化。 选民要么站在一边无休止地争论&#xff0c;要么呆在家里接受政治现状。物理学家要么接受量子力学并进行计算&#xff0c;要么在关于量子力学究竟是如何描述现实的无休止辩论中站队。 史蒂文温伯格(Steven Weinberg)过去对量子力…

Java+MySQL基于SSM的爱心救助车队管理系统的设计与实现 开题 毕业设计

随着我国国民经济的发展和人文素质的不断提高,越来越多的爱心人士出现在了社会的各种角落之中,其中的哥和爱心人士,组织了一种基于交通和车辆之间的互助的民间组织,这种组织叫做雷锋爱心车队,而且雷锋爱心车队已经在我们各大城市相继出现。为了能够帮助车队之间更好的进行管理,…

Linux/macOS 安装 Kaldi

文章目录一、关于 kaldi二、安装1、下载源码2、查看 INSTALL 文件root -- INSTALLtools -- INSTALLsrc -- INSTALL3、处理tools4、处理 src三、测试报错1&#xff1a;Bad FST header报错1&#xff1a;gmm-init-mono: command not found一、关于 kaldi Kaldi is a toolkit for …

OpenMAX——数据格式OMX输入缓冲

开放多媒体加速层&#xff08;英语&#xff1a;Open Media Acceleration&#xff0c;缩写为OpenMAX&#xff09;&#xff0c;一个不需要授权、跨平台的软件抽象层&#xff0c;以C语言实现的软件接口&#xff0c;用来处理多媒体。它是由Khronos Group提出的标准&#xff0c;也由…

[整型/浮点型二分算法详解]二分查找算法真的很简单吗

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;《初识C语言》 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、二分查找是什么二、二分查找…

html大作业【NBA篮球介绍 22个页面】学生网页设计源码

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…