支持向量机——pytorch与paddle实现支持向量机

pytorchpaddle_0">支持向量机——pytorchpaddle实现支持向量机

本文将深入探讨支持向量机的理论基础,并通过PyTorch和PaddlePaddle两个深度学习框架来展示如何实现支持向量机模型。我们将首先介绍支持向量机、优化的基本概念,这些数学工具是理解和实现支持向量机的基础。通过PyTorch和PaddlePaddle的代码示例,我们将展示如何设计、训练和评估一个支持向量机模型,从而让读者能够直观地理解并掌握这两种框架在机器学习问题中的应用。

本文部分为torch框架以及部分理论分析,paddle框架对应代码可见支持向量机paddle
感兴趣的uu可以看看本专栏的往期内容哦~:
深度强化学习开端——DQN算法求解车杆游戏
强化学习的适应性改进——策略梯度算法求解山地车游戏
线性回归——pytorchpaddle实现线性回归的详细过程
接下来我们进入正题!

import torch
print("pytorch version:",torch.__version__)
pytorch version: 2.2.2+cu121

支持向量机(SVM)理论分析

支持向量机(Support Vector Machine, SVM)是一种广泛使用的分类器,特别适合于高维数据分类问题。SVM 的主要思想是寻找一个最优超平面,以最大化两个类别之间的边界(即“间隔”)。

基本概念

给定训练数据集 { ( x i , y i ) } i = 1 N \{(x_i, y_i)\}_{i=1}^{N} {(xi,yi)}i=1N,其中 x i ∈ R n x_i \in \mathbb{R}^n xiRn y i ∈ { − 1 , + 1 } y_i \in \{-1, +1\} yi{1,+1}。SVM 旨在找到一个超平面 w ⋅ x + b = 0 w \cdot x + b = 0 wx+b=0,使得该超平面能最好地将两类数据分开。

对于线性可分的数据集,最优超平面可以通过解决以下优化问题来找到:

min ⁡ w , b 1 2 ∥ w ∥ 2 s.t. y i ( w ⋅ x i + b ) ≥ 1 , i = 1 , 2 , … , N \begin{align*} &\min_{w, b} \frac{1}{2} \|w\|^2 \\ &\text{s.t.} \quad y_i(w \cdot x_i + b) \geq 1, \quad i = 1, 2, \ldots, N \end{align*} w,bmin21w2s.t.yi(wxi+b)1,i=1,2,,N
这里, ∥ w ∥ \|w\| w 是向量 w w w 的欧几里得范数,代表超平面的法向量; b b b 是偏置项。约束条件确保了每个数据点都被正确分类,并且距离超平面至少有一定的“间隔”。

训练优化方法

解决上述优化问题通常使用拉格朗日乘子法和对偶理论。引入拉格朗日乘子 α i ≥ 0 \alpha_i \geq 0 αi0,我们可以得到拉格朗日函数:

