高斯混合模型:GMM和期望最大化算法的理论和代码实现

高斯混合模型(gmm)是将数据表示为高斯(正态)分布的混合的统计模型。这些模型可用于识别数据集中的组,并捕获数据分布的复杂、多模态结构。

gmm可用于各种机器学习应用,包括聚类、密度估计和模式识别。

在本文中,将首先探讨混合模型,重点是高斯混合模型及其基本原理。然后将研究如何使用一种称为期望最大化(EM)的强大技术来估计这些模型的参数,并提供在Python中从头开始实现它。最后将演示如何使用Scikit-Learn库使用GMM执行聚类。

混合模型

混合模型是一种概率模型,用于表示可能来自多个不同来源或类别的数据,每个来源或类别都由单独的概率分布建模。例如,金融回报在正常市场条件下和危机期间的表现通常不同,因此可以将其建模为两种不同分布的混合。

形式上,如果X是随机变量,其分布是K个分量分布的混合,则X的概率密度函数(PDF)或概率质量函数(PMF)可表示为:

P (x)是混合模型的总密度或质量函数。K是混合模型中组分分布的数目。

fₖ(x;θₖ)是第k个分量分布的密度或质量函数,参数化为θₖ。

Wₖ为第k个分量的混合权值,0≤Wₖ≤1,权值之和为1。Wₖ也称为分量k的先验概率。

θₖ表示第k个分量的参数,例如高斯分布中的平均值和标准差。

混合模型假设每个数据点来自K个分量分布中的一个,根据混合权重wₖ选择具体的分布。该模型不需要知道每个数据点属于哪个分布。

高斯混合模型(Gaussian mixture model, GMM)是一种常见的混合模型,其概率密度由高斯分布的混合给出:

X是一个d维向量。

μₖ是第k个高斯分量的平均向量。

Σₖ是第k个高斯分量的协方差矩阵。

N (x;μₖ,Σₖ)为第k个分量的多元正态密度函数:

对于单变量高斯分布,概率密度可以简化为:

μₖ是第k个高斯分量的平均值。

σₖ是第k个高斯分量的协方差矩阵。

N (x;μₖ,σₖ)为第k个分量的单变量正态密度函数:

下面的Python函数绘制了两个单变量高斯分布的混合分布:

 from scipy.stats import norm
 
 def plot_mixture(mean1, std1, mean2, std2, w1, w2):
     # Generate points for the x-axis
     x = np.linspace(-5, 10, 1000)
     
     # Calculate the individual nomral distributions
     normal1 = norm.pdf(x, mean1, std1)
     normal2 = norm.pdf(x, mean2, std2)
     
     # Calculate the mixture
     mixture = w1 * normal1 + w2 * normal2
     
     # Plot the results
     plt.plot(x, normal1, label='Normal distribution 1', linestyle='--')
     plt.plot(x, normal2, label='Normal distribution 2', linestyle='--')
     plt.plot(x, mixture, label='Mixture model', color='black')
     plt.xlabel('$x$')
     plt.ylabel('$p(x)$')
     plt.legend()

我们用这个函数来绘制两个高斯分布的混合物,如果参数为μ₁= -1,σ₁= 1,μ₂= 4,σ₂= 1.5,混合权为w₁= 0.7和w₂= 0.3:

 # Parameters for the two univariate normal distributions
 mean1, std1 = -1, 1
 mean2, std2 = 4, 1.5
 w1, w2 = 0.7, 0.3
 
 plot_mixture(mean1, std1, mean2, std2, w1, w2)

虚线表示单个正态分布,黑色实线表示结果的混合。该图说明了混合模型如何将两个分布组合在一起,每个分布都有自己的平均值、标准差和总体混合结果中的权重。

学习GMM参数

我们学习的目标是找到最能解释观测数据的GMM参数(均值、协方差和混合系数)。为此,需要首先定义给定输入数据的模型的可能性。

对于具有K个分量的GMM,数据集X = {X 1,…,X 1} (n个数据点),似然函数L由每个数据点的概率密度乘积给出,由GMM定义:

其中,θ表示模型的所有参数(均值、方差和混合权重)。

在实际应用中,使用对数似然更容易,因为概率的乘积可能导致大型数据集的数值下溢。对数似然由下式给出:

GMM的参数可以通过对θ最大化对数似然函数来估计。但是我们不能直接应用极大似然估计(MLE)来估计GMM的参数:

对数似然函数是高度非线性的,难于解析最大化。

该模型具有潜在变量(混合权重),这些变量在数据中不能直接观察到。

为了克服这些问题,通常使用期望最大化(EM)算法来解决这个问题

期望最大化(EM)

EM算法是在依赖于未观察到的潜在变量的统计模型中寻找参数的最大似然估计的有力方法。

该算法首先随机初始化模型参数。然后在两个步骤之间迭代:

1、期望步(e步):根据观察到的数据和模型参数的当前估计,计算模型相对于潜在变量分布的期望对数似然。这一步包括对潜在变量的概率进行估计。

2、最大化步骤(m步):更新模型的参数,以最大化观察数据的对数似然,给定e步骤估计的潜在变量。

这两个步骤重复直到收敛,通常由对数似然变化的阈值或迭代的最大次数决定。

在GMMs中,潜在变量表示每个数据点的未知分量隶属度。设Z′为随机变量,表示生成数据点x′的分量。Z′可以取值{1,…,K}中的一个,对应于K个分量。

E-Step

在e步中,我们根据模型参数的当前估计值计算潜在变量Z ^的概率分布。换句话说,我们计算每个高斯分量中每个数据点的隶属度概率。

Z′= k的概率,即x′属于第k个分量,可以用贝叶斯规则计算:

我们用变量γ(z′ₖ)来表示这个概率,可以这样写:

变量γ(z′ₖ)通常被称为responsibilities,因为它们描述了每个分量对每个观测值的responsibilities。这些参数作为关于潜在变量的缺失信息的代理。

关于潜在变量分布的期望对数似然现在可以写成:

函数Q是每个高斯分量下所有数据点的对数似然的加权和,权重就是我们上面说的responsibilities。Q不同于前面显示的对数似然函数l(θ|X)。对数似然l(θ|X)表示整个混合模型下观测数据的似然,没有明确考虑潜在变量,而Q表示观测数据和估计潜在变量分布的期望对数似然。

M-Step

在m步中,更新GMM的参数θ(均值、协方差和混合权值),以便使用e步中计算的最大化期望似然Q(θ)。

参数更新如下:

1、更新每个分量的方法:

第k个分量的新平均值是所有数据点的加权平均值,权重是这些点属于分量k的概率。这个更新公式可以通过最大化期望对数似然函数Q相对于平均值μₖ而得到。

以下是证明步骤,单变量高斯分布的期望对数似然为:

这个函数对μₖ求导并设其为0,得到:

2、更新每个分量的协方差:

也就是说,第k个分量的新协方差是每个数据点与该分量均值的平方偏差的加权平均值,其中权重是分配给该分量的点的概率。

在单变量正态分布的情况下,此更新简化为:

3、更新混合权值

也就是说,第k个分量的新权重是属于该分量的点的总概率,用n个点的个数归一化。

重复这两步保证收敛到似然函数的局部最大值。由于最终达到的最优取决于初始随机参数值,因此通常的做法是使用不同的随机初始化多次运行EM算法,并保留获得最高似然的模型。

Python实现

下面将使用Python实现EM算法,用于从给定数据集估计两个单变量高斯分布的GMM的参数。

首先导入所需的库:

 import numpy as np
 import matplotlib.pyplot as plt
 import seaborn as sns
 
 from scipy.stats import norm
 
 np.random.seed(0)  # for reproducibility

