多项式朴素贝叶斯分类器

在这篇文章中,我们介绍多项式朴素贝叶斯分类器是如何工作的,然后使用scikit-learn作为实际工作的示例来介绍如何使用。

与假设高斯分布的高斯朴素贝叶斯分类器相反,多项式朴素贝叶斯分类器依赖于多项分布。通过学习/估计每个类的多项概率来“拟合”多项式分类器-使用平滑技巧来处理空特征。Multinomial Naive Bayes(多项式朴素贝叶斯)是一种常用的文本分类算法,特别适用于处理多类别分类问题,例如文档分类、垃圾邮件检测等。它是朴素贝叶斯(Naive Bayes)算法的一种变体,主要用于处理特征是离散型变量的情况,通常用于文本分类任务中。

多项分布

如果你已经熟悉多项分布,可以跳过这个部分。

了解多项式朴素贝叶斯的第一步是了解什么是多项分布。

多项分布(Multinomial Distribution)是概率论和统计学中常用的一种概率分布,用于描述具有多个离散结果的随机试验。它是二项分布的推广,适用于多类别问题,例如投掷一枚骰子多次,每次可能得到1、2、3、4、5、6这六种结果的其中一种。

多项分布描述了进行 nn 次独立的多项试验时,各个类别的概率分布。如果一个随机变量 XX 表示了这些试验中各类别出现的次数,其中有 kk 个类别(例如在骰子的例子中就是6个类别),则多项分布的概率质量函数为:

多项分布是离散型的。与二项分布类似,但不同的是,二项分布只涉及两种结果,而多项分布适用于多种结果的情况。每个试验的结果可以是多个类别之一。多项分布中的概率质量函数考虑了各个类别出现的次数以及各类别的概率。

如果投掷一个六面骰子 10 次,每个面出现的次数是 X1,X2,…,X6X1,X2,…,X6,那么 X1+X2+…+X6=10X1+X2+…+X6=10。假设骰子是公平的,则每个面的概率是相等的,即 p1=p2=…=p6=16p1=p2=…=p6=61。这时多项分布可以描述各个面出现次数的概率分布。

我们可以使用numpy随机选择函数模拟这样的分布。例如,从加载骰子分布中抽取100个样本:

 loaded_dice_probs = [1/6, 1/4, 1/4, 1/6, 1/12, 1/12]
 dice_faces = [1, 2, 3, 4, 5, 6]
 n_try = 100
 # Sample the distribution
 sampled_loaded_dice = np.random.multinomial(n_try, loaded_dice_probs)
 sampled_loaded_dice
 #--> array([17, 26, 21, 18,  8, 10])

关于多项分布,另一个需要了解的重要的东西是概率质量函数。概率质量函数给出了从离散分布中观察到特定结果的概率。投掷100次,得到64次正面36次反面的概率为:

其实就是二项式定理。对于一个多项式定理,我们得到了多项式概率(p_1,…,p_n)和总尝试次数N=x_1+…+x_n的广义表达式:

假设有一个装好的骰子,我们想计算这个骰子的分布是(1/6,1/4,1/4,1/6,1/12,1/12)的概率。掷骰子100次,得到x1=12面1,x2=15面2,然后我们可以计算观察到这样一个结果的概率:

这个示例展示了如何在给定相关概率(所有pi)的情况下计算观察给定结果(所有xi)的概率。这很重要,因为它将有助于计算给定样本X=(x1,…,xn)属于分类问题中可能的多项分布p=(p1,…,pn)的概率。

分类问题

高斯朴素贝叶斯和多项是朴素贝叶斯实际上在原理上非常接近,主要是对潜在特征分布的假设不同:我们假设每个类别的每个特征都遵循高斯分布,而不是假设它们遵循多项分布。

与高斯方法相比,在学习过程中估计分布参数的方式不同,在预测过程中使用分布参数的方式也不同。但总的来说,过程是相似的。以下是重要的步骤:

贝叶斯定理允许我们计算样本属于给定类别y的概率。创建一个空分类器,计算新样本属于所有类的概率,并返回概率最大的类。为了能够计算贝叶斯方程的概率,我们丢弃分母p(x),因为在比较每个类时它并不重要。然后需要使用假设所有特征都遵循多项分布来简化可能性项,对于每个类(朴素独立性实际上是内置在多项分布中的)。然后使用多项分布的概率质量函数来计算给定样本属于一类的概率。

这样就可以来拟合我们的模型,通过学习每一类的多项分布参数。一旦模型拟合就可以使用pmf来计算贝叶斯定理给出的最终概率,并返回最高概率类。

对于上面说的计算贝叶斯方程的概率

其中p(y_i)是任何样本属于类y_i的概率,这是由数据集中每个类的比例给出的——p(x|y_i)是一个样本等于x的概率,假设它属于类y_i:这正是PMF给我们的,或者说样本x属于y_i类的概率为:

式中p_1i为类i与特征1相关的多项概率。

就像我们从贝叶斯方程中去掉分母一样,我们也可以去掉PMF的前导分数,因为它也只取决于x而不是类,所以最终得到:

这意味着我们只需要估计每个类的多项概率,就能够计算一个样本属于任何类的概率。并且不需要像高斯方法那样使用链式法则和独立性假设。用独立概率项的乘积来表示它的另一种方法是:

与类先验(p(yi))成正比乘以p(xj|yi)的所有j的乘积,这是在给定样本属于类yi的情况下,观察到特征j的xj结果的概率。

使用平滑技巧估计多项参数

我们已经知道了如何计算一个给定样本属于一类yi的概率,现在需要估计多项概率参数,包括正分布和负分布。

我们将使用数据集的一部分,即“训练集”来训练我们的模型,以便它“学习”那些多项参数。这一部分解释了它是如何在数字上实现的。

第一步也是最简单的一步是计算类先验,即观察到类yi的概率(与样本x无关),这是通过计算训练集中每个类的比例来完成的。

下一步是计算多项参数(对于pos和负数都是pj)。每个类都是独立于其他类处理的。对于每个类,X训练集对所有样本求和,因此我们计算一个“特征计数”向量:这个向量分布是真实底层分布的映射。然后将这些特征计数的向量转换为多项式分布参数的“有效”向量,将该向量除以总和。

但是,如果一个类从未出现在类中,比如单词“atrocious”从未出现在训练集的正部分,该怎么办?那么,正类的相关概率θ_atrocious将为0(分子为0),这将导致该样本属于正类的总体概率也为0:

在学习过程中从未出现过“atrocious”这个词这一事实意味着,无论新样本的内容如何,任何新样本属于正类的概率都为0。或者说我们不能允许任何一类的多项式分布概率参数为0;否则,该类的总贝叶斯概率总是0。

为了避免这种情况,我们使用了“平滑技巧”,即在估计概率参数时在分子和分母上都添加一个α项。这样,即使一个特征(一个词)在所有样本中都不存在,估计的学习概率也不会为0:

现在我们知道如何正确估计多项概率参数,可以继续预测新样本的类别。

在对数空间计算预测,避免数值下溢

现在我们有了计算每个样本属于任何类的概率所需的所有值,我们可以代入数字并执行计算来预测该类。

假设输入数据集包含1000或10000列(想想词表中的所有单词),其中许多单词非常稀疏地出现,使得它们的概率非常小。这将如何转化为给定类别y的总概率的计算:

其中x_j是样本x在第j列的值,p_j是该类的多项分布参数j的概率。

让我们通过创建一个包含300个样本、10000个特征列的数据集来模拟这一点,其值在1到50之间。在文本上下文中,这相当于300个文档,词汇表为100000个单词,其中每个文档中的每个单词出现1到50次。

 import numpy as np
 J = 10000
 nsamples = 300
 X = np.random.choice(np.arange(1, 50), size=(nsamples,J)) 
 # split into train and test (test has only 1 sample)
 X_train, X_test = X[:-1], X[-1]
 # estimate the distribution probabilities
 feature_probs = X_train.sum(axis=0)/ X_train.sum()
 print(feature_probs)
 # [9.53780825e-05 1.05477725e-04 1.03631698e-04 … 1.07925718e-04
 # 1.09517582e-04 9.51506733e-05]