L ( w , b , α ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 N α i [ y i ( w ⋅ x i + b ) − 1 ] L(w, b, \alpha) = \frac{1}{2} \|w\|^2 - \sum_{i=1}^{N} \alpha_i [y_i(w \cdot x_i + b) - 1] L(w,b,α)=21w2i=1Nαi[yi(wxi+b)1]
L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 关于 w w w b b b 求偏导,并令其等于 0,我们可以将对 w w w b b b 的优化问题转化为对 α \alpha α 的优化问题:

max ⁡ α ∑ i = 1 N α i − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j x i ⋅ x j s.t. α i ≥ 0 , ∑ i = 1 N α i y i = 0 \begin{align*} &\max_{\alpha} \sum_{i=1}^{N} \alpha_i - \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j x_i \cdot x_j \\ &\text{s.t.} \quad \alpha_i \geq 0, \quad \sum_{i=1}^{N} \alpha_i y_i = 0 \end{align*} αmaxi=1Nαi21i=1Nj=1Nαiαjyiyjxixjs.t.αi0,i=1Nαiyi=0
这是一个二次规划问题,可以使用标准的优化算法(如 SMO,Sequential Minimal Optimization)来解决。

# 接下来我们将使用PyTorch实现线性支持向量机过程
# 我们首先生成一些数据用于分类问题
def synthetic_data_classfier(w, b, num_examples):"""生成y=Xw+b+噪声"""X = torch.normal(-1, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(-0.00001, 0.00001, y.shape)# 将大于0的元素设置为1  y[y > 0] = 1.  # 将小于0的元素设置为-1  y[y < 0] = -1.return X, y.reshape((-1, 1))true_w = torch.tensor([-0.1, -0.2, -0.3, -0.4, -0.5, -1.0, 1, 0.5, 0.4, 0.3, 0.2, 0.1])  # 参数这样设置是为了让数据期望变为0
true_b = 0
features, labels = synthetic_data_classfier(true_w, true_b, 10000)
# 将数据放置在迭代器里边
from sklearn.model_selection import train_test_split  
from torch.utils.data import Dataset, DataLoader  class CustomDataset(Dataset):  def __init__(self, features, labels):  self.features = features  self.labels = labels  def __len__(self):  return len(self.labels)  def __getitem__(self, idx):  return self.features[idx], self.labels[idx]  def create_data_loaders(features, labels, batch_size=32, test_size=0.2, random_state=42):  # 划分数据集  X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=test_size, random_state=random_state)  # 创建Dataset对象  train_dataset = CustomDataset(X_train, y_train)  test_dataset = CustomDataset(X_test, y_test)  # 创建DataLoader对象  train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)  test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)  return train_loader, test_loader  train_loader, test_loader = create_data_loaders(features, labels, batch_size=64)
# 让我们来设计一个线性支持向量模型吧
class LinearSVM(torch.nn.Module):def __init__(self, input_dim):  super(LinearSVM, self).__init__()  self.w = torch.nn.Parameter(torch.randn(input_dim))  # randn为服从标准正态分布的随机数,此处我们生成一个随机向量作为参数wself.b = torch.nn.Parameter(torch.randn(1))  # 偏置项self.Loss = None  # 损失函数self.optimizer = None  # 优化器def forward(self, x):return torch.matmul(x, self.w) + self.b  # 前向传播获得输出def refresh_params(self, x, y):# 利用x,y数据更新参数w,b out = self.forward(x)if self.Loss is None:self.Loss = torch.nn.MSELoss()L = self.Loss(out.reshape(-1, 1), y)# 利用梯度下降法更新参数w,bif self.optimizer is None:self.optimezer = torch.optim.SGD([self.w, self.b], lr=0.001)  # 优化器self.optimezer.zero_grad()  # 梯度清零L.backward()  # 反向传播self.optimezer.step()  # 更新参数
# 接下来让我们进行训练和测试过程吧!
model = LinearSVM(input_dim=features.shape[1])  # 加载模型
for epoch in range(100):for features_train, labels_train in train_loader:model.refresh_params(features_train, labels_train)# 测试数据精度if epoch % 10 == 0 or epoch == 99:with torch.no_grad():for features_test, labels_test in test_loader:predictions = model.forward(features_test)predictions = torch.sign(predictions).reshape(labels_test.shape)correct = (predictions == labels_test).float()accuracy = correct.sum() / len(correct)print("Epoch: {}, Accuracy: {}".format(epoch, accuracy))break
Epoch: 0, Accuracy: 0.453125
Epoch: 10, Accuracy: 0.9375
Epoch: 20, Accuracy: 0.984375
Epoch: 30, Accuracy: 0.984375
Epoch: 40, Accuracy: 0.984375
Epoch: 50, Accuracy: 0.984375
Epoch: 60, Accuracy: 0.984375
Epoch: 70, Accuracy: 0.984375
Epoch: 80, Accuracy: 0.984375
Epoch: 90, Accuracy: 0.984375
Epoch: 99, Accuracy: 0.984375

由以上代码我们可以发现,当数据线性可分时,利用线性回归的策略都可以得到一个较好的精度。接下来我们参考机器学习算法实践-SVM中的SMO算法对SMO算法的详细介绍,设计一个标准的SVM分类器,并利用SMO算法进行优化。

def clip(a, L, H):# 对alpha进行修剪if a > H:return Helif a < L:return Lelse:return aclass SVM(torch.nn.Module):  def __init__(self, input_dim):  super(SVM, self).__init__()  self.w = torch.randn(input_dim)self.b = torch.randn(1)self.alpha = None  # 这个将在SMO中作为拉格朗日乘子的缓存  self.C = 1.0  # 正则化参数,可以根据需要调整  self.eps = 1e-3  # 用于判断数值解的容差  self.kernel_function = self.linear_kernel  # 核函数,默认为线性核  def forward(self, x):  # 前向传播return torch.matmul(x, self.w) + self.b def linear_kernel(self, x1, x2):# 线性核函数  if x1.shape[0] != x2.shape[0]:return torch.matmul(x1, x2)return torch.dot(x1, x2)  def f(self, x, data_x, data_y):# 计算目标函数return torch.sum(self.alpha * data_y * self.kernel_function(data_x, x)) + self.bdef SMO(self, x, y, i, j):# SMO算法,其中输入的i,j为待优化的alpha下标# 获得没有修建的原始解# 旧的alpha值alpha_i_old = self.alpha[i].clone()alpha_j_old = self.alpha[j].clone()# 计算两个alpha下标对应的样本点x_i = x[i]x_j = x[j]# 计算两个alpha下标对应的样本点对应的标签y_i = y[i]y_j = y[j]# 计算SVM预测值与真实值的误差E_i = self.f(x_i, x, y) - y_iE_j = self.f(x_j, x, y) - y_j# 计算x_i与x_j的核函数值k_ii, k_jj, k_ij = self.kernel_function(x_i, x_i), self.kernel_function(x_j, x_j), self.kernel_function(x_i, x_j)eta = k_ii + k_jj - 2*k_ijif eta <= 0:print('WARNING  eta <= 0')returnalpha_j_new_unrestricted = alpha_j_old + (y_j * (E_i - E_j)) / eta# 对alpha进行修剪if y_i != y_j:L = max(0, alpha_j_old - alpha_i_old)H = min(self.C, self.C + alpha_j_old - alpha_i_old)else:L = max(0, alpha_i_old + alpha_j_old - self.C)H = min(self.C, alpha_j_old + alpha_i_old)alpha_j_new = clip(alpha_j_new_unrestricted, L, H)alpha_i_new = alpha_i_old + y_i*y_j*(alpha_j_old - alpha_j_new)if abs(alpha_j_new - alpha_j_old) < 0.00001:returnself.alpha[i], self.alpha[j] = alpha_i_new, alpha_j_new# 更新阈值bb_i = -E_i - y_i*k_ii*(alpha_i_new - alpha_i_old) - y_j*k_ij*(alpha_j_new - alpha_j_old) + self.bb_j = -E_j - y_i*k_ij*(alpha_i_new - alpha_i_old) - y_j*k_jj*(alpha_j_new - alpha_j_old) + self.bif 0 < alpha_i_new < self.C:self.b = b_ielif 0 < alpha_j_new < self.C:self.b = b_jelse:self.b = (b_i + b_j)/2def refresh_params(self, x, y):# 利用SMO算法更新参数w,b,alphaif self.alpha is None:self.alpha = torch.zeros(x.shape[0]).reshape(-1, 1)  # 拉格朗日乘子# 遍历样本,随机选择第二个样本进行优化  for i in range(x.shape[0]):  # 选择第二个alpha  j = torch.randint(0, x.shape[0], (1,)).item()  while j == i:  # 确保i和j不是同一个样本  j = torch.randint(0, x.shape[0], (1,)).item()  # 调用SMO来尝试更新alpha_i和alpha_j  self.SMO(x, y, i, j)  # 更新权重向量 w  self.w = torch.zeros(x.shape[1])  # 初始化 w 为零向量  for i in range(x.shape[0]):  self.w += self.alpha[i] * y[i] * x[i]  # 根据上述公式累加更新 w
# 接下来让我们选取一部分数据来看看SMO算法吧
model = SVM(input_dim=features.shape[1])  # 加载模型
# 选取数据集中前2000个数据进行训练
model.refresh_params(features[:3000,:], labels[:3000,:])# 测试数据精度
with torch.no_grad():for features_test, labels_test in test_loader:predictions = model.forward(features_test)predictions = torch.sign(predictions).reshape(labels_test.shape)correct = (predictions == labels_test).float()accuracy = correct.sum() / len(correct)print( "Accuracy: {}".format(accuracy))break
Accuracy: 0.9375

可以看到利用上述代码,我们可以得到一个精度相对较高的SVM分类器。

支持向量与间隔

在 SVM 中,“支持向量”是指那些距离超平面最近的数据点,它们对确定最优超平面起决定性作用。间隔(margin)是支持向量到超平面的距离,其大小由 1 ∥ w ∥ \frac{1}{\|w\|} w1 给出。SVM 的目标是最大化这个间隔。

核函数与非线性 SVM

对于非线性可分的数据集,我们可以通过引入核函数 K ( x , y ) K(x, y) K(x,y) 来将数据映射到一个更高维的空间,从而在新的空间中实现线性可分。常用的核函数包括多项式核、高斯核(RBF 核)等。
支持向量机(Support Vector Machine, SVM)是一种常用的监督学习模型,主要用于分类和回归分析。当数据不是线性可分时,可以引入核函数,将数据映射到更高维的空间,从而在新的空间中实现线性可分。

具有核函数的支持向量机

给定训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } T = \{(x_1, y_1), (x_2, y_2), \ldots, (x_N, y_N)\} T={(x1,y1),(x2,y2),,(xN,yN)},其中 $ x_i \in \mathbb{R}^n,y_i \in {+1, -1} $。支持向量机的基本思想是找到一个超平面,以最大化两个类别之间的间隔。

在非线性可分的情况下,引入一个非线性映射 ϕ ( x ) \phi(x) ϕ(x) 将输入空间的数据映射到一个更高维的特征空间,然后在这个特征空间中寻找最优超平面。然而,直接计算 ϕ ( x ) \phi(x) ϕ(x) 可能是复杂的,甚至是不可能的。因此,我们引入核函数 K ( x , z ) K(x, z) K(x,z),它满足 K ( x , z ) = ϕ ( x ) ⋅ ϕ ( z ) K(x, z) = \phi(x) \cdot \phi(z) K(x,z)=ϕ(x)ϕ(z),从而避免显式地计算 ϕ ( x ) \phi(x) ϕ(x)

常用的核函数包括:

  • 线性核: K ( x , z ) = x ⋅ z K(x, z) = x \cdot z K(x,z)=xz
  • 多项式核: K ( x , z ) = ( γ x ⋅ z + r ) d K(x, z) = (\gamma x \cdot z + r)^d K(x,z)=(γxz+r)d,其中 γ , r , d \gamma, r, d γ,r,d 是参数。
  • 径向基核(RBF): K ( x , z ) = exp ⁡ ( − γ ∥ x − z ∥ 2 ) K(x, z) = \exp(-\gamma \|x - z\|^2) K(x,z)=exp(γxz2),其中 γ \gamma γ 是参数。
  • Sigmoid核: K ( x , z ) = tanh ⁡ ( γ x ⋅ z + r ) K(x, z) = \tanh(\gamma x \cdot z + r) K(x,z)=tanh(γxz+r),其中 γ , r \gamma, r γ,r 是参数。

对偶问题

支持向量机中,对偶问题是通过拉格朗日乘数法将原问题转化为更易求解的形式。对偶问题的求解通常更高效,并且可以引入核函数来处理非线性可分的情况。

原问题可以表示为:
min ⁡ w , b , ξ 1 2 ∥ w ∥ 2 + C ∑ i = 1 N ξ i s.t. y i ( w ⋅ ϕ ( x i ) + b ) ≥ 1 − ξ i , ξ i ≥ 0 , i = 1 , 2 , … , N \min_{w, b, \xi} \frac{1}{2} \|w\|^2 + C \sum_{i=1}^{N} \xi_i \\ \text{s.t.} \quad y_i (w \cdot \phi(x_i) + b) \geq 1 - \xi_i, \quad \xi_i \geq 0, \quad i = 1, 2, \ldots, N w,b,ξmin21w2+Ci=1Nξis.t.yi(wϕ(xi)+b)1ξi,ξi0,i=1,2,,N
其中 w w w 是超平面的法向量, b b b 是偏置项, ξ i \xi_i ξi 是松弛变量,用于处理不可分的情况, C C C 是惩罚参数。

通过拉格朗日乘数法,我们可以得到对偶问题:
max ⁡ α ∑ i = 1 N α i − 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j K ( x i , x j ) s.t. ∑ i = 1 N α i y i = 0 , 0 ≤ α i ≤ C , i = 1 , 2 , … , N \max_{\alpha} \sum_{i=1}^{N} \alpha_i - \frac{1}{2} \sum_{i=1}^{N} \sum_{j=1}^{N} \alpha_i \alpha_j y_i y_j K(x_i, x_j) \\ \text{s.t.} \quad \sum_{i=1}^{N} \alpha_i y_i = 0, \quad 0 \leq \alpha_i \leq C, \quad i = 1, 2, \ldots, N αmaxi=1Nαi21i=1Nj=1NαiαjyiyjK(xi,xj)s.t.i=1Nαiyi=0,0αiC,i=1,2,,N
其中 α i \alpha_i αi 是拉格朗日乘子, K ( x i , x j ) K(x_i, x_j) K(xi,xj) 是核函数。

求解对偶问题后,我们可以得到最优的 α ∗ \alpha^* α,进而通过 α ∗ \alpha^* α 得到最优的超平面参数 w ∗ w^* w b ∗ b^* b。最终,决策函数可以表示为:
f ( x ) = sign ( ∑ i = 1 N α i ∗ y i K ( x i , x ) + b ∗ ) f(x) = \text{sign} \left( \sum_{i=1}^{N} \alpha_i^* y_i K(x_i, x) + b^* \right) f(x)=sign(i=1NαiyiK(xi,x)+b)

支持向量机的拓展:支持向量回归(SVR)

支持向量机不仅可以用于分类问题,还可以扩展到回归问题,即支持向量回归(Support Vector Regression, SVR)。在 SVR 中,目标是找到一个回归函数 f ( x ) = w ⋅ ϕ ( x ) + b f(x) = w \cdot \phi(x) + b f(x)=wϕ(x)+b,其中 ϕ ( x ) \phi(x) ϕ(x) 是将数据映射到高维空间的函数。SVR 通过引入一个不敏感损失函数 ϵ \epsilon ϵ 来实现回归,该函数只惩罚那些与预测值差距大于 ϵ \epsilon ϵ 的点。

SVR 的优化问题与 SVM 类似,但约束条件和目标函数有所不同。通过解决相应的优化问题,我们可以找到最优的回归函数。
支持向量机是一种强大的分类和回归工具,特别适合于处理高维数据和复杂模式识别问题。通过选择合适的核函数和参数,SVM 可以灵活地处理线性和非线性问题。此外,SVM 还可以通过拓展到支持向量回归来解决回归问题,进一步扩大了其应用范围。

接下来我们使用机器学习sklearn实现支持向量机和支持向量回归

from sklearn import svm  
from sklearn.model_selection import train_test_split  
from sklearn import datasets  
from sklearn.metrics import accuracy_score  # 加载数据集,这里以鸢尾花数据集为例  
iris = datasets.load_iris()  
X = iris.data  
y = iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)  
# 创建SVM分类器  
clf = svm.SVC(kernel='linear')  # 线性核函数,你也可以选择其他核函数,如'rbf'、'poly'、'sigmoid'等  # 训练模型  
clf.fit(X_train, y_train)  # 进行预测  
y_pred = clf.predict(X_test)  # 评估模型  
print("Accuracy:", accuracy_score(y_test, y_pred))
Accuracy: 0.9777777777777777
# 接下来我们使用之前生成的数据进行支持向量回归,看看模型精度
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.3) 
# 创建SVM分类器  
clf = svm.SVC(kernel='linear')  # 线性核函数,你也可以选择其他核函数,如'rbf'、'poly'、'sigmoid'等   
# 训练模型  
clf.fit(X_train, y_train)  
# 进行预测  
y_pred = clf.predict(X_test)  
# 评估模型  
print("Accuracy:", accuracy_score(y_test, y_pred))
Accuracy: 0.9963333333333333C:\Users\sswun\AppData\Roaming\Python\Python311\site-packages\sklearn\utils\validation.py:1183: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().y = column_or_1d(y, warn=True)