接下来,让我们编写一个函数来初始化GMM的参数:

 def init_params(x):    
     """Initialize the parameters for the GMM
     """    
     # Randomly initialize the means to points from the dataset
     mean1, mean2 = np.random.choice(x, 2, replace=False)
     
     # Initialize the standard deviations to 1
     std1, std2 = 1, 1
     
     # Initialize the mixing weights uniformly
     w1, w2 = 0.5, 0.5
     
     return mean1, mean2, std1, std2, w1, w2

均值从数据集中的随机数据点初始化,标准差设为1,混合权重设为0.5。

e步,计算属于每个高斯分量的每个数据点的概率:

 def e_step(x, mean1, std1, mean2, std2, w1, w2):
     """E-Step: Compute the responsibilities
     """    
     # Compute the densities of the points under the two normal distributions  
     prob1 = norm(mean1, std1).pdf(x) * w1
     prob2 = norm(mean2, std2).pdf(x) * w2
     
     # Normalize the probabilities
     prob_sum = prob1 + prob2 
     prob1 /= prob_sum
     prob2 /= prob_sum
     
     return prob1, prob2

m步,根据e步计算来更新模型参数:

 def m_step(x, prob1, prob2):
     """M-Step: Update the GMM parameters
     """    
     # Update means
     mean1 = np.dot(prob1, x) / np.sum(prob1)
     mean2 = np.dot(prob2, x) / np.sum(prob2)
     
     # Update standard deviations
     std1 = np.sqrt(np.dot(prob1, (x - mean1)**2) / np.sum(prob1))
     std2 = np.sqrt(np.dot(prob2, (x - mean2)**2) / np.sum(prob2))
     
     # Update mixing weights
     w1 = np.sum(prob1) / len(x)
     w2 = 1 - w1
     
     return mean1, std1, mean2, std2, w1, w2

最后编写运行EM算法的主函数,在e步和m步之间迭代指定次数的迭代:

 def gmm_em(x, max_iter=100):
     """Gaussian mixture model estimation using Expectation-Maximization
     """    
     mean1, mean2, std1, std2, w1, w2 = init_params(x)
         
     for i in range(max_iter):
         print(f'Iteration {i}: μ1 = {mean1:.3f}, σ1 = {std1:.3f}, μ2 = {mean2:.3f}, σ2 = {std2:.3f}, ' 
               f'w1 = {w1:.3f}, w2 = {w2:.3f}')
         
         prob1, prob2 = e_step(x, mean1, std1, mean2, std2, w1, w2)
         mean1, std1, mean2, std2, w1, w2 = m_step(x, prob1, prob2)     
         
     return mean1, std1, mean2, std2, w1, w2

为了测试我们的实现,需要将通过从具有预定义参数的已知混合分布中采样数据来创建一个合成数据集。然后将使用EM算法估计分布的参数,并将估计的参数与原始参数进行比较。

首先从两个单变量正态分布的混合物中采样数据:

 def sample_data(mean1, std1, mean2, std2, w1, w2, n_samples):    
     """Sample random data from a mixture of two Gaussian distribution.
     """
     x = np.zeros(n_samples)
     for i in range(n_samples):
         # Choose distribution based on mixing weights
         if np.random.rand() < w1:
             # Sample from the first distribution
             x[i] = np.random.normal(mean1, std1)
         else:
             # Sample from the second distribution
             x[i] = np.random.normal(mean2, std2)
     
     return x

然后使用这个函数从之前定义的混合分布中采样1000个数据点:

 # Parameters for the two univariate normal distributions
 mean1, std1 = -1, 1
 mean2, std2 = 4, 1.5
 w1, w2 = 0.7, 0.3
 
 x = sample_data(mean1, std1, mean2, std2, w1, w2, n_samples=1000)

现在可以在这个数据集上运行EM算法:

 final_dist_params = gmm_em(x, max_iter=30)