相应的概率是1e-4的数量级,这个数量级很小,计算机可以很好的处理这样的数字,所以现在没有问题。但是当计算样本属于一个类时,问题就出现了,这个概率如上所示,通过取所有p_j^{x_j}的乘积得到,其中p_j是单词j的估计概率,x_j是单词j在测试样本中出现的次数。我们得到:

 # compute the probability for the test sample
 print(feature_probs ** X_test)
 print(np.prod(feature_probs ** X_test))
 [1.37037886e-169 2.34731879e-064 5.34752484e-188 ... 1.84077019e-032
  1.72545280e-024 4.29538125e-069]
 0.0

乘积的单个项在1e-24和1e-188之间,这是非常非常(非常!)小的数值,已经难以处理的数量级了。计算这些数字的整体乘积肯定会低于计算机可以处理的范围,我们最终得到Python识别为0的结果。换句话说,从一个不含0的乘积得到0这是不对的。

这个问题被称为数值下溢,其中变量值非常接近于0,以至于我们失去了它们之间的精度和相对顺序。

为了避免这种下溢问题,我们需要在“对数空间”中进行所有计算,因为小值的对数只是一个负值,但并不小(不那么接近0)。一般的想法是取我们数量的对数,因为对数函数提供了有用的性质,我们甚至可以重写公式:

样本x属于y类的概率是

这样就从一个非常小的值的乘积,变成了一个(常规)负值的加权和。这仅仅是因为log是单调的。下图总结了在对数空间中预测新样本类别的计算过程:

Python示例

让我们首先使用已知分布创建一个单词的示例数据集。然后使用多项式朴素贝叶斯创建一个文本分类器。

我们使用词袋方法对单词进行特征提取,特征表示每个单词在评论中出现的次数。然后生成2个多项分布:

 import numpy as np
 import pandas as pd
 import matplotlib.pyplot as plt
 import seaborn as sns
 from sklearn.feature_extraction.text import CountVectorizer
 from sklearn.model_selection import train_test_split
 from sklearn.naive_bayes import MultinomialNB
 
 # Define the vocabulary
 vocabulary = ['good', 'bad', 'excellent', 'poor', 'great', 'terrible', 'awesome', 'awful', 'fantastic', 'horrible']
 # here the learned vocabulary is set from the begining
 # it is usually created with the dataset but for this we assume it is limited to this list
 
 # Define probabilities for positive distribution
 # note that probabilities for "bad" words are not 0, so they might appear in positive docs, and vice versa
 # also, normalize probabilities to sum to 
 positive_probs = np.array([0.3, 0.1, 0.5, 0.1, 0.4, 0.1, 0.6, 0.1, 0.5, 0.1])
 negative_probs = np.array([0.1, 0.3, 0.1, 0.5, 0.1, 0.4, 0.1, 0.6, 0.1, 0.5])
 positive_probs /= positive_probs.sum()
 negative_probs /= negative_probs.sum()
 
 # Let's plot each distribution
 df = pd.DataFrame({'neg': negative_probs, 'pos': positive_probs},index=vocabulary)
 df_melted = df.reset_index(names='word').melt(id_vars='word', value_vars=['pos', 'neg'], var_name="class", value_name="prob.")
 g = sns.catplot(df_melted, y="prob.", hue="class", x='word', kind='bar')
 g.ax.set_xticklabels(g.ax.get_xticklabels(), rotation=90, ha='center', va='top')
 g.ax.set_title('True distrbutions')