可以看到,利用sklearn设计的支持向量机分类器,我们可以得到一个很高的分类精度。接下来我们实现一下支持向量回归的过程。

# 支持向量回归过程
from sklearn.metrics import mean_squared_error  # 加载California housing数据集  
boston = datasets.fetch_california_housing()
X = boston.data  
y = boston.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建SVR模型  
svr = svm.SVR(kernel='rbf', C=1e3, gamma=0.1)  # 这里使用了RBF核函数  # 训练模型  
svr.fit(X_train, y_train)  # 进行预测  
y_pred = svr.predict(X_test)  # 评估模型  
mse = mean_squared_error(y_test, y_pred)  
print("Mean Squared Error:", mse)  
Mean Squared Error: 1.1010094730131161

支持向量机(SVM)的发展历程可以追溯到上个世纪60年代。1963年,Vapnik在解决模式识别问题时首次提出了支持向量方法,其中起决定性作用的样本被称为支持向量。然后在1971年,Kimeldorf提出了基于支持向量构建核空间的方法。然而,SVM的真正发展和普及是在1995年,当Vapnik等人正式提出统计学习理论之后。从那时起,SVM逐渐成为一种广泛使用的机器学习算法。

在SVM的发展历程中,还出现了许多改进和变种。例如,模糊支持向量机、最小二乘支持向量机、加权支持向量机、主动学习的支持向量机、以及基于决策树的支持向量机等,都是对原始SVM的改进和扩展。这些改进使得SVM能够更灵活地处理各种不同类型的数据和问题。

