第9章 EM算法:例题及课后习题

1 概要

1.EM算法是含有隐变量的概率模型极大似然估计或极大后验概率估计的迭代算法。含有隐变量的概率模型的数据表示为 P ( Y , Z ∣ θ ) P(Y,Z|\theta) P(Y,Zθ)。这里, Y Y Y是观测变量的数据, Z Z Z是隐变量的数据, θ \theta θ 是模型参数。EM算法通过迭代求解观测数据的对数似然函数 L ( θ ) = log ⁡ P ( Y ∣ θ ) {L}(\theta)=\log {P}(\mathrm{Y} | \theta) L(θ)=logP(Yθ)的极大化,实现极大似然估计。每次迭代包括两步:

E E E步,求期望,即求 l o g P ( Y , Z ∣ Y , θ ) logP\left(Y,Z | Y, \theta\right) logP(Y,ZY,θ) )关于 P ( Z ∣ Y , θ ( i ) ) P\left(Z | Y, \theta^{(i)}\right) P(ZY,θ(i)))的期望:

Q ( θ , θ ( i ) ) = ∑ Z log ⁡ P ( Y , Z ∣ θ ) P ( Z ∣ Y , θ ( i ) ) Q\left(\theta, \theta^{(i)}\right)=\sum_{Z} \log P(Y, Z | \theta) P\left(Z | Y, \theta^{(i)}\right) Q(θ,θ(i))=ZlogP(Y,Zθ)P(ZY,θ(i))
称为 Q Q Q函数,这里 θ ( i ) \theta^{(i)} θ(i)是参数的现估计值;

M M M步,求极大,即极大化 Q Q Q函数得到参数的新估计值:

θ ( i + 1 ) = arg ⁡ max ⁡ θ Q ( θ , θ ( i ) ) \theta^{(i+1)}=\arg \max _{\theta} Q\left(\theta, \theta^{(i)}\right) θ(i+1)=argθmaxQ(θ,θ(i))

在构建具体的EM算法时,重要的是定义 Q Q Q函数。每次迭代中,EM算法通过极大化 Q Q Q函数来增大对数似然函数 L ( θ ) {L}(\theta) L(θ)

2.EM算法在每次迭代后均提高观测数据的似然函数值,即

P ( Y ∣ θ ( i + 1 ) ) ⩾ P ( Y ∣ θ ( i ) ) P\left(Y | \theta^{(i+1)}\right) \geqslant P\left(Y | \theta^{(i)}\right) P(Yθ(i+1))P(Yθ(i))

在一般条件下EM算法是收敛的,但不能保证收敛到全局最优。

3.EM算法应用极其广泛,主要应用于含有隐变量的概率模型的学习。高斯混合模型的参数估计是EM算法的一个重要应用,下一章将要介绍的隐马尔可夫模型的非监督学习也是EM算法的一个重要应用。

4.EM算法还可以解释为 F F F函数的极大-极大算法。EM算法有许多变形,如GEM算法。GEM算法的特点是每次迭代增加 F F F函数值(并不一定是极大化 F F F函数),从而增加似然函数值。

关于EM算法的数学推导可以见文章:EM算法数学推导

2 书中例题

在这里插入图片描述

观测数据的似然函数: P ( Y ∣ θ ) = ∏ j = 1 n [ π p y j ( 1 − p ) 1 − y j + ( 1 − π ) q y j ( 1 − q ) 1 − y j ] P(Y|\theta) = \prod_{j=1}^{n}[\pi p^{y_j}(1-p)^{1-y_j}+(1-\pi) q^{y_j}(1-q)^{1-y_j}] P(Yθ)=j=1n[πpyj(1p)1yj+(1π)qyj(1q)1yj]

E step:计算在模型参数 π ( i ) , p ( i ) , q ( i ) \pi^{(i)},p^{(i)},q^{(i)} π(i)p(i)q(i)下观测数据 y j y_j yj来自掷硬币B的概率。