我们只创建了两个多项式分布。使用它们并对它们进行采样以创建具有已知类的实际数据集。

 # Generate random documents for each class
 # create 1000 positive reviews and 1000 negative reviews : our dataset is balanced
 # the length (=number of words=sum of each row) may vary between 5 and 15 words)
 # note that the vocabulary of each review (=number of distinct word) may be different
 n_samples = 1000
 positive_docs = [' '.join(np.random.choice(vocabulary, size=np.random.randint(5, 15), p=positive_probs)) for _ in range(n_samples)]
 negative_docs = [' '.join(np.random.choice(vocabulary, size=np.random.randint(5, 15), p=negative_probs)) for _ in range(n_samples)]
 
 # Create labels
 labels_positive = np.ones(n_samples, dtype=int)
 labels_negative = np.zeros(n_samples, dtype=int)
 
 # Combine documents and labels
 documents = np.concatenate([positive_docs, negative_docs])
 labels = np.concatenate([labels_positive, labels_negative])
 
 plt.figure()
 sns.heatmap(CountVectorizer(vocabulary=vocabulary).fit_transform(documents).toarray(), xticklabels=vocabulary, cbar_kws={'label':'word count'})#, cmap="copper")

生成了2000个样本,其中1000个样本来自正多项式分布,1000个样本来自负多项式分布。词表使用scikit-learn的CountVectorizer(本质上相当于标准的collections.Counter)转换为数值矩阵。这样我们就有一个输入数据集X和相应的目标类向量y。

我们可以首先手动估计分布参数,就像scikit-learn中fit所做的那样。scikit-learn实际上是在“对数空间”中工作的,而概率并不是可用的。我们可以简单地使用theta = (classifier.feature_count_)来计算学习到的概率。T / classifier. feature_count_sum (axis=1)).T。

 X_train, X_test, y_train, y_test = train_test_split(documents, labels, test_size=0.2, random_state=42, shuffle=True)
 
 # Create a CountVectorizer to convert documents into a matrix of token counts
 vectorizer = CountVectorizer(vocabulary=vocabulary)
 
 # Fit and transform the training data
 X_train_counts = vectorizer.fit_transform(X_train)
 
 # Train a multinomial naive Bayes classifier
 classifier = MultinomialNB(alpha=0)  # notice I use alpha=0 here because I control the dataset and know there are no "empty" feature
 classifier.fit(X_train_counts, y_train)
 for class_, count_, feature_count_ in zip(classifier.classes_, classifier.class_count_, classifier.feature_count_):
     print("For class", class_, "there were ", count_, "instance in the dataset. For those samples, the total counts for each word is", feature_count_)
 
 # estimate distribution parametsers ourselves from scikit-learn stored attributes
 thetas = (classifier.feature_count_.T / classifier.feature_count_.sum(axis=1)).T
 print(thetas)
 # sort by class
 X_train_pos = X_train_counts[y_train==0]
 X_train_neg = X_train_counts[y_train==1]
 print(X_train_pos.sum(axis=0)/X_train_pos.sum(), X_train_neg.sum(axis=0)/X_train_neg.sum())
 
 df = pd.DataFrame({'neg': thetas[0], 'pos': thetas[1]}, index=vocabulary)
 df_melted = df.reset_index(names='word').melt(id_vars='word', value_vars=['pos', 'neg'], var_name="class", value_name="prob.")
 g = sns.catplot(df_melted, y="prob.", hue="class", x='word', kind='bar')
 g.ax.set_xticklabels(g.ax.get_xticklabels(), rotation=90, ha='center', va='top')
 g.ax.set_title('Learned distrbutions')

结果如下

 For class 0 there were  799.0 instance in the dataset. For those samples, the total counts for each word is [ 258.  815.  256. 1274.  294. 1134.  296. 1618.  264. 1402.]
 For class 1 there were  801.0 instance in the dataset. For those samples, the total counts for each word is [ 827.  277. 1306.  281. 1121.  293. 1618.  228. 1344.  244.]
 [[0.03389831 0.10708186 0.03363553 0.1673893  0.0386283  0.14899488
   0.03889108 0.21258705 0.03468664 0.18420707]
  [0.10969625 0.03674227 0.17323252 0.03727285 0.14869346 0.03886457
   0.21461732 0.03024274 0.17827298 0.03236504]]
 [[0.03389831 0.10708186 0.03363553 0.1673893  0.0386283  0.14899488
   0.03889108 0.21258705 0.03468664 0.18420707]] 
 [[0.10969625 0.03674227 0.17323252 0.03727285 0.14869346 0.03886457
   0.21461732 0.03024274 0.17827298 0.03236504]]