至于SVM的未来发展道路,虽然目前SVM已经在许多领域取得了显著的成功,但随着数据科学和机器学习领域的快速发展,SVM仍面临一些挑战和机遇。

一方面,随着大数据时代的到来,如何高效地处理海量数据成为SVM面临的一个重要问题。未来的研究可能会集中在开发更高效的优化算法,以提高SVM在处理大数据时的性能和效率。

另一方面,随着深度学习技术的快速发展,如何将深度学习的思想与方法融入SVM中,以进一步提升其性能,也是未来研究的一个重要方向。例如,可以利用深度学习的特征提取能力来优化SVM的输入特征,或者借鉴深度学习的训练方法来改进SVM的训练过程。

此外,随着越来越多的复杂应用场景的出现,如何对SVM进行改进以适应这些场景也是未来研究的一个重要课题。例如,在处理不平衡数据集、多类别分类、以及在线学习等问题时,SVM可能需要进行相应的改进和优化。

总的来说,虽然SVM已经是一种非常成熟和有效的机器学习算法,但随着技术的不断进步和应用场景的不断拓展,SVM仍然有着广阔的发展空间和潜力。
本文部分为torch框架以及部分理论分析,paddle框架对应代码可见支持向量机paddle


http://www.ppmy.cn/embedded/22270.html