得到以下输出:

 Iteration 0: μ1 = -1.311, σ1 = 1.000, μ2 = 0.239, σ2 = 1.000, w1 = 0.500, w2 = 0.500
 Iteration 1: μ1 = -1.442, σ1 = 0.898, μ2 = 2.232, σ2 = 2.521, w1 = 0.427, w2 = 0.573
 Iteration 2: μ1 = -1.306, σ1 = 0.837, μ2 = 2.410, σ2 = 2.577, w1 = 0.470, w2 = 0.530
 Iteration 3: μ1 = -1.254, σ1 = 0.835, μ2 = 2.572, σ2 = 2.559, w1 = 0.499, w2 = 0.501
 ...
 Iteration 27: μ1 = -1.031, σ1 = 1.033, μ2 = 4.180, σ2 = 1.371, w1 = 0.675, w2 = 0.325
 Iteration 28: μ1 = -1.031, σ1 = 1.033, μ2 = 4.181, σ2 = 1.370, w1 = 0.675, w2 = 0.325
 Iteration 29: μ1 = -1.031, σ1 = 1.033, μ2 = 4.181, σ2 = 1.370, w1 = 0.675, w2 = 0.325

该算法收敛到接近原始参数的参数:μ₁= -1.031,σ₁= 1.033,μ₂= 4.181,σ₂= 1.370,混合权值w₁= 0.675,w₂= 0.325。

让我们使用前面编写的plot_mixture()函数来绘制最终分布,绘制采样数据的直方图:

 def plot_mixture(x, mean1, std1, mean2, std2, w1, w2):
     # Plot an histogram of the input data
     sns.histplot(x, bins=20, kde=True, stat='density', linewidth=0.5, color='gray')
     
     # Generate points for the x-axis
     x_ = np.linspace(-5, 10, 1000)
     
     # Calculate the individual nomral distributions
     normal1 = norm.pdf(x_, mean1, std1)
     normal2 = norm.pdf(x_, mean2, std2)
     
     # Calculate the mixture
     mixture = w1 * normal1 + w2 * normal2
     
     # Plot the results
     plt.plot(x_, normal1, label='Normal distribution 1', linestyle='--')
     plt.plot(x_, normal2, label='Normal distribution 2', linestyle='--')
     plt.plot(x_, mixture, label='Mixture model', color='black')
     plt.xlabel('$x$')
     plt.ylabel('$p(x)$')
     plt.legend()
 plot_mixture(x, *final_dist_params)

结果如下图所示:

可以看出,估计的分布与数据点的直方图密切一致。以上是为了我们了解算法进行的Python代码,但是在实际使用的时候还会存在很多问题,所以如果要实际中应用,可以直接使用Sklearn的实现。

Scikit-Learn中的GMM

Scikit-Learn在类sklearn.mixture.GaussianMixture中提供了高斯混合模型的实现。

与Scikit-Learn中的其他聚类算法不同,这个算法不提供labels_属性。因此要获得数据点的聚类分配,需要调用拟合模型上的predict()方法(或调用fit_predict())。

下面使用这个类对以下数据集执行聚类,该数据集由两个椭圆blobs和一个球形blobs组成:

 from sklearn.datasets import make_blobs
 
 X, y = make_blobs(n_samples=500, centers=[(0, 0), (4, 4)], random_state=0)
 
 # Apply a linear transformation to make the blobs elliptical
 transformation = [[0.6, -0.6], [-0.2, 0.8]]
 X = np.dot(X, transformation) 
 
 # Add another spherical blob
 X2, y2 = make_blobs(n_samples=150, centers=[(-2, -2)], cluster_std=0.5, random_state=0)
 X = np.vstack((X, X2))

看看我们的数据

 def plot_data(X):
     sns.scatterplot(x=X[:, 0], y=X[:, 1], edgecolor='k', legend=False)
     plt.xlabel('$x_1$')
     plt.ylabel('$x_2$')
 
 plot_data(X)

接下来,我们用n_components=3实例化GMMclass,并调用它的fit_predict()方法来获取簇分配:

 from sklearn.mixture import GaussianMixture
 
 gmm = GaussianMixture(n_components=3)
 labels = gmm.fit_predict(X)

可以检查EM算法收敛需要多少次迭代:

 print(gmm.n_iter_)
 2