由于我们的训练集包含大量样本,因此学习到的分布非常接近用于生成它们的真实分布。

理解多项式分类在这里是如何工作的一种方法是比较候选类沿样本分布的分布。分类器返回与样本分布最相似的类:

 x_new = vectorizer.transform(X_test)[0].toarray()[0]
 x_normed = x_new / x_new.sum()
 
 df = pd.DataFrame({'neg': thetas[1], 'pos': thetas[0], 'new':x_normed}, index=vocabulary)
 df_melted = df.reset_index(names='word').melt(id_vars='word', value_vars=['pos', 'new', 'neg'], var_name="class", value_name='prob.')
 g = sns.catplot(df_melted, y="prob.", hue="class", x='word', kind='bar')
 g.ax.set_xticklabels(g.ax.get_xticklabels(), rotation=90, ha='center', va='top')
 g.ax.set_title('Learned distrbutions along with new sample to predict')

对于这个样本,我们可以直观地预测为正。但是让我们使用scikit-learn模型提供一个基于数字的决策:

 classifier.predict([x_new])
 #--> array([0])

我们还可以检查并尝试在对数空间中手动重现模型所做的计算。当你在模型上使用.predict_proba时,它只是取log-probs的指数:

 x_new = [vectorizer.transform(X_test)[0].toarray()[0]]
 
 # class log prior
 print(classifier.class_log_prior_)
 print(np.log(classifier.class_count_/classifier.class_count_.sum()))
 
 # feature log 
 print(classifier.feature_log_prob_)
 print(np.log(classifier.feature_count_.T / classifier.feature_count_.sum(axis=1)).T)
 
 # final log  likelihood
 print(classifier.predict_joint_log_proba(x_new))
 jll = np.dot(x_new, np.log(classifier.feature_count_.T / classifier.feature_count_.sum(axis=1))) + np.log(classifier.class_count_/classifier.class_count_.sum())
 print(jll)
 
 # log prob.
 print(classifier.predict_log_proba(x_new))
 from scipy.special import logsumexp
 log_prob_x = logsumexp(jll, axis=1) 
 print(jll - np.atleast_2d(log_prob_x).T)
 # last 3 lines are equivalent to normalizing the sum of probability in 'not-log-space': x_ = x_ / x_.sum()
 
 # final prob
 print(classifier.predict_proba(x_new))
 print(np.exp(jll - np.atleast_2d(log_prob_x).T))

结果如下:

 [-0.69439796 -0.69189796]
 [-0.69439796 -0.69189796]
 [[-3.38439026 -2.23416174 -3.3921724  -1.78743301 -3.25377008 -1.90384336
   -3.24699039 -1.54840375 -3.36140075 -1.69169478]
  [-2.21004013 -3.30382732 -1.75312052 -3.28949016 -1.9058684  -3.24767222
   -1.53889873 -3.4984992  -1.72443931 -3.4306766 ]]
 [[-3.38439026 -2.23416174 -3.3921724  -1.78743301 -3.25377008 -1.90384336
   -3.24699039 -1.54840375 -3.36140075 -1.69169478]
  [-2.21004013 -3.30382732 -1.75312052 -3.28949016 -1.9058684  -3.24767222
   -1.53889873 -3.4984992  -1.72443931 -3.4306766 ]]
 [[-16.67116009 -20.94229983]]
 [[-16.67116009 -20.94229983]]
 [[-0.01386923 -4.28500897]]
 [[-0.01386923 -4.28500897]]
 [[0.9862265 0.0137735]]
 [[0.9862265 0.0137735]]

这里我们使用alpha=0可以轻松地手工重现计算,但由于这是一个超参数,因此可能需要对其进行调优。

总结