相关文章

大数据005-hadoop003-了解MR及Java的简单实现

了解MapReduce MapReduce过程分为两个阶段&#xff1a;map阶段、reduce阶段。每个阶段搜键-值对作为输入和输出。 要执行一个MR任务&#xff0c;需要完成map、reduce函数的代码开发。 Hellow World 【Hadoop权威指南】中的以分析气象数据为例&#xff0c;找到每年的最高气温。…

抽象的代理模式1.0版本

前言&#xff1a; 在阅读Spring Security官方文档时&#xff0c;里面设计到了一种设计模式——代理模式Proxy 众里寻她千百度&#xff0c;蓦然回首&#xff0c;那人却在灯火阑珊处 开始 在之前的文章里陈述了一个观点——编程语言和语言没有区别 现看看我们日常生活中的代理…

笔记:编写程序,绘制一个展示支付宝月账单报告的饼图,

文章目录 前言一、饼图是什么&#xff1f;二、分析题目三、编写代码总结 前言 编写程序&#xff0c;绘制一个展示支付宝月账单报告的饼图&#xff0c;实现过程如下&#xff1a; &#xff08;1&#xff09; 导入 matplotlib.pyplot 模块&#xff1b; &#xff08;2&#xff09;…

C语言——字符串和字符串函数