EM算法只需两次迭代即可收敛。检查估计的GMM参数:

 print('Weights:', gmm.weights_)
 print('Means:\n', gmm.means_)
 print('Covariances:\n', gmm.covariances_)

结果如下:

 Weights: [0.23077331 0.38468283 0.38454386]
 Means:
  [[-2.01578902 -1.95662033]
  [-0.03230299  0.03527593]
  [ 1.56421574  0.80307925]]
 Covariances:
  [[[ 0.254315   -0.01588303]
   [-0.01588303  0.24474151]]
 
  [[ 0.41202765 -0.53078979]
   [-0.53078979  0.99966631]]
 
  [[ 0.35577946 -0.48222654]
   [-0.48222654  0.98318187]]]

可以看到,估计的权重非常接近三个blob的原始比例,球形blob的均值和方差非常接近其原始参数。

让我们来绘制聚类的结果:

 def plot_clusters(X, labels):    
     sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=labels, palette='tab10', edgecolor='k', legend=False)
     plt.xlabel('$x_1$')
     plt.ylabel('$x_2$')
 
 plot_clusters(X, labels)

GMM正确地识别了这三个簇。

我们还可以使用predict_proba()方法来获得每个集群中每个数据点的隶属性概率。

 prob = gmm.predict_proba(X)

例如,数据集中的第一个点属于绿色簇的概率非常高:

 print('x =', X[0])
 print('prob =', prob[0])
 #x = [ 2.41692591 -0.07769481]
 #prob = [3.11052582e-21 8.85973054e-10 9.99999999e-01]

可以通过使每个点的大小与它属于它被分配到的集群的概率成比例来可视化这些概率:

位于两个椭圆簇之间的边界上的点具有较低的概率。具有显著低概率密度(例如,低于预定义阈值)的数据点可以被识别为异常或离群值。

我们还可以与其他的聚类方法作比较

可以看到,其他聚类算法不能正确识别椭圆聚类。

模型评价

对数似然是评估GMMs的主要方法。在训练过程中也可以对其进行监控,检查EM算法的收敛性。为了比较具有不同分量数或不同协方差结构的模型。需要两个额外的度量,它们平衡了模型复杂性(参数数量)和拟合优度(由对数似然表示):

1、Akaike Information Criterion (AIC):

P是模型中参数的个数(包括所有的均值、协方差和混合权值)。L是模型的最大似然(模型具有最优参数值的似然)。

AIC值越低,说明模型越好。AIC奖励与数据拟合良好的模型,但也惩罚具有更多参数的模型。

2、Bayesian Information Criterion (BIC):

式中p和L的定义与前文相同,n为数据点个数。

与AIC类似,BIC平衡了模型拟合和复杂性,但对具有更多参数的模型施加了更大的惩罚,因为p乘以log(n)而不是2。

在Scikit-Learn中,可以使用gmm类的aic()和bic()方法来计算这些度量。例如上面的GMM聚类的AIC和BIC值为:

 print(f'AIC = {gmm.aic(X):.3f}')
 print(f'BIC = {gmm.bic(X):.3f}')
 
 #AIC = 4061.318
 #BIC = 4110.565

我们可以通过将不同分量数的GMMs拟合到数据集上,然后选择AIC或BIC值最低的模型,从而找到最优的分量数。

总结

最后我们总结一下gmm与其他聚类算法的优缺点:

优点:

与假设球形簇的k-means不同,由于协方差分量,gmm可以适应椭球形状。这使得gmm能够捕获更多种类的簇形状。

由于使用协方差矩阵和混合系数,可以处理不同大小的聚类,这说明了每个聚类的分布和比例。

gmm提供了属于每个簇的每个点的概率(软分配),这可以在理解数据时提供更多信息。

可以处理重叠的集群,因为它根据概率而不是硬边界为集群分配数据点。

易于解释聚类结果,因为每个聚类都由具有特定参数的高斯分布表示。

除了聚类,GMMs还可以用于密度估计和异常检测。

缺点:

需要提前指定分量(簇)的数量。

假设每个集群中的数据遵循高斯分布,这对于实际数据可能并不总是有效的假设。