多项分布是一种重要的概率分布,适用于描述多类别、多次试验的情况,是概率论和统计学中的基础之一。它表示实验可以有N个不同的输出,重复M次。可以把它看作投掷硬币的二项分布的概括,就像反复计算掷骰子的每面一样。多项式朴素贝叶斯分类器的总体思想与高斯朴素贝叶斯分类器非常相似,只是在拟合和预测计算上有所不同。为了学习每个类别的多项概率参数,可以简单地将训练集沿特征求和,并将结果除以该向量的和。这提供了对概率的估计。使用一个平滑的技巧可以处理在训练中未出现的特征。为了预测新样本的类别,则需要使用多项分布的概率质量函数,并在“对数空间”中计算所有概率,以避免下溢和计算机无法处理的小数字。

多项分布在实际中有广泛的应用,特别是在以下领域:

  • 自然语言处理中的文本分类、主题建模等。
  • 生物统计学中的多样性指数的计算。
  • 计数数据的建模,如调查数据、市场调查等。
  • 假设检验,用于检验多类别随机变量的比例是否满足某种期望。

https://avoid.overfit.cn/post/1fb34d655cdb4dcda077b75042256c45

作者:Yoann Mocquin

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

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

相关文章

2024 年 6 款最佳 SD 卡恢复软件

“有没有最好的 SD 卡恢复软件可以推荐给我来恢复 SD 卡上丢失的数据?程序太多了。我很难选择合适的存储卡数据恢复软件。” 有一天,我的朋友让我向他推荐最好的SD卡数据恢复软件,因为他在网上搜索,发现有很多选择,而…

JS13-事件的绑定和事件对象Event

绑定事件的两种方式/DOM事件的级别 DOM0的写法&#xff1a;onclick element.onclick function () {}举例&#xff1a; <body> <button>点我</button> <script>var btn document.getElementsByTagName("button")[0];//这种事件绑定的方式…

关于汽车中网改装需要报备吗?(第二天)

车联网改造需要申报吗&#xff1f; 今天2022年10月20日&#xff0c;小编就给大家介绍一下车联网改装是否需要申报的相关知识。 让我们来看看。 汽车格栅改装无需申报。 这种年检可以直接通过。 您不必担心&#xff0c;因为汽车格栅对于实车的外观来说并不陌生&#xff0c;因此…

Docker常用命令!!!

一、docker基础命令 1、启动docker systemctl start docker 2、关闭docker systemctl stop docker 3、重启docker systemctl restart docker 4、docker设置随服务启动而自启动 systemctl enable docker 5、查看docker 运行状态 systemctl status docker 6、查看docker 版本号信…

eth 套利案例五

交易hash : 0xb69981d437af7b9b705b3eb459df89d69901b5aff1cf2f99673372c873d50daf 时间&#xff1a; 2024.02.24 获利&#xff1a; 9699刀 交易流程&#xff1a; 292376226817040592 2940802860 先贷出230个weth, 然后再换成eth 再换成 2940802860 个kekec, 然后再用 29237…

# Django通过开关控制数据库参数(JS版)

目录 场景初始的视图层HTML部分JS代码视图层接受部分 场景 此时我的表单中有一排开关 数据库有一排状态 需求是要当开关开启时数据库state为1&#xff0c;关闭时为0 初始的视图层 将整个adv数据表返回给前端HTML def adv(request):adv_list Adv.objects.all()return rende…

C++项目 -- 负载均衡OJ(一)compile_server

C项目 – 负载均衡OJ&#xff08;二&#xff09;compile_server 文章目录 C项目 -- 负载均衡OJ&#xff08;二&#xff09;compile_server一、compile_server设计1.总体服务流程 二、compiler.hpp三、runner.hpp四、compile_run.hpp五、compile_server.cc5.1.编译功能调试&…

【记录搭建elk 如何在linux共享文件】

『如何在linux共享文件 &#xff0c;搭建elk直接看第二部分』 新增用户a b c adduser a adduser b adduser c新增用户组 A groupadd developteam将用户a b c 加入 组 usermod -a -G developteam hadoop usermod -a -G developteam hbase usermod -a -G developteam hive设置um…

拷贝他人maven仓库jar包到自己本地仓库,加载maven依然提示无法下载对应依赖

所遇问题&#xff1a; 拷贝他人maven仓库jar包到自己本地maven仓库repository下的对应依赖位置&#xff0c;重新加载idea的maven依然提示无法下载对应依赖。 解决办法&#xff1a; 在maven->repository找到对应报错依赖路径&#xff0c;删除xxx.repositories 和 xxx.lastU…