一、字符串 实际上C语言中实际上是没有内置的字符串类型的&#xff0c;大部分字符串都是以字符型数组和常量字符串的形式存在的。 字符串可以通过多种方式在C语言中声明和初始化&#xff1a; 直接初始化&#xff1a; char greeting[] "Hello, world!"; 在这个例…

02.Kafka部署安装

1 Linux 安装 Kafka 1.1 安装前的环境准备 由于 Kafka 是用 Scala 语言开发的&#xff0c;运行在 JVM 上&#xff0c;因此在安装Kafka之前需要先安装JDK。 yum install java-1.8.0-openjdk* -y kafka 依赖 zookeeper&#xff0c;所以需要先安装 zookeeper。 wget https://ar…

docker 部署 kafka-ui

docker 部署 kafka-ui docker run -p 8080 \--name kafka-ui \-e KAFKA_CLUSTERS_0_NAMEkafka \-e KAFKA_CLUSTERS_0_BOOTSTRAPSERVERSlocalhost:9092 \-e TZAsia/Shanghai \-e LANGC.UTF-8 \-e SERVER_SERVLET_CONTEXT_PATH"/" \-e AUTH_TYPE"LOGIN_FORM"…

全面理解Python中的迭代器

一、引言 在Python编程中&#xff0c;数据的处理和操作是核心任务之一。想象一下&#xff0c;你有一个装满各种颜色球的箱子&#xff0c;你想逐个查看并使用这些球&#xff0c;但又不想一次性将它们全部取出。这就引出了我们今天要讨论的主题——迭代。 1.1 什么是迭代 迭代…