当集群只包含少量数据点时,可能不能很好地工作,因为模型依赖于足够的数据来准确估计每个分量的参数。

聚类结果对初始参数的选择很敏感。

在GMMs中使用的EM算法会陷入局部最优,收敛速度较慢。

条件差的协方差矩阵(即接近奇异或条件数非常高的矩阵)会导致EM计算过程中的数值不稳定。

与k-means等简单算法相比,计算量更大,特别是对于大型数据集或分量数量很高的情况下。

https://avoid.overfit.cn/post/fbd97f86b7f84b5aa6ca593bf841a278

作者:Roi Yehoshua

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java Web学习笔记】 1 - HTML入门

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/html 零、网页的组成 HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息&#xff0c;可以包含文字、图片视频等。 CSS样式是表现。就像网页的外衣。比如&#xff0c;标题字体、…

electerm下载和安装

electerm下载和安装 一、概述 electerm 是一款免费开源、基于electron/ssh2/node-pty/xterm/antd/ subx等libs的终端/ssh/sftp客户端(linux, mac, win)。 而且个人觉得electerm界面更好看一些&#xff0c;操作都是类似的。 二、下载安装 下载地址&#xff1a;https://elec…

正则表达式从放弃到入门(1):“正则表达式”是什么?

正则表达式从放弃到入门&#xff08;1&#xff09;&#xff1a;“正则表达式”是什么&#xff1f; 本博文转载自 这是一篇”正则表达式”扫盲贴&#xff0c;如果你还不理解什么是正则表达式&#xff0c;看这篇文章就对了。 如果你已经掌握了”正则表达式”&#xff0c;就不用再…

pip包管理工具

pip 是 Python 包管理工具&#xff0c;该工具提供了对Python包的查找、下载、安装、卸载的功能。 Python 2.7.9 或 Python 3.4 以上版本的python都自带 pip 工具 1. 配置pip国内镜像 pip安装的包都存在于外国的服务器上&#xff0c;速度会非常慢&#xff0c;可以给pip配置国内…

全栈冲刺 之 一天速成MySQL

一、为什么使用数据库 数据储存在哪里&#xff1f; 硬盘、网盘、U盘、光盘、内存&#xff08;临时存储&#xff09; 数据持久化 使用文件来进行存储&#xff0c;数据库也是一种文件&#xff0c;像excel &#xff0c;xml 这些都可以进行数据的存储&#xff0c;但大量数据操作…

arcgis投影栅格不可用

1、使用【投影栅格】工具进行栅格数据投影转换时报错。 解决方法&#xff1a;如果使用的是arcgis10.5及以下的版本&#xff0c;则需要更换更高的版本&#xff0c;因为这个是软件问题&#xff0c;需要更换到arcgis10.6及以上版本&#xff0c;更高级别的版本已经修复了这个问题。…

【题目】链表相关算法题

文章目录 一. 合并两个有序链表题目解析算法原理代码编写 二. 相交链表问题题目解析算法原理代码编写 三. 环形链表问题1. 判断是否有环2. 计算环的长度3. 找到环的入口点 四. 反转链表方法一&#xff1a;边迭代、边逆置方法二&#xff1a;头插 五. 判断链表是否回文题目解析算…

LinkedList详解

LinkedList详解 LinkedList是List接口的一个主要的实现类之一&#xff0c;基于链表的实现。以java8为例来了解一下LinkedList的源码实现 继承关系 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>,…

进制转化总结

来源&#xff0c;做个笔记&#xff0c;讲的还蛮清楚通信原理-2.5 数据封装与传输05_哔哩哔哩_bilibili ip地址范围

6 新建工程——寄存器

文章目录 6.1 本地新建工程文件夹6.2 新建工程6.2.1 选择CPU型号6.2.2 在线添加库文件6.2.3 添加文件6.2.4 复制存储器分配文件6.2.5 配置选项卡6.2.5.1 Linker6.2.5.2 Target6.2.5.3 Output 选项卡6.2.5.4 Listing 选项卡6.2.6 下载器配置 版本说明&#xff1a;MDK5.24 6.1 本…

许战海战略文库|重回大众视野的健力宝如何重生

摘要&#xff1a;销售额连续7年没有增长;产业主品牌定位不清晰;产品不协同缺少产品战略;子品牌无法形成合力新产品共性不足;过度差异化缺少渠道战略;被渠道能力更强的品牌挤压。火遍世界的“东方魔水”从第一品牌到被人遗忘&#xff0c;健力宝该如何重生? 健力宝诞生于1984年&…

css 三栏布局的实现

三栏布局在前端页面设计中是一个常见的布局方式&#xff0c;通常包含左侧、中间和右侧三个部分。这种布局方式在多种场景中都很受欢迎&#xff0c;例如博客、新闻网站和企业官网。本文将详细介绍三栏布局的实现方法&#xff0c;包括用法、代码、深入理解&#xff0c;以及配合高…

Python编程基础:输入/输出函数、注释与缩进

Python是一种简单易学的编程语言&#xff0c;广泛应用于Web开发、数据分析、人工智能等领域。无论您是初学者还是有一定编程经验的人士&#xff0c;都可以从Python的基础知识开始建立自己的编程技能。 目录 理论Python语言的发展程序设计语言的分类静态语言与脚本语言的区别 代…

解决element ui tree组件不产生横向滚动条

结果是这样的 需要在tree的外层&#xff0c;包一个父组件 <div class"tree"><el-tree :data"treeData" show-checkbox default-expand-all></el-tree></div> 在css里面这样写,样式穿透按自己使用的css编译器以及框架要求就好 &l…

笔记:Pika Labs 3D 动画生成工具

Pika Labs 一款3D 动画生成工具 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/134657306 目 录 1. 简介2. 准备2.1 安装 discord2.2 加入 Discord 频道 3. Pika 使用指南2.1 快速开始2.2 从图像到视频2.3 Pika Bot按钮2.4 提示&#xff08;Prompt&a…

WPF Live Charts2 自学笔记

文章目录 前言实现效果微软平台的历史问题 WPF 项目搭建Nuget添加额外框架添加项目初始化livecharts配置其它LiveCharts2 案例简单案例Demo示例ViewViewModel GPU渲染 Github地址仓库 前言 LiveChart 是C# 上面很受欢迎的统计图 UI控件。最近在学WPFhalcon开发&#xff0c;想想…

肖sir__mysql之单表练习题2__(2)

mysql之单表练习题 一.建表语句 create table grade(class int(4),chinese int(8),english int(4),math int(8),name varchar(20),age int(8),sid int(4)primary key auto_increment) DEFAULT charsetutf8; insert into grade(class,chinese,english,math,name,age)values(1833…

在Android上搭建一个NDK项目

首先New Project&#xff0c;选择Native C&#xff0c;点击Next。 填入项目名称和包名&#xff0c;点击Next。 这里我们选择Cmake默认的C版本。 创建好的项目目录&#xff0c;里面比我们正常的Android项目多了一个cpp目录 打开MainActivity。里面定义了一个jni方法stringFromJN…

LLM;超越记忆《第 2 部分 》

一、说明 在这篇博客中&#xff0c;我深入研究了将大型语言模型&#xff08;LLM&#xff09;提升到基本记忆之上的数学框架。我们探索了动态上下文学习、连续空间插值及其生成能力&#xff0c;揭示了 LLM 如何理解、适应和创新超越传统机器学习模型。 LLM代表了人工智能的重大飞…

如何使用 NFTScan NFT API 在 Starknet 网络上开发 Web3 应用

Starknet 是由以色列软件公司 StarkWare 开发的免许可的第 2 层网络。Starknet 作为以太坊上的 ZK Rollup 运行&#xff0c;帮助 dApp 使用 STARK 证明以更低的交易成本实现更大的计算规模。该网络允许智能合约与区块链上部署的其他合约进行交互&#xff0c;从而提高协议之间的…