μ j ( i + 1 ) = π ( i ) ( p ( i ) ) y j ( 1 − ( p ( i ) ) 1 − y j π ( i ) ( p ( i ) ) y j ( 1 − ( p ( i ) ) 1 − y j + ( 1 − π ( i ) ) ( q ( i ) ) y j ( 1 − q ( i ) ) 1 − y j \mu^{(i+1)}_j=\frac{\pi^{(i)} (p^{(i)})^{y_j}(1-(p^{(i)})^{1-y_j}}{\pi^{(i)} (p^{(i)})^{y_j}(1-(p^{(i)})^{1-y_j}+(1-\pi^{(i)}) (q^{(i)})^{y_j}(1-q^{(i)})^{1-y_j}} μj(i+1)=π(i)(p(i))yj(1(p(i))1yj+(1π(i))(q(i))yj(1q(i))1yjπ(i)(p(i))yj(1(p(i))1yj

M step:计算模型参数的新估计值。

π ( i + 1 ) = 1 n ∑ j = 1 n μ j ( i + 1 ) \pi^{(i+1)}=\frac{1}{n}\sum_{j=1}^n\mu^{(i+1)}_j π(i+1)=n1j=1nμj(i+1)

p ( i + 1 ) = ∑ j = 1 n μ j ( i + 1 ) y j ∑ j = 1 n μ j ( i + 1 ) p^{(i+1)}=\frac{\sum_{j=1}^n\mu^{(i+1)}_jy_j}{\sum_{j=1}^n\mu^{(i+1)}_j} p(i+1)=j=1nμj(i+1)j=1nμj(i+1)yj

q ( i + 1 ) = ∑ j = 1 n ( 1 − μ j ( i + 1 ) ) y j ∑ j = 1 n ( 1 − μ j ( i + 1 ) ) q^{(i+1)}=\frac{\sum_{j=1}^n(1-\mu^{(i+1)}_j)y_j}{\sum_{j=1}^n(1-\mu^{(i+1)}_j)} q(i+1)=j=1n(1μj(i+1))j=1n(1μj(i+1))yj

import mathclass EM:def __init__(self, prob):self.pro_A, self.pro_B, self.pro_C = prob# e_stepdef pmf(self, i):pro_1 = self.pro_A * math.pow(self.pro_B, data[i]) * math.pow((1 - self.pro_B), 1 - data[i])pro_2 = (1 - self.pro_A) * math.pow(self.pro_C, data[i]) * math.pow((1 - self.pro_C), 1 - data[i])return pro_1 / (pro_1 + pro_2)# m_stepdef fit(self, data):count = len(data)print('init prob:{}, {}, {}'.format(self.pro_A, self.pro_B,self.pro_C))for d in range(count):_ = yield_pmf = [self.pmf(k) for k in range(count)]pro_A = 1 / count * sum(_pmf)pro_B = sum([_pmf[k] * data[k] for k in range(count)]) / sum([_pmf[k] for k in range(count)])pro_C = sum([(1 - _pmf[k]) * data[k]for k in range(count)]) / sum([(1 - _pmf[k])for k in range(count)])print('{}/{}  pro_a:{:.3f}, pro_b:{:.3f}, pro_c:{:.3f}'.format(d + 1, count, pro_A, pro_B, pro_C))self.pro_A = pro_Aself.pro_B = pro_Bself.pro_C = pro_C
data = [1, 1, 0, 1, 0, 0, 1, 0, 1, 1]
em = EM(prob=[0.5, 0.5, 0.5]) # 初值都设置为0.5
f = em.fit(data)
next(f) # 开始生成器
init prob:0.5, 0.5, 0.5
# 第一次迭代
f.send(1)
1/10  pro_a:0.500, pro_b:0.600, pro_c:0.600
# 第二次
f.send(2)
2/10  pro_a:0.500, pro_b:0.600, pro_c:0.600
em = EM(prob=[0.4, 0.6, 0.7])  # 换另一些初值
f2 = em.fit(data)
next(f2)
init prob:0.4, 0.6, 0.7
f2.send(1)
1/10  pro_a:0.406, pro_b:0.537, pro_c:0.643
f2.send(2)
2/10  pro_a:0.406, pro_b:0.537, pro_c:0.643

3 高斯混合模型(GMM)

高斯混合模型是一种概率模型,用于表示具有多个高斯分布成分的数据集。假设有一个由 K K K 个高斯分布组成的混合模型,其概率密度函数可以表示为:

p ( x ) = ∑ k = 1 K π k N ( x ∣ μ k , Σ k ) p(x) = \sum_{k=1}^K \pi_k \mathcal{N}(x \mid \mu_k, \Sigma_k) p(x)=k=1KπkN(xμk,Σk)

其中:

  • π k \pi_k πk 是第 k k k 个高斯成分的权重,满足 ∑ k = 1 K π k = 1 \sum_{k=1}^K \pi_k = 1 k=1Kπk=1 π k ≥ 0 \pi_k \geq 0 πk0
  • N ( x ∣ μ k , Σ k ) \mathcal{N}(x \mid \mu_k, \Sigma_k) N(xμk,Σk) 是均值为 μ k \mu_k μk、协方差为 Σ k \Sigma_k Σk 的高斯分布。

EM算法求解步骤

EM算法用于最大化具有隐变量模型的似然函数。对于GMM,隐变量是指每个数据点属于哪个高斯成分。EM算法的步骤包括E步和M步,具体如下:

初始化
  1. 初始化参数 { π k ( 0 ) , μ k ( 0 ) , Σ k ( 0 ) } \{\pi_k^{(0)}, \mu_k^{(0)}, \Sigma_k^{(0)}\} {πk(0),μk(0),Σk(0)}
  2. 计算初始的对数似然函数值。
E步(Expectation Step)

计算第 i i i 个数据点属于第 k k k 个高斯成分的后验概率,即责任(又称响应度)

γ i k ( t ) = π k ( t ) N ( x i ∣ μ k ( t ) , Σ k ( t ) ) ∑ j = 1 K π j ( t ) N ( x i ∣ μ j ( t ) , Σ j ( t ) ) \gamma_{ik}^{(t)} = \frac{\pi_k^{(t)} \mathcal{N}(x_i \mid \mu_k^{(t)}, \Sigma_k^{(t)})}{\sum_{j=1}^K \pi_j^{(t)} \mathcal{N}(x_i \mid \mu_j^{(t)}, \Sigma_j^{(t)})} γik(t)=j=1Kπj(t)N(xiμj(t),Σj(t))πk(t)N(xiμk(t),Σk(t))

M步(Maximization Step)

更新参数:

  1. 更新混合系数:

π k ( t + 1 ) = 1 N ∑ i = 1 N γ i k ( t ) \pi_k^{(t+1)} = \frac{1}{N} \sum_{i=1}^N \gamma_{ik}^{(t)} πk(t+1)=N1i=1Nγik(t)

  1. 更新均值:

μ k ( t + 1 ) = ∑ i = 1 N γ i k ( t ) x i ∑ i = 1 N γ i k ( t ) \mu_k^{(t+1)} = \frac{\sum_{i=1}^N \gamma_{ik}^{(t)} x_i}{\sum_{i=1}^N \gamma_{ik}^{(t)}} μk(t+1)=i=1Nγik(t)i=1Nγik(t)xi

  1. 更新协方差矩阵:

Σ k ( t + 1 ) = ∑ i = 1 N γ i k ( t ) ( x i − μ k ( t + 1 ) ) ( x i − μ k ( t + 1 ) ) T ∑ i = 1 N γ i k ( t ) \Sigma_k^{(t+1)} = \frac{\sum_{i=1}^N \gamma_{ik}^{(t)} (x_i - \mu_k^{(t+1)})(x_i - \mu_k^{(t+1)})^T}{\sum_{i=1}^N \gamma_{ik}^{(t)}} Σk(t+1)=i=1Nγik(t)i=1Nγik(t)(xiμk(t+1))(xiμk(t+1))T

收敛判定

计算当前的对数似然函数值,如果其增量小于预设的阈值,则算法收敛;否则,返回E步继续迭代。

4 第9章习题

习题9.1

  如例9.1的三硬币模型,假设观测数据不变,试选择不同的处置,例如, π ( 0 ) = 0.46 , p ( 0 ) = 0.55 , q ( 0 ) = 0.67 \pi^{(0)}=0.46,p^{(0)}=0.55,q^{(0)}=0.67 π(0)=0.46,p(0)=0.55,q(0)=0.67,求模型参数为 θ = ( π , p , q ) \theta=(\pi,p,q) θ=(π,p,q)的极大似然估计。

解答:

import numpy as np
import mathclass EM:def __init__(self, prob):self.pro_A, self.pro_B, self.pro_C = probdef pmf(self, i):pro_1 = self.pro_A * math.pow(self.pro_B, data[i]) * math.pow((1 - self.pro_B), 1 - data[i])pro_2 = (1 - self.pro_A) * math.pow(self.pro_C, data[i]) * math.pow((1 - self.pro_C), 1 - data[i])return pro_1 / (pro_1 + pro_2)def fit(self, data):print('init prob:{}, {}, {}'.format(self.pro_A, self.pro_B,self.pro_C))count = len(data)theta = 1d = 0while (theta > 0.00001):# 迭代阻塞_pmf = [self.pmf(k) for k in range(count)]pro_A = 1 / count * sum(_pmf)pro_B = sum([_pmf[k] * data[k] for k in range(count)]) / sum([_pmf[k] for k in range(count)])pro_C = sum([(1 - _pmf[k]) * data[k]for k in range(count)]) / sum([(1 - _pmf[k])for k in range(count)])d += 1print('{}  pro_a:{:.4f}, pro_b:{:.4f}, pro_c:{:.4f}'.format(d, pro_A, pro_B, pro_C))theta = abs(self.pro_A - pro_A) + abs(self.pro_B -pro_B) + abs(self.pro_C -pro_C)self.pro_A = pro_Aself.pro_B = pro_Bself.pro_C = pro_C
# 加载数据
data = [1, 1, 0, 1, 0, 0, 1, 0, 1, 1]em = EM(prob=[0.46, 0.55, 0.67])
f = em.fit(data)
init prob:0.46, 0.55, 0.67
1  pro_a:0.4619, pro_b:0.5346, pro_c:0.6561
2  pro_a:0.4619, pro_b:0.5346, pro_c:0.6561

习题9.2

  过于简单,略。

习题9.3

  已知观测数据:-67,-48,6,8,14,16,23,24,28,29,41,49,56,60,75。试估计两个分量的高斯混合模型的5个参数。

解答:

from sklearn.mixture import GaussianMixture  # 用于高斯混合模型的实现
import numpy as np
import matplotlib.pyplot as plt# 初始化观测数据
data = np.array([-67, -48, 6, 8, 14, 16, 23, 24, 28, 29, 41, 49, 56, 60, 75]).reshape(-1, 1)# 聚类。指定混合成分的数量为2(即模型中有两个高斯分布)
gmmModel = GaussianMixture(n_components=2)
gmmModel.fit(data)
labels = gmmModel.predict(data)
print("labels =", labels) # 输出每个数据点所属的高斯分布的标签
print("Means =", gmmModel.means_.reshape(1, -1))
print("Covariances =", gmmModel.covariances_.reshape(1, -1))
print("Mixing Weights = ", gmmModel.weights_.reshape(1, -1))
labels = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
Means = [[ 32.98489643 -57.51107027]]
Covariances = [[429.45764867  90.24987882]]
Mixing Weights =  [[0.86682762 0.13317238]]
import matplotlib.pyplot as plt
from matplotlib_inline import backend_inline
backend_inline.set_matplotlib_formats('svg')for i in range(0, len(labels)):if labels[i] == 0:plt.scatter(i, data.take(i), s=15, c='red')elif labels[i] == 1:plt.scatter(i, data.take(i), s=15, c='blue')
plt.title('Gaussian Mixture Model')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

在这里插入图片描述

习题9.4

  EM算法可以用到朴素贝叶斯法的非监督学习,试写出其算法。

解答:

EM算法的一般化:

E步骤:
根据参数初始化或上一次迭代的模型参数来计算出隐变量的后验概率,其实就是隐变量的期望。作为隐变量的现估计值: w j ( i ) = Q i ( z ( i ) = j ) : = p ( z ( i ) = j ∣ x ( i ) ; θ ) w_j^{(i)}=Q_{i}(z^{(i)}=j) := p(z^{(i)}=j | x^{(i)} ; \theta) wj(i)=Qi(z(i)=j):=p(z(i)=jx(i);θ)
M步骤:
将似然函数最大化以获得新的参数值:
θ : = arg ⁡ max ⁡ θ ∑ i ∑ z ( i ) Q i ( z ( i ) ) log ⁡ p ( x ( i ) , z ( i ) ; θ ) Q i ( z ( i ) ) \theta :=\arg \max_{\theta} \sum_i \sum_{z^{(i)}} Q_i (z^{(i)}) \log \frac{p(x^{(i)}, z^{(i)} ; \theta)}{Q_i (z^{(i)})} θ:=argθmaxiz(i)Qi(z(i))logQi(z(i))p(x(i),z(i);θ)

使用NBMM(朴素贝叶斯的混合模型)中的 ϕ z , ϕ j ∣ z ( i ) = 1 , ϕ j ∣ z ( i ) = 0 \phi_z,\phi_{j|z^{(i)}=1},\phi_{j|z^{(i)}=0} ϕz,ϕjz(i)=1,ϕjz(i)=0参数替换一般化的EM算法中的 θ \theta θ参数,然后依次求解 w j ( i ) w_j^{(i)} wj(i) ϕ z , ϕ j ∣ z ( i ) = 1 , ϕ j ∣ z ( i ) = 0 \phi_z,\phi_{j|z^{(i)}=1},\phi_{j|z^{(i)}=0} ϕz,ϕjz(i)=1,ϕjz(i)=0参数的更新问题。

NBMM的EM算法:
E步骤:
w j ( i ) : = P ( z ( i ) = 1 ∣ x ( i ) ; ϕ z , ϕ j ∣ z ( i ) = 1 , ϕ j ∣ z ( i ) = 0 ) w_j^{(i)}:=P\left(z^{(i)}=1 | x^{(i)} ; \phi_z, \phi_{j | z^{(i)}=1}, \phi_{j | z^{(i)}=0}\right) wj(i):=P(z(i)=1∣x(i);ϕz,ϕjz(i)=1,ϕjz(i)=0)
M步骤:
ϕ j ∣ z ( i ) = 1 : = ∑ i = 1 m w ( i ) I ( x j ( i ) = 1 ) ∑ i = 1 m w ( i ) ϕ j ∣ z ( i ) = 0 : = ∑ i = 1 m ( 1 − w ( i ) ) I ( x j ( i ) = 1 ) ∑ i = 1 m ( 1 − w ( i ) ) ϕ z ( i ) : = ∑ i = 1 m w ( i ) m \phi_{j | z^{(i)}=1} :=\frac{\displaystyle \sum_{i=1}^{m} w^{(i)} I(x_{j}^{(i)}=1)}{\displaystyle \sum_{i=1}^{m} w^{(i)}} \\ \phi_{j | z^{(i)}=0}:= \frac{\displaystyle \sum_{i=1}^{m}\left(1-w^{(i)}\right) I(x_{j}^{(i)}=1)}{ \displaystyle \sum_{i=1}^{m}\left(1-w^{(i)}\right)} \\ \phi_{z^{(i)}} :=\frac{\displaystyle \sum_{i=1}^{m} w^{(i)}}{m} ϕjz(i)=1:=i=1mw(i)i=1mw(i)I(xj(i)=1)ϕjz(i)=0:=i=1m(1w(i))i=1m(1w(i))I(xj(i)=1)ϕz(i):=mi=1mw(i)

5 一个例子

使用Python和scikit-learn库来实现高斯混合模型,并应用EM算法进行参数估计。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture# 生成数据
np.random.seed(0)
n_samples = 300# 生成第一个高斯分布的数据
mean1 = [0, 0]
cov1 = [[1, 0.75], [0.75, 1]]
data1 = np.random.multivariate_normal(mean1, cov1, n_samples)# 生成第二个高斯分布的数据
mean2 = [3, 3]
cov2 = [[1, 0.75], [0.75, 1]]
data2 = np.random.multivariate_normal(mean2, cov2, n_samples)# 合并数据
data = np.vstack((data1, data2))# 创建并拟合高斯混合模型
gmm = GaussianMixture(n_components=2, covariance_type='full', random_state=0)
gmm.fit(data)# 预测每个数据点的类别标签
labels = gmm.predict(data)# 获取模型参数
weights = gmm.weights_
means = gmm.means_
covariances = gmm.covariances_print("Mixing Weights (混合系数):", weights)
print("Means (均值):", means)
print("Covariances (协方差矩阵):", covariances)# 可视化结果
plt.scatter(data[:, 0], data[:, 1], c=labels, s=40, cmap='viridis', zorder=2)
plt.scatter(means[:, 0], means[:, 1], c='red', s=100, marker='X', zorder=3)
plt.title("Gaussian Mixture Model Clustering")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()
Mixing Weights (混合系数): [0.49842773 0.50157227]
Means (均值): [[2.95306327 2.96316145][0.10026529 0.04560121]]
Covariances (协方差矩阵): [[[0.89428558 0.60641642][0.60641642 0.77687958]][[1.05451964 0.7500382 ][0.7500382  0.94281161]]]

在这里插入图片描述

代码来自:https://github.com/fengdu78/lihang-code
参考书籍:李航《机器学习方法》

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

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

相关文章

SmartEDA革新来袭:融合Multisim与Proteus精髓,引领电子设计新纪元!

在电子设计领域,每一次技术的革新都如同春风化雨,滋润着设计师们的心田。今天,我们迎来了一个划时代的电子设计自动化(EDA)工具——SmartEDA,它不仅融合了业界知名的Multisim和Proteus的精华,更…

煤矿智能巡检机器人:推动煤矿行业变革的关键力量

目前我国煤炭资源总量达到了2078.85亿吨,已探明储量为1432亿吨,煤矿能源现阶段还是我国重要的基础能源。而煤矿生产作业存在巨大危险,主要包括高温、高压、燃爆和有毒气体等环境因素,同时机械设备运转过程中潜藏着重大风险。这些危…

MySQL中的Bin-log是什么?有什么作用?

Bin-log日志也被称之为二进制日志,作用与Redo-log类似,主要是记录所有对数据库表结构变更和表数据修改的操作,对于select、show这类读操作并不会记录。bin-log是MySQL-Server级别的日志,所有引擎都能用的日志,而redo-l…

DataStructure.包装类简单认识泛型

包装类&简单认识泛型 【本节目标】1 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱 2 什么是泛型3 引出泛型3.1 语法 4 泛型类的使用4.1 语法4.2 示例4.3 类型推导(Type Inference) 5. 裸类型(Raw Type) (了解)5.1 说明…

tensorflow学习:错误 InternalError: Dst tensor is not initialized

tensorflow学习:错误 InternalError: Dst tensor is not initialized_dst tensor is not initialized.-CSDN博客https://blog.csdn.net/wanglitao588/article/details/77033659

多元化功能空间,打造影像产业生态圈

国际数字影像产业园的多元化功能空间定位涵盖了从产业实训、研发创新、资产交易、集群发展到孵化服务、大数据支持、产学研合作以及人力资源服务等多个方面,旨在为数字影像产业提供全方位的支持和服务,推动产业的升级和发展。 1、产业实训空间&#xff1…

开发一款直播APP完整指南

直播是一种强大的营销工具,可以让企业与观众进行真实的互动。 根据Grand View Research发布的预测,直播行业规模将从 2021 年的 700 亿美元增长到 2028 年的近 2240 亿美元,七年内增长三倍。 区块链技术和人工智能等技术进步将在未来几年提…

网络协议TCP/IP, HTTP/HTTPS介绍

TCP/IP协议 TCP/IP是一种基于连接的通信协议,它是互联网的基础协议。TCP代表传输控制协议,IP代表Internet协议。虽然这两个协议通常一起提及,但它们实际上是分开的:IP负责在网络中从一台计算机向另一台计算机发送数据包&#xff0…

深度学习21-30

1.池化层作用(筛选、过滤、压缩) h和w变为原来的1/2,64是特征图个数保持不变。 每个位置把最大的数字取出来 用滑动窗口把最大的数值拿出来,把44变成22 2.卷积神经网络 (1)conv:卷积进行特征…

圈复杂度.

圈复杂度是衡量代码的重要标准 配置: eslint里面:rules:complexity:[error,10]

ChatBI开源实现: 基于SuperSonic的AI+BI的产品设计

产品起源 为什么要做这样的产品?文章《ChatBI开源实现: AIBI的产品设计》中有介绍 为什么要自己做这样的产品?1、低成本试错;2、未来数据生态入口; 为什么要基于Supersonic做? 开源协议友好:可魔改商用 社区…

深入解析MVCC:多版本并发控制的数据库之道

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…

C语言王国——深入自定义类型(联合体、枚举)

目录 一、引言 二、联合体 2.1 联合体类型的声明 2.2 联合体大小的计算 2.3 联合体的实践运用 2.4 用联合体测试大小端字节序 三、枚举 3.1 枚举类型的声明 3.2 枚举类型的特点 四、总结 一、引言 我们刚学完了结构体,相信大家对自定义类型也有了些许了解&…

【代码随想录】【算法训练营】【第50天】 [1143]最长公共子序列 [1035]不相交的线 [53]买卖股票的最佳时机III [392]判断子序列

前言 思路及算法思维,指路 代码随想录。 题目来自 LeetCode。 day 50,周三,无法坚持~ 题目详情 [1143] 最长公共子序列 题目描述 1143 最长公共子序列 解题思路 前提: 思路: 重点: 代码实现 C语…

07 - matlab m_map地学绘图工具基础函数 - 绘制等高线

07 - matlab m_map地学绘图工具基础函数 - 绘制等高线 0. 引言1. 关于绘制m_contour2. 关于绘制m_contourf3. 关于绘制m_elev4. 结语 0. 引言 本篇介绍下m_map中添加绘制等高线的一系列函数及其用法,主要函数包括m_elev、m_contour、m_contourf还有一些函数也和绘制…

初探海龟绘图

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 海龟绘图是Python内置的模块,在使用前需要导入该模块,可以使用以下几种方法导入: l 直接使用import语句导入海龟…

LeetCode 算法:将有序数组转换为二叉搜索树 c++

原题链接🔗:将有序数组转换为二叉搜索树 难度:简单⭐️ 题目 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。 示例 1: 输入:nums [-10,-3,0,5,9]…

[面试题]Zookeeper

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis[面试题]消息队列[面试题]…

【C语言】操作符(上)

目录 1. 操作符的分类 2. 原码、反码、补码 3. 移位操作符 3.1 左移操作符 3.2 右移操作符 4. 位操作符:&、|、^、~ 5. 单目操作符 6. 逗号表达式 最近准备期末考试,好久不见啦,现在回归—— 正文开始—— 1. …

mulesoft --环境安装与搭建

1.mavenjdkpostman 2.anypoint statdio 下载安装 下载 Anypoint Studio & Mule |骡子软件 (mulesoft.com) 填好基本信息后,会发邮件,在邮件中下载,跳到官网下载 3注册账号 Download Anypoint Studio & Mule | MuleSoft 4.Connect…