代谢组数据分析三:差异分析

Differetial Analysis 差异分析的目的是为了筛选代谢物标记物,常用的方法有以下几种 倍数变化法 (Fold Change),也有基于log2的Fold change,计算组间倍数变化 T检验,计算组间均值的t统计量差别 PLS-DA或OPLS-DA的VIP(Variable Importance for the Projection,变量投影重要…

centos 7 yum install -y nagios

centos 7 systemctl disable firewalld --now vi /etc/selinux/config SELINUXdisabled yum install -y epel-release httpd nagios yum install -y httpd nagios systemctl enable httpd --now systemctl enable nagios --now 浏览器 IP/nagios 用户名&#xff1a;…

BetterDisplay Pro for Mac:显示器校准软件

BetterDisplay Pro for Mac是一款出色的显示器校准软件&#xff0c;旨在提升你的视觉体验。它提供了准确的显示器参数调整&#xff0c;包括亮度、对比度、色温和色域等&#xff0c;让你的显示器呈现更真实、清晰、细腻的图像。此外&#xff0c;软件还提供多种预设模式和自定义选…

MySql: 可视化工具监测管理数据库

Navicat 官网 Navicat 也可以从网盘中下载 链接: https://pan.baidu.com/s/1gawJN5d4_eBSQiZaFeNMSA 提取码: 33bd

数据库之数据库恢复技术思维导图+大纲笔记

大纲笔记&#xff1a; 事务的基本概念 事务 定义 用户定义的一个数据库操作系列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的基本单位 语句 BEGIN TRANSACTION 开始 COMMIT 提交&#xff0c;提交事务的所有操作 ROLLBACK 回滚&#xff0c…

泰克示波器电流探头如何抓浪涌电流波形?

泰克示波器是一种常见的电子测量仪器&#xff0c;广泛应用于电子工程、通信工程、医疗设备等领域。它的主要功能是实时显示电信号的波形&#xff0c;从而帮助工程师和技术人员分析和调试电路。而在一些特定的应用场景中&#xff0c;例如电源、电机、电器设备等&#xff0c;我们…

OpenCV如何实现背投

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV直方图比较 下一篇&#xff1a;OpenCV如何模板匹配 目标 在本教程中&#xff0c;您将学习&#xff1a; 什么是背投以及它为什么有用如何使用 OpenCV 函数 cv::calcBackProject 计…

弹性网络回归(概念+实例)

目录 前言 一、基本概念 1. 弹性网络回归的原理 2. 弹性网络回归的优点 3. 弹性网络回归的应用 4. 弹性网络回归的调参 二、实例 前言 弹性网络回归&#xff08;Elastic Net Regression&#xff09;是一种用于处理回归问题的机器学习算法&#xff0c;它结合了岭回归&…

icloud里面的通讯录怎么全部导出,通讯录格式如何转换,简单!

随着科技的发展&#xff0c;我们的日常生活越来越离不开手机和各种应用程序。通讯录作为手机中最重要的功能之一&#xff0c;记录着我们的亲朋好友、同事和业务伙伴的联系方式。因此&#xff0c;定期备份通讯录变得尤为重要。iCloud作为苹果公司提供的一项云服务&#xff0c;可…

格瑞威特 | 邀您参加2024全国水科技大会暨技术装备成果展览会

—— 展位号&#xff1a;A13 —— 企业介绍 北京格瑞威特环保设备有限公司成立于2009年&#xff0c;是专业从事设计、研发、销售智能加药计量泵、在线水质分析仪表、便携式水质分析仪表、流量计、液位计、阀门、搅拌机、烟气报警仪、加药装置等各类水处理设备及配件的OEM供服…

React的状态管理useState

基础使用 useState 是一个 React Hook&#xff08;函数&#xff09;&#xff0c;它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果和普通JS变量不同的是&#xff0c;状态变量一旦发生变化组件的视图UI也会跟着变化&#xff08;数据驱动视图&#xff09; useState…

【AIGC】探索大语言模型中的词元化技术机器应用实例

科技前沿&#xff1a;探索大语言模型中的词元化技术及其应用实例 一、词元化技术的原理与重要性二、词元化技术的应用实例与代码展示三、词元化技术在科技热点中的应用四、总结与展望 随着人工智能技术的迅猛发展&#xff0c;自然语言处理领域也取得了长足的进步。其中&#xf…

vue中 key 的原理

Vue中&#xff0c;key是用于帮助Vue识别VNode的一种特殊属性&#xff0c; 当Vue在更新DOM时&#xff0c;它会尽可能地复用已经存在的元素而不是重新创建&#xff0c; key的作用&#xff0c;就是&#xff0c;帮助Vue识别每个VNode的唯一性&#xff0c; 从而在进行DOM更新时&a…