13. 机器学习 - 数据集的处理

文章目录

    • Training data split
    • Normalization
    • Standardized
    • ONE-HOT
    • 补充:SOFTMAX 和 CROSS-ENTROPY

茶桁的AI秘籍  核心基础 13

Hi, 你好。我是茶桁。

上一节课,咱们讲解了『拟合』,了解了什么是过拟合,什么是欠拟合。也说过,如果大家以后在工作中做的就是机器学习的相关事情,那么欠拟合和过拟合就会一直陪伴着你,这两者是相互冲突的。

现在,让我们一起来思考一个问题:overfitting,过拟合产生的原因是什么?

如果这是在模型层面的话,参数过多还是过少?如果从数据层面来看,是过多还是过少呢?

好,我们来揭晓答案。如果模型层面思考,那是就是参数过多。如果从数据层面来看, 那是数据过少。

现在我们需要理解一件事情,这两个事情其实是一回事,数据量多和模型复杂其实是一回事。它背后的原因就是因为任何一个f(x)如果有很多的参数,拟合的时候随着这个参数数量越多,那么我们所需要的训练数据集也要增多。也就是说当模型非常复杂,参数特别多,只要数据量特别大,那就不算多。就说现有的数据量对于参数不够,训练力度不够。

这就好比是有一个天才的孩子,脑子极其聪明,就跟茶桁一样。哎, 这个孩子呢智商极其高,但是他想事情想的特别的复杂,结果他现在见到的事情都是太过于简单的东西。那么就不能把他的这个潜力发挥出来。

好,我们接着下一个问题:如何判断一件事情有没有发生过拟合或者欠拟合呢?

Alt text

我们看这张图,假如这是一个2分类问题,咱们训练时候结果的准确度是0.7左右。那么大家想一下, 这个是过拟合还是欠拟合呢?

如果模型训练的时候效果还不错,快接近于1了,达到了百分之九十几。但是实际上用validation数据集去测的时候发现准确度下到百分之八十几,或者百分之七十几,总之就是比在训练的时候那个效果要差。这个就叫作过拟合。

咱们上节课给大家说的就是这个问题,机器学习的整个流程最终的目的不是为了把loss函数降到最低,我们要关心的是像recall,precition,这种信息才是最关键的。

Training data split

接下来,咱么要再讲几个机器学习里面极其重要的几个概念,第一个是数据集的切分(Training data split)。第二个是Normalization。第三个,Standardized。

其实上节课,咱们已经说过了数据集的切分问题。数据集切分最主要的原因是因为我们经常会遇见过拟合的情况,为了避免我们把所有的数据拿来不断的做training, 然后在使用的时候效果变得不好,那我们不如自己找一些数据出来做test sets,为了可以反复多次的去检验效果好不好,就增加了一个validation sets。

在真实环境下我们是怎么去做这样一件事呢?我们来简单的演示下:

from sklearn.model_selection import train_test_split
import numpy as npsample_data = np.random.random(size(100, 5))train, test = train_test_split(sample_data, train_size=0.8)
train---
array([[1.55582066e-01, 8.19437761e-01, 3.54628257e-02, 5.53248385e-01,4.23785508e-01],
...[7.24889349e-01, 1.23458057e-01, 9.74101303e-01, 1.72605427e-01,6.59164912e-01]])

非常的简单,我们来看,sklearn里自带了这种分割方法。我们随机了100行5列的数据,然后使用train_test_split将其分割成traintest两份,在后面的参数内设置了百分位。

这样,这个数据就做了一个拆分。值得注意的是,给大家教一个小技巧,这是第一种方法:split。其实不只是sklearn, pytorch和keras也都有split方法。

但是我们去看一下源码会发现, 这个split方法是没有validation,它的输出只有train和test两部分。

Alt text

为了解决这个问题,我们可以用一个简单的方法。这次我们使用Numpy。