蓝桥杯算法心得——附近最小(优先队列+滑动窗口)

大家好&#xff0c;我是晴天学长&#xff0c;这题可以用贪心优先队列和滑动窗口来写&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .附近最小 问题描述 小蓝有—个序列a[1], a[2],...,a[n]。 给定—个…

【MySQL】7. 基本查询(create / retrieve)

表的增查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 1. Create 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)] VALUES (value_list) [, (value_list)] ...value_list: value, […

【办公类-16-07-07】“2023下学期 大班户外游戏2(有场地和无场地版,每天不同场地)”(python 排班表系列)

作品展示 背景需求&#xff1a; 2024年2月教务组发放的是“每周五天内容相同&#xff0c;两周10天内容相同”的户外游戏安排 【办公类-16-07-05】合并版“2023下学期 大班户外游戏&#xff08;有场地和无场地版&#xff0c;两周一次&#xff09;”&#xff08;python 排班表系…

探秘国内ip切换手机软件,全是干货,火速Get!

随着互联网的普及和深入&#xff0c;人们在网络空间中的活动也变得越来越频繁。然而&#xff0c;在享受网络便利的同时&#xff0c;个人隐私保护和数据安全问题愈发突出。国内IP切换手机软件因其功能多样、易用性强大而备受关注。这类软件可以帮助用户切换IP地址&#xff0c;隐…

百度智能云+SpringBoot=AI对话【人工智能】

百度智能云SpringBootAI对话【人工智能】 前言版权推荐百度智能云SpringBootAI对话【人工智能】效果演示登录AI对话 项目结构后端开发pom和propertiessql_table和entitydao和mapperservice和implconfig和utilLoginController和ChatController 前端开发css和jslogin.html和chat.…

Java newInstance方法学习

用newInstance与用new是有区别的&#xff0c;区别在于创建对象的方式不一样&#xff0c;前者是使用类加载机制&#xff1b; newInstance方法要求该 Class 对应类有无参构造方法&#xff1b; 执行 newInstance()方法实际上就是使用对应类的无参构造方法来创建该类的实例&#x…

【prometheus-operator】k8s监控集群外redis

1、部署exporter GitHub - oliver006/redis_exporter: Prometheus Exporter for Redis Metrics. Supports Redis 2.x, 3.x, 4.x, 5.x, 6.x, and 7.x redis_exporter-v1.57.0.linux-386.tar.gz # 解压 tar -zxvf redis_exporter-v1.57.0.linux-386.tar.gz # 启动 nohup ./redi…

流畅的 Python 第二版(GPT 重译)(三)

第五章&#xff1a;数据类构建器 数据类就像孩子一样。它们作为一个起点是可以的&#xff0c;但要作为一个成熟的对象参与&#xff0c;它们需要承担一些责任。 马丁福勒和肯特贝克 Python 提供了几种构建简单类的方法&#xff0c;这些类只是一组字段&#xff0c;几乎没有额外功…

软件管理rpm与yum

源代码包下载 Compare, Download & Develop Open Source & Business Software - SourceForgehttps://sourceforge.net/ rpm包下载 Welcome to the RPM repository on fr2.rpmfind.nethttp://rpmfind.net/linux/RPM/ 软件包管理 1.rpm包管理: 1)查询: 安装…

蓝桥杯Python B组练习——完美的代价

一、题目 问题描述   回文串&#xff0c;是一种特殊的字符串&#xff0c;它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串&#xff0c;它不一定是回文的&#xff0c;请你计算最少的交换次数使得该串变成一个完美的回文串。   交换的定义是…

计算机网络相关

OSI七层模型 各层功能&#xff1a; TCP/IP四层模型 应用层 传输层 网络层 网络接口层 访问一个URL的全过程 在浏览器中输入指定网页的 URL。 浏览器通过 DNS 协议&#xff0c;获取域名对应的 IP 地址。 浏览器根据 IP 地址和端口号&#xff0c;向目标服务器发起一个 TCP…