indices = np.random.choice(range(len(sample_data)), size=int(0.8*(len(sample_data))), replace=True)indices---
array([39, 65,  5, 13, 69,  8, 49,  2, 16, 16, 28, 28, 99, 13, 64, 76, 55,96, 12, 87, 81, 55, 96, 54, 94, 15, 44, 23, 17, 76, 98, 84, 21, 50,62, 58, 21, 95, 22,  3,  6, 35, 93, 34, 68, 49, 29, 81, 58, 45, 95,26, 21, 97, 43, 30, 40, 52, 93, 34, 17, 71, 76, 38, 92, 62, 21, 98,56, 28, 54, 39, 15, 17, 62, 81, 61,  4, 51, 71])

这里我们等于是把它的整体的顺序打乱,后面的replace就是可以重复的去取。这样我们就随机的取了一些下标。

这是一个比较简单的方法, 那么我们为什么要设置replace=True呢?当数量特别大的时候,多取几个少取几个其实不是很影响,另外replace的话,他内部的那个随机的算法其实是不一样的,速度会快的多。以后如果遇到类似的事情,你也可以去用这个方法去做它。

Normalization

除了这个以外, 做机器学习的时候,要做数值的归一化(Normalization)和标准化(Standardized)这样一个动作。

Alt text

我们这么做的目的是什么呢?假设我们现在有多个特征的数据集,不过我们注意到一点,就是这些特征值跨越的范围是无法进行比较的。

比如,一个特征在1和10之间变化,但是另外一个实在1和1000之间变化。如果我们忽略了这一点而直接进行建模,模型分配给这些特征的权重将会受到严重影响,模型最终会为较大的变量分配较高的权重。

现在要解决这个问题,将这些特征置于相同或者至少是可比较的范围内,那就需要对数据做一个数据归一化。

归一化的目标是讲数据缩放到特定范围内,一般来说是[0,1]或者[-1,1]之间。这有助于消除不同特征之间的尺度差异,确保它们对模型的权重贡献大致相等。

数据归一化对于每个特征x,归一化后的值Xnormalized计算如下:

Alt text

其中min是特征的最小值,max是特征的最大值。这个操作确保了数据的最小值映射到0, 最大值映射到1.

在数据预处理过程中,首先计算每个特征的最小值和最大值,然后使用上述公式对数据进行归一化。这通常通过一次遍历数据来实现。

在进行归一化的时候,我们所使用的那个公式会有一个缺点,就是它并不能很好的去处理异常值。比方说,如果有0到40之间的99个值,其中一个值为100, 则这99个值讲全部转换为0到0.4之间的值。这些数据和以前一样被压缩!下图就是个示例:

Alt text

这些数据在进行归一化之后,解决的是y轴上堆集的问题,但是x轴上的问题依然存在,就像途中橙色点那个异常值:

Alt text

关于这个知识点,我们来看一个极其简单的例子:

some_large_number = [23421421,42155151,25531238,21826139, 32189732, 32103721]
def normalize(x):return (x - np.min(x)) / (np.max(x) - np.min(x))
ic(normalize(np.array(some_large_number)))---
array([0.07847317, 1., 0.18225672, 0., 0.50979325, 0.5055623 ])

我手动定义了6个比较大的数字,在进行处理之后我们看到了,都变成了一些特别小的数字。

同样的,对于特别小的数字,它一样可以进行处理:

some_small_number = [0.00000231213,  0.0005600321, 0.0000041412892, 0.000987890576, 0.0000578921764]
ic(normalize(np.array(some_small_number)))--- 
array([0., 0.56588085, 0.00185592, 1., 0.05639333])

Standardized

那么还有就是标准化,对于标准化,其目标是讲数据转化为均值为0, 标准差为1的分布,也就是标准正态分布。这有助于处理偏斜分布的数据,并确保数据的均值和方差在模型中起到合适的作用。

Alt text

那对于每一个特征x,标准化的值z计算如下:

Alt text

μ \mu μ是特征的均值, σ \sigma σ是特征的标准差。这个操作使数据的均值为0,标准差为1。

在数据预处理的过程中,首先计算每个特征的均值和标准差,然后使用上述公式对数据进行标准化处理。标准化后的数据具有均值0和标准差1,这有助于模型更好的理解和捕捉数据之间的关系。

无论是归一化还是标准化,其实依据来源都是基于线性代数的变化理论,这确保了归一化和标准化后的数据分布具有特定的属性,这些属性对于机器学习算法的表现非常有帮助。

我们来看一个标准化的例子,为了让大家更为明显的了解其意义,我做了一些非常大的数据,但是每一个都不相同。这些数据有一个特点,就是相对于数值本身的大小来说,几个数值之间的差距可以说是非常微小的:

some_dense_number = [47238941, 47238946, 47238951, 47238931, 47238949, 47238936]
def standarlize(x):return (x - np.mean(x))/ np.std(x)ic(standarlize(np.array(some_dense_number)))---
array([-0.18752289,  0.51568795,  1.2188988 , -1.59394459,  0.93761446, -0.89073374])

我们定义的数据实际上是非常密集,但是使用standarlize公式之后,就变得比较的分散,比较的均匀了。这个情况还是很多的。

ONE-HOT

在讲完training data split, normalization, Standardized之后,我们来看下面一点: ONE-HOT。

为什么要用ONE-HOT? 我们都直到,咱们计算机里其实都是数字,包括视频,图片,声音,文字等其实都是数字。

数字和数字其实是不一样的。比如,有一群人分成了4组:

Alt text

然后有一个女生的GPA是4:

Alt text

那么分组的4和GPA的4有什么区别?最明显的一个区别就是,分组的4只是一个组名,那么假如和1组交换组名并没有太大的关系,但是GPA的这个4如何和1交换一下,那就从4分变成1分了,那这两个是不能相互变换的。本质上,其区别就是一个可比一个不可比。

我们也就发现了,数字其实是有区别的。这个世界中,数字其实可以分成两类:

第一类叫作Categorical,叫作分类数据,也被称为离散数据或名义数据。它们之间不能被比较,也不能被排序,这些数字也仅仅是表示一个和另外一个不一样。就我们刚才讲人群分为1、2、3、4组,其实分成A、B、C、D组也是一样的,只是表示区别。

Alt text

第二类是Numerical,数值数据,也被称为连续数据。这个是可以比较的,也可以进行排序。这种数据包括可以用来进行数学运算的实数值。

Alt text

Numerical还可以进一步分为整数和浮点数。

知道了这一点之后,那我们以后遇到类似的情况不要随便的做加减乘除。

那我们有了Categorical和Numerical这两种类型之后,会对我们有一些什么比较重要的影响?

如果现在有一个函数,这个函数输入一个x向量,它输出就是分为一个Categorical和numerical。

输出是0-1这样一个数字,是一个典型的逻辑回归。

假如有一个人在北京,年龄27,性别男,月入一万二。然后还有一个人,生活在安徽,年龄28,性别女,月入8,000。第三个住在上海,年龄28,性别男,月入一万三。

  1. 北京, 27, 12000
  2. 安徽, 28, 8000
  3. 上海, 28, 13000

我们注意这三组数据,如果现在做一个向量表证。

关于地域,我们常常使用的方法包括邮编排序,或者使用拼音排序。假如这里我们就使用拼音首字母来进行排序,安徽假如是1, 北京是2, 上海是27。

我们的数据进行向量化可能就会变成下面这样:

# 1. 北京
vec(2, 27, 12000)
# 2. 安徽
vec(1, 28, 8000)
# 3. 上海
vec(27, 28, 13000)

然后我们定义一个函数:

def f(x):return (0, 1)

非常简单一个函数,返回表示对某一样东西买还是不买。

函数的实现过程就是类似于wi * xi + b这种形式。

我们观察向量发现,就向量值而言,北京这个人和安徽这个人之间的向量差比北京和上海这两人之间的向量差还要小。

∣ v 1 − v 2 ∣ < ∣ v 1 − v 3 ∣ |v_1 - v_2| < |v_1 - v_3| v1v2<v1v3

我们假如说经过函数f(x)之后,输出的结果分别为Y1, Y2, Y3。因为v1和v2离的更近,就会有一个结果,Y1和Y2的结果其实会更相似。但是其实呢,这种结果完全不对。这样乱比其实会出问题,会让程序出错。

我们现在知道,这其实是一个Categorical的问题。为了解决Categorical的这种问题,我把Categorical改成这样:

北京: [1, 0, 0]
安徽: [0, 1, 0]
上海: [0, 0, 1]

改成这样之后这个向量就变成了这样:

# 1. 北京
vec(1, 0, 0, 27, 12000)
# 2. 安徽
vec(0, 1, 0, 28, 8000)
# 3. 上海
vec(0, 0, 1, 28, 13000)

向量变成这样之后,就解决了我们刚刚说的那个问题。不会导致因为分类过于相似让北京和安徽向量相似度大于北京和上海的相似度。

对于这样一个向量,三组数据中改变的那个值向量值就都为 2 \sqrt 2 2 ,这一种方式就被称为ONE-HOT。

那这种方式也是存在问题的,目前我们只去考虑三个城市。可是当存在成百上千个城市的时候,比如说Google地图等等这些应用。

Alt text

当城市越来越多的时候,那它的维度就会变得很高:

Beijing     = [1, 0, 0, 0, 0, 0, ..., 0]
Shanghai    = [0, 1, 0, 0, 0, 0, ..., 0]
Chengdu     = [0, 0, 1, 0, 0, 0, ..., 0]
Shenzhen    = [0, 0, 0, 1, 0, 0, ..., 0]
...

我们想想一下,这样得有多少个地址?可能空间会极其的大,你这样的话数字光存起来得上亿个存储单元。

ONE-HOT就有这样的问题:

  1. 耗费空间
  2. 数据量大,更新起来,效率极低
  3. 遗漏了很多重要新息

就比如,我们再增加几个人如下:

- 重庆 27 9000
- 成都 26 8500
- 呼和浩特 26 8500

在这三个城市中,我们脑子里其实就直到,重庆和成都是非常接近的。但是在ONE-HOT里是体现不出来,其向量值依然是根号2。

为了解决这些问题,人们就用到了更先进的一种方法:embedding,
叫作嵌入。

嵌入就是把东西放在固定的位置,这个就是嵌入的意思。在这里,就我们空间中如果有几个实体NTT1 NTT2 NTT3,我们把这些实体放到这个空间中,要达到一个结果就是如果实体1和实体2的相似度小于实体1和实体3的相似度,这个相似度我们可以自己来定义,比如成都和重庆的生活方式,再比如重庆和北京都是直辖市。

在这个问题场景下,我们期望达到的结果是如果这两个实体相似那么他们在空间中的距离也接近。

如何实现Embedding, 这本身是一个研究领域, 是现在非监督学习,表证学习里面非常重要的一个研究领域,属于比较高级的一个知识点。

第二就是如果之后咱们学NLP,那么一定会讲到这个,因为要把文本单词进行嵌入,到时候会学到。如果是学推荐系统的,大家也会学什么Graph embedding,基于图的用户行为。

那之后咱们学习NLP,其基础就是Embedding。关于这个问题,我们其实目前了解到这里就行了。再往下延展下去,又是一个专门的研究话题。延展后的这个问题解决方案,在我们后面的课程中会等着大家去学习。

我们再来看看ONE-HOT的实际展示:

array = ['北京','上海','广州','宁夏','成都','上海','北京']def one_hot(elements):pure = list(set(elements))vectors = []for i in elements:vec = [0] * len(pure)vec[pure.index(i)] = 1vectors.append(vec)return vectors
ic(one_hot(array))---
one_hot(array): [[0, 0, 0, 1, 0],[0, 0, 0, 0, 1],[0, 0, 1, 0, 0],[1, 0, 0, 0, 0],[0, 1, 0, 0, 0],[0, 0, 0, 0, 1],[0, 0, 0, 1, 0]]

其实ONE-HOT非常简单,但是基本上很多面试官都喜欢问这个问题。这个问题主要就是一个可以考察一下你的Python编程能力,其次他可以去问一下你one hot的作用是什么,再者还可以往后问你one hot有什么缺点,怎么解决等等。一个问题就可以问你半个小时。

补充:SOFTMAX 和 CROSS-ENTROPY

好,在本节课最后,我们来做一个前面课程的补充,在今天才想起来,有一个相关的点遗漏了没有讲到。

之前我们讲过逻辑回归的loss函数:

假如y=1, loss可以等于-log(yhat), 如果y等于0, loss就可以写成-log(1-yhat)。两个合并后就组成了最终的loss函数:

l o s s = − ( y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ) loss = -(ylog\hat y + (1-y)log(1- \hat y)) loss=(ylogy^+(1y)log(1y^))

那么,这个是解决二分类的,结果才不是0就是1。现在的问题就是如果我们要解决多分类的问题怎么办。

如果要解决多分类的话,需要把x变成一种能预测多分类的东西。那最终yhat可以表示成 y ^ = ( 0.25 , 0.20 , 0.75 ) \hat y = (0.25, 0.20, 0.75) y^=(0.25,0.20,0.75)

也就是,现在要表示三个类别,那我们可以用三个小数来表示。这个向量经过各种计算,如果能够变成一个三维的向量,然后再去优化里边的参数就可以做到。

那这也就代表的是类别1、类别2、类别3的概率。ytrue就可以写成yhat的形式,就变成(1, 0, 0)。

就是我们给定一个 x ⃗ \vec x x , 它实际的y是(1, 0, 0), 那么yhat就是估计值等于0.25、0.20和0.75。然后对比一下两组数据之间的差别,这样我们就可以优化其中的形成参数(w, b)。

通过不断优化, 就可以计算到更接近于(1, 0, 0)这样的值。

首先就是怎么样把x向量变成3维的。

这个其实不难,如果x是10维的,110。那么给他再乘以一个
10
3的矩阵,它最后就会变成一个1行乘3列的矩阵。

那么现在假如说现在有这样一个x:

x = [1231, 12314, 4341, 1542, 4123, 4512, 3213, 1241, 1231, 6842]

然后我们来做这样一件事:

x = np.array(normalize(x))
weights = np.random.random(size=(10, 3))
np.dot(x, weights)---
array([0.86907231, 1.32234548, 0.88170994])

这样,我们就生成了一个维度是3的一串数字。在机器学习里面,我们把这个叫做算子:logits。

现在我们将一个10维的x变成了一个3维的logit,下一步我们就要考虑,怎么将这个logit变成一个概率分布呢?

我们就要用到一个和逻辑函数特别像的一个函数,Softmax:

Alt text

我把它写出来:

logits = np.dot(x, weights)def softmax(x):return np.exp(x) / np.sum(np.exp(x))ic(softmax(logits))---
array([0.27884889, 0.43875588, 0.28239524])

这样,我们输入的是logits,输入到Softmax,输出的就是概率了。

输出成概率之后,我们定义一个依然和逻辑函数很像的一个函数,叫做Cross-entropy。

我们刚才使用softmax输出的数组就是概率,也就是估算的yhat。这个Cross-entropy的loss就是:

Alt text

求得loss,然后再对x求偏导,就可以通过梯度下降让输入的x得到和真正的y相近的yhat。

那我们将cross-entropy也写一下:

def cross_entropy(yhat, y):return -np.sum(y_i * np.log(yhat_i) for y_i, yhat_i in zip(y, yhat))

现在我们需要一组真正的y,也就是真实值,和我们预测房价时所使用的真实值是一样的东西,只是现在我们的y的维度不太一样:

y = [0, 1, 0]

接着我们使用cross_entropy将我们之前使用softmax计算的概率分布和真实的y放进去:

ic(cross_entropy(softmax(logits),y))---
1.040664959870481

这个时候我们就得到了一个loss值。

我们现在去给weights求偏导。然后通过不断的迭代,就能找到一组wi, 和x进行点乘就能够生成和y接近的值。

以上这些就是softmax和cross-entropy的作用。

cross-centropy就是用来衡量产生的yhat和y之间的相似程度差距的。 Softmax是把任意的一组数字变成概率分布,然后这个概率分布就可以送到loss函数里面和实际上的y进行对比。

Softmax有这么几个特性,它的结果是一个典型的概率分布。还有就是Softmax中有e的n次方,可以把Max变得更大。除了把Max变得更大,还保留原来小的数字。

理论上完全可以找别的函数代替,计算机里边很多东西,只要好用就行。这就是放大特征,正是面对多分类任务的一个做法。

Softmax在实现的时候有个坑稍微要注意一下,在实现的时候我们多加一句:

def softmax(x):x = np.array(x)x -= np.max(x) # 多加这么两句return np.exp(x) / np.sum(np.exp(x))ic(softmax(logits))

首先,如果x的输入是一个array就不用管了,但是如果不是,我们就要强制转换一下。

下一句代码是因为e的x次方可能非常的大,但是我们计算机的存储是有限的,最大只能表示2^63的数字,再大就表示不了了。所以我们就需要这样一段代码来处理一下,让最后结果的数字不要那么大。

好,那这一节课的内容到这里也就结束了。

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

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

相关文章

SK海力士:将成为引领人工智能时代的定制型半导体存储器公司

AI芯片是一种专门针对人工智能应用设计的芯片&#xff0c;能够高效地处理人工智能任务&#xff0c;如机器学习、深度学习等。AI芯片具有高运算速度、低功耗、便于集成等特点&#xff0c;是人工智能领域的重要发展方向之一。 目前&#xff0c;AI芯片主要分为GPU、FPGA和ASIC三种…

Spark On Hive原理和配置

目录 一、Spark On Hive原理 &#xff08;1&#xff09;为什么要让Spark On Hive&#xff1f; 二、MySQL安装配置&#xff08;root用户&#xff09; &#xff08;1&#xff09;安装MySQL &#xff08;2&#xff09;启动MySQL设置开机启动 &#xff08;3&#xff09;修改MySQL…

Spring Boot进阶(94):从入门到精通:Spring Boot和Prometheus监控系统的完美结合

&#x1f4e3;前言 随着云原生技术的发展&#xff0c;监控和度量也成为了不可或缺的一部分。Prometheus 是一款最近比较流行的开源时间序列数据库&#xff0c;同时也是一种监控方案。它具有极其灵活的查询语言、自身的数据采集和存储机制以及易于集成的特点。而 Spring Boot 是…

Android-宝宝相册(第四次作业)

第四次作业-宝宝相册 题目 用Listview建立宝宝相册&#xff0c;相册内容及图片可自行设定&#xff0c;也可在资料文件中获取。给出模拟器仿真界面及代码截图。 &#xff08;参考例4-8&#xff09; 创建工程项目 创建名为baby的项目工程&#xff0c;最后的工程目录结构如下图所…

报错:SSL routines:ssl3_get_record:wrong version number

一、问题描述 前后端联调的时候&#xff0c;连接后端本地服务器&#xff0c;接口一直pending调不通&#xff0c;控制台还报以下错误&#xff1a; 立马随手搜索了一下解决方案&#xff0c;但是emmm&#xff0c;不符合前端的实际情况&#xff1a; 二、解决方法&#xff1a; 实际…

SpringCore完整学习教程5,入门级别

本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库。 6.1. Jackson 为Jackson提供了自动配置&#xff0c;Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时&#xff0c;将自动配置Obj…

理解V3中的proxy和reflect

现有如下面试题 结合GeexCode和Gpt // 这个函数名为onWatch&#xff0c;接受三个参数obj、setBind和getlogger。 // obj是需要进行监视的对象。 // setBind是一个回调函数&#xff0c;用于在设置属性时进行绑定操作。 // getlogger是一个回调函数&#xff0c;用于在获取属性时…

【阅读和学习代码】VoxelNet

文章目录 将点特征 转换为 voxel 特征稀疏张量 到 稠密张量&#xff0c;反向索引参考博客 将点特征 转换为 voxel 特征 https://github.com/skyhehe123/VoxelNet-pytorch/blob/master/data/kitti.py 【Python】np.unique() 介绍与使用 self.T &#xff1a; # maxiumum numbe…

php简单后门实现及php连接数据库

php简单后门实现 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>easybackdoor</title>…

云服务器搭建Spark集群

文章目录 1. Local 模式1.1 安装local模式1.2 命令行工具1.3 提交本地应用 2. Standlone模式2.1 集群配置2.2 修改配置文件2.3 启动集群与停止集群2.4 提交应用到集群环境2.5 提交应用的参数详细说明2.6 配置历史服务2.7 配置高可用&#xff08;HA&#xff09; 3. Yarn模式&…

如何使用ffmpeg制作透明背景的视频

最近我们尝试在网页上叠加数字人讲解的功能&#xff0c;发现如果直接在网页上放一个矩形的数字人视频&#xff0c;效果会很差&#xff0c;首先是会遮挡很多画面的内容&#xff0c;其次就是不管使用任何任务背景&#xff0c;画面都和后面的网页不是很协调&#xff0c;如图所示&a…

提升技能,挑战自我——一站式在线题库小程序

在这个信息爆炸的时代&#xff0c;我们总是在寻找一种方式&#xff0c;让自己在众多的知识海洋中快速提升技能&#xff0c;挑战自我。今天&#xff0c;我要向大家推荐一款全新的在线题库小程序KD蝌蚪阿坤&#xff0c;它将帮助你实现这个目标。 KD蝌蚪阿坤是一款全面的在线题库…

5 个编写高效 Makefile 文件的最佳实践

在软件开发过程中&#xff0c;Makefile是一个非常重要的工具&#xff0c;它可以帮助我们自动化构建、编译、测试和部署。然而&#xff0c;编写高效的Makefile文件并不是一件容易的事情。在本文中&#xff0c;我们将讨论如何编写高效的Makefile文件&#xff0c;以提高我们的开发…

Python---练习:有一物,不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?

案例&#xff1a; 有一物&#xff0c;不知其数&#xff0c;三三数之余二&#xff0c;五五数之余三&#xff0c;七七数之余二&#xff0c;问物几何&#xff1f; 人话&#xff1a; 有一个数字&#xff0c;不知道具体是多少&#xff0c;用3去除剩2&#xff0c;用5去除剩3&#…

Linux中shell脚本中的变量

目录 一、变量的定义 二、shell脚本中变量的定义方法 1、变量名称 2、环境级别 3、用户级别 4、系统级别 5、删除设定的变量 三、变量的转译 1、转译 2、声明 3、变量的数组 四、Linux中命令的别名设定 五、用户环境变量的更改 脚本中的传参 1、非交互模式 2…

android studio启动Task配置

Android studio 高版本默认不开启Task配置&#xff0c;需要自己手动开启 1.低版本配置路径&#xff1a;&#xff08;复制他人图片&#xff09; 2.高版本路径&#xff1a;添加下图勾选配置即可 3.gradle task 3.1 初识task gradle中所有的构建工作都是由task完成的,它帮我们处…

Anaconda下载和安装

1.概述 1&#xff09;包含conda&#xff1a;conda是一个环境管理器&#xff0c;其功能依靠conda包来实现&#xff0c;该环境管理器与pip类似。 2&#xff09;安装大量工具包&#xff1a;Anaconda会自动安装一个基本的python&#xff0c;该python的版本Anaconda的版本有关。该…

2023年清洁电器行业数据分析:洗地机市场规模持续倍增,进入赛点

洗地机作为清洁电器领域的明星品类&#xff0c;正在成为继扫地机器人之后拉动清洁电器市场大盘的又一核心动力。 在清洁电器领域&#xff0c;扫地机器人、洗地机和吸尘器是三大热门品类。截至今年9月份&#xff0c;根据鲸参谋平台的数据显示&#xff0c;吸尘器的规模继续大幅下…

嵌入式 Tomcat 调校

SpringBoot 嵌入了 Web 容器如 Tomcat/Jetty/Undertow&#xff0c;——这是怎么做到的&#xff1f;我们以 Tomcat 为例子&#xff0c;尝试调用嵌入式 Tomcat。 调用嵌入式 Tomcat&#xff0c;如果按照默认去启动&#xff0c;一个 main 函数就可以了。 简单的例子 下面是启动…

系列十八、请描述下bean的生命周期

一、概述 bean的生命周期是指bean从创建到销毁的整个过程。 二、生命周期 bean的生命周期是指bean从创建到销毁的整个过程&#xff0c;大致可以分为如下四个过程&#xff1a; 2.1、实例化 实例化可以通过如下几种方式完成&#xff1a;&#xff08;参考系列十五&#xff09…