NLP从零开始------12. 关于前十一章补充(英文分词)

        相较于基础篇章,这一部分相较于基础篇减少了很多算法推导,多了很多代码实现。

1.英文词规范化

        英文词规范化一般分为标准化缩写,大小写相互转化,动词目态转化等。

1.1 大小写折叠

        大小写折叠( casefolding) 是将所有的英文大写字母转化成小写字母的过程。在搜索场景中, 用户往往喜欢使用小写字母形式,而在计算机中, 大写字母和小写字母并非同一字符,当遇到用户想要搜索一些人名、地名等带有大写字母的专有名词的情况下,若不将小写字母转换成大写, 可能难以匹配正确的搜索结果。示例代码:

# 待处理的句子
sentence = "Let's study Hands-on-NLP"# 将句子中的所有字符转换为小写
lowercase_sentence = sentence.lower()# 打印转换后的句子
print(lowercase_sentence)

        结果:

D:\ana\envs\nlp\python.exe D:\pythoncode\nlp\main.py 
let's study hands-on-nlp进程已结束,退出代码为 0

1.2 词目还原

       在诸如英文这样的语言中,很多单词都会根据不同的主语、语境、时态等情形修改为相应的形态,而这些单词本身表达的含义是接近甚至相同的, 例如英文中的 am、 is、are都可以还原成 be,英文名词 cat根据不同情形有 cat、 cats、 cat's、 cats'等多种形态。这些形态对文本的语义影响相对较小,但是大幅提高了词表的大小, 因而提高了自然语言处理模型的构建成本。因此在有些文本处理问题上,需要将所有的词进行词目还原( lemmatization), 即找出词的原型。人类在学习这些语言的过程中,可以通过词典查找词的原型; 类似地,计算机可以通过构建词典来进行词目还原:

# 构建词典
lemma_dict = {'am': 'be','is': 'be','are': 'be','cats': 'cat',"cats'": 'cat',"cat's": 'cat','dogs': 'dog',"dogs'": 'dog',"dog's": 'dog','chasing': 'chase'
}# 待处理的句子
sentence = "Two dogs are chasing three cats"# 将句子分割成单词列表
words = sentence.split()# 打印原始单词列表
print(f'词目还原前: {words}')# 初始化词目还原后的单词列表
lemmatized_words = []# 遍历单词列表,进行词目还原
for word in words:if word in lemma_dict:lemmatized_words.append(lemma_dict[word])else:lemmatized_words.append(word)# 打印词目还原后的单词列表
print(f'词目还原后: {lemmatized_words}')

        代码结果如下:
 

词目还原前: [' Two', ' dogs', ' are', ' chasing', ' three', ' cats']
词目还原后: [' Two', ' dog', ' be', ' chase', ' three', ' cat']

        另外,也可以利用NLTK 自带的词典来进行词目还原:
 

import nltk
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet# 下载分词包和wordnet包
nltk.download('punkt', quiet=True)
nltk.download('wordnet', quiet=True)# 创建词形还原器实例
lemmatizer = WordNetLemmatizer()# 待处理的句子
sentence = "Two dogs are chasing three cats"# 使用nltk的分词器对句子进行分词
words = word_tokenize(sentence)# 打印原始单词列表
print(f'词目还原前: {words}')# 词形还原后的单词列表
lemmatized_words = []# 遍历单词列表,进行词形还原
for word in words:# 词形还原时需要确定词性,这里暂时使用名词(NOUN)作为示例lemmatized_words.append(lemmatizer.lemmatize(word, pos=wordnet.NOUN))# 打印词形还原后的单词列表
print(f'词目还原后: {lemmatized_words}')

        代码结果如下:
 

D:\ana\envs\nlp\python.exe D:\pythoncode\nlp\cihuanyuan2.py 
[nltk_data] Error loading punkt: <urlopen error [Errno 11004]
[nltk_data]     getaddrinfo failed>
[nltk_data] Error loading wordnet: <urlopen error [Errno 11004]
[nltk_data]     getaddrinfo failed>
词目还原前: ['Two', 'dogs', 'are', 'chasing', 'three', 'cats']
词目还原后: ['Two', 'dog', 'are', 'chasing', 'three', 'cat']进程已结束,退出代码为 0

        更精确的词目还原基于语素分析( morphological parsing)。在语言学中, 语素( morpheme)是语言中最小的有意义或有语法功能的单位。以中文为例,“动”“手”和“学”这3个语素就组合成了“动手学”这个词。在英文中, 情况会有些不一样, 英文中的很多单词是由词干( stem)和词缀( affix) 组成的。词干是表达主要含义的语素, 而词缀一般和词干连接,表达了附加的含义。例如 unbelievable这个词,由“ un”(词缀, 表示否定)、“ believ”(表示 believe,词干,表示相信)和“ able”(词缀, 表示可能的) 组成,三者合起来的意思是“不可置信的”。想要准确地抽取出词的词根和词干,就需要使用语素分析。

1.3 词干还原

        词干还原( stemming)是将词变成词干的过程。词干还原是一种简单快速的词目还原的方式, 通过将所有的词缀直接移除来获取词干。为了保持词干的完整性, 波特词干还原器提出了一套基于改写规则的方法来进行词干还原。例如:
                        · TIONAL -> TION (如(conditional->condition);
                        · IZATION->IZE (如(organization>organize);
                        · SSES ->SS(如(classes→class)。
        读者如果对这部分有兴趣的话,可以查阅NLTK 中对词干还原相关的描述。

2. 聚类模型分享

2.1 无监督的朴素贝叶斯模型

        朴素贝叶斯模型假设一个文档中的所有词都是在给定文档标签的条件下独立同分布地通过一个离散分布生成。朴素贝叶斯模型定义文档x_{i}的概率如下:
                        P(x_{i})= \sum \limits _{k=1}^{K} \pi _{k}P(x_{i}| \psi _{k})= \sum \limits _{k=1}^{K} \pi _{k} \prod \limits _{j=1}^{w_{i}}Multi(x_{i,j}| \psi k)
        其中, πₖ是第k个簇的混合系数, ψₖ是第k个簇的离散分布(记为 Multi)的参数,表示为\pi_{k} \psi_{k} = (p_{k,1}, p_{k,2}, \ldots, p_{k,\nu}),v为词表大小。w_{i}为当前文档x_{i}的长度,x_{i,j}表示文档x_{i}中的第j个词。

    将朴素贝叶斯模型用于文本分类时,文档标签是包含在数据中的, 因此可以进行监督学习。但在聚类任务中, 文档标签(即文档所属的簇)是未知的。因此, 与高斯混合模型的学习类似,我们需要同时学习朴素贝叶斯模型的参数和文档标签。常见的学习目标依然是最大化所有文档的概率,优化方法同样是最大期望值算法, 即随机初始化所有参数, 然后交替运行E步骤和M步骤直到模型收敛。
        1. E步骤
        计算每个文档的标签分布,将文档基于该分布部分地分配给各个标签:
                     P(y_{i}=k|x_{i}, \theta ^{(t)}) \propto \pi _{k}^{(t)} \prod \limits _{j=1}^{w_{i}}Multi(x_{i,j}| \psi _{k}^{(t)})
        其中, 上标(t)用于标示迭代次数, \theta^{t}为第t次迭代中的模型参数。
        2. M步骤
        根据每个标签被分配到的数据点进行加权最大似然估计,更新该标签对应的参数。首先,更新离散分布中每个词l的概率p_{k,l}^{(t+1)}:
                                ​​​​​​​        ​​​​​​​p_{k,l}^{(t+1)}= \frac { \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)}) \sum \limits _{j} \hbar (x_{i,j}=l)}{ \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})w_{i'}}
        其中, 1()在括号内等式成立时为1,否则为0。这个公式的分子计算的是加权分配到第k个标签的所有文档中出现词1的加权总次数,分母计算的是加权分配到第k个标签的所有文档的总词数。其次, 还需要更新每个标签的混合系数\pi _{k}^{(t+1)},更新公式与5.2节基于高斯混合模型的最大期望值算法的M步骤对应公式完全相同:
                ​​        ​​​​​       ​​​​​​​        ​​     ​     ​​​​​​​\pi _{k}^{(t+1)}= \frac { \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})}{m}
        其中, m为文档x的总个数。

        算法代码演示:

from scipy.special import logsumexp# 无监督朴素贝叶斯
class UnsupervisedNaiveBayes:def __init__(self, K, dim, max_iter=100):self.K = Kself.dim = dimself.max_iter = max_iter# 初始化参数,pi为先验概率分布,P用于保存K个朴素贝叶斯模型的参数self.pi = np.ones(K) / Kself.P = np.random.random((K, dim))self.P /= self.P.sum(axis=1, keepdims=True)# E步骤def E_step(self, X):# 根据朴素贝叶斯公式,计算每个数据点分配到每个簇的概率分布for i, x in enumerate(X):# 由于朴素贝叶斯使用了许多概率连乘,容易导致精度溢出,# 因此使用对数概率self.Y[i, :] = np.log(self.pi) + (np.log(self.P) *\x).sum(axis=1)# 使用对数概率、logsumexp和exp,等价于直接计算概率,# 好处是数值更加稳定self.Y[i, :] -= logsumexp(self.Y[i, :])self.Y[i, :] = np.exp(self.Y[i, :])# M步骤def M_step(self, X):# 根据估计的簇概率分布更新先验概率分布self.pi = self.Y.sum(axis=0) / self.Nself.pi /= self.pi.sum()# 更新每个朴素贝叶斯模型的参数for i in range(self.K):self.P[i] = (self.Y[:, i:i+1] * X).sum(axis=0) / \(self.Y[:, i] * X.sum(axis=1)).sum()# 防止除0self.P += 1e-10self.P /= self.P.sum(axis=1, keepdims=True)# 计算对数似然,用于判断迭代终止def log_likelihood(self, X):ll = 0for x in X:# 使用对数概率和logsumexp防止精度溢出logp = []for i in range(self.K):logp.append(np.log(self.pi[i]) + (np.log(self.P[i]) *\x).sum())ll += logsumexp(logp)return ll / len(X)# 无监督朴素贝叶斯的迭代循环def fit(self, X):self.N = len(X)self.Y = np.zeros((self.N, self.K))ll = self.log_likelihood(X)print(f'初始化log-likelihood = {ll:.4f}')print('开始迭代')for i in range(self.max_iter):self.E_step(X)self.M_step(X)new_ll = self.log_likelihood(X)print(f'第{i}步, log-likelihood = {new_ll:.4f}')if new_ll - ll < 1e-4:print('log-likelihood不再变化,退出程序')breakelse:ll = new_lldef transform(self, X):assert hasattr(self, 'Y') and len(self.Y) == len(X)return np.argmax(self.Y, axis=1)def fit_transform(self, X):self.fit(X)return self.transform(X)

2.2基于高斯混合模型的最大期望值算法

        这里首先介绍高斯混合模型,然后介绍用于无监督学习高斯混合模型的最大期望值算法。

2.2.1 高斯混合模型

        相比于将每个数据点确定性地分类到一个簇中,给出每个数据点归属于每个簇的概率分布会更好地体现数据点和簇之间的关系。这里使用高斯混合模型来建模这个概率分布。顾名思义,高斯混合是指多个高斯分布(即正态分布) 函数的组合, 它的概率密度函数如下:
        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        P(x)= \sum \limits _{k=1}^{K} \pi _{k} \mathcal V(x| \mu _{k}, \sum \limits k)
        其中, πₖ是混合系数, 满足\pi _{k} \ge 0, \sum \limits _{k=1}^{K} \pi _{k}=1。也就是说, πₖ表示一个离散分布。N(x|μₖ,∑ₖ)是第k个高斯函数,其中μₖ为均值,维度与数据点x的维度一样,记作d, ∑为协方差矩阵,维度为d×d。N (x|μₖ,∑k)的具体概率密度函数为
        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        \mathcal M(x| \mu k,E_{k})= \frac { \exp (- \frac {1}{2}(x- \mu k)^{ \tau } \sum \limits ^{-1}(x- \mu k))}{ \sqrt {(2 \pi )^{d}| \sum \limits |}}
        其中, |∑|为协方差矩阵∑的行列式。
        高斯混合也可以理解为一个生成式模型, 通过两个步骤生成数据点x。令变量y表示数据点x的标签,即x是从哪一个高斯函数采样得到的。第一步, 根据概率分布πₖ采样,令y=k; 第二步, 根据高斯分布. N(x|μₖ,∑ₖ)生成数据点。不难发现, 通过这个过程生成数据点x的概率密度函数即是前面定义的高斯混合。

        在高斯混合用于聚类时, 每个高斯函数对应一个簇, 而每个数据点的标签则表示该数据点属于哪一个簇。在文本聚类这样的无监 贝叶斯网络督任务中,我们既不知道高斯混合的参数(即混合系数πₖ、均值μₖ和协方差∑ₖ),也不知道每个数据点的标签,因此需要同时学习这两者。常见的学习目标为最大化所有数据点的边际概率:
        ​​​​​​​        ​​​​​​​        \prod \limits _{i=1}^{N}P(x_{i})= \prod \limits _{i=1}^{N} \sum \limits _{k=1}^{K}P(y_{i}=k,x_{i})= \prod \limits _{i=1}^{N} \sum \limits _{k=1}^{K} \pi _{k} \mathcal M(x_{i}| \mu _{k}, \sum \limits _{k})
        其中, N是数据集大小。那么如何优化这个目标函数呢? 最常见的方法是最大期望值算法。

2.2.1 最大期望值算法

        最大期望值算法首先随机初始化高斯混合模型的所有参数,然后交替运行E步骤和M步骤,直到模型收敛(常见判断标准是边际概率不再显著增加)。

        1. E步骤
        E步骤将每个数据点按照一定的权重部分地分配给不同的高斯函数。我们将这些权重定义为该数据点被分配到各个高斯函数的概率, 即该数据点的标签的概率分布:
         ​​​​​​​        ​​​​​​​        P(y_{i}=k|x_{i}, \theta ^{(t)}) \propto \pi _{k}^{(t)} \mathcal N(x_{i}| \mu _{k}^{(t)}, \sum \limits _{k}^{(t)})
        其中, 上标(t)用于标示第t次迭代时模型的参数,θ⁽ᵗ⁾为模型参数(即所有的\pi _{k}^{(t)}、 \mu _{k}^{(t)}\sum \limits _{k}^{(t)})。

        2. M步骤

        M步骤需要为每个高斯函数计算新的参数, 基本思想是根据每个高斯函数被分配到的数据点进行最大似然估计。由于每个数据点都是按一定的权重分配给每个高斯函数, 因此这里的最大似然估计也是加权的。这种加权最大似然估计存在以下闭式解:
        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​\mu _{k}^{(t+1)}= \frac { \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})x_{i}}{ \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})}
        上述公式将分配到第k个高斯函数的数据点进行加权平均。
        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​\sum \limits _{k}= \frac { \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})(x_{i}- \mu _{i}^{(t+1)})(x_{i}- \mu _{i}^{(t+1)})^{T}}{ \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})}
        上述公式将分配到第k个高斯函数的数据点计算加权的协方差矩阵。
        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        \pi _{k}^{(t+1)}= \frac { \sum \limits _{i}P(y_{i}=k|x_{i}, \theta ^{(t)})}{m}
        其中, m是数据点的总个数。上述公式计算分配到第k个高斯函数的数据点个数占所有数据点个数的比例。由于每个数据点是按权重部分地分配给每个高斯函数的,因此数据点个数的计算方式是对权重求和。
        通过E步骤和M步骤,我们就拥有了一个完整的最大期望值算法的过程。最大期望值算法具体细节不再展开,有兴趣的读者可以参考相关的机器学习教材。

2.2.3 最大期望值算法与k均值聚类算法的关联

        如果为最大期望值算法假设两个限定条件:
        (1)所有高斯模型都为球状(即协方差矩阵等比于单位矩阵),且权重和协方差均相同,只有均值是可变化的参数;
        (2)E步骤中计算的标签概率分布均为点估计,也就是说强制将每个数据点分配给单个高斯模型, 这等价于假设所有的方差均无限接近于0。
        我们就会发现, 最大期望值算法等价于k均值聚类算法。
        接下来演示如何使用高斯混合模型来进行聚类。注意,高斯混合模型会计算每个数据点归属于各个族的概率分布,这里将概率最大的族作为聚类输出。

        

from scipy.stats import multivariate_normal as gaussian
from tqdm import tqdm# 高斯混合模型
class GMM:def __init__(self, K, dim, max_iter=100):# K为聚类数目,dim为向量维度,max_iter为最大迭代次数self.K = Kself.dim = dimself.max_iter = max_iter# 初始化,pi = 1/K为先验概率,miu ~[-1,1]为高斯分布的均值,# sigma = eye为高斯分布的协方差矩阵self.pi = np.ones(K) / Kself.miu = np.random.rand(K, dim) * 2 - 1self.sigma = np.zeros((K, dim, dim))for i in range(K):self.sigma[i] = np.eye(dim)# GMM的E步骤def E_step(self, X):# 计算每个数据点被分到不同簇的密度for i in range(self.K):self.Y[:, i] = self.pi[i] * gaussian.pdf(X, \mean=self.miu[i], cov=self.sigma[i])# 对密度进行归一化,得到概率分布self.Y /= self.Y.sum(axis=1, keepdims=True)# GMM的M步骤def M_step(self, X):# 更新先验概率分布Y_sum = self.Y.sum(axis=0)self.pi = Y_sum / self.N# 更新每个簇的均值self.miu = np.matmul(self.Y.T, X) / Y_sum[:, None]# 更新每个簇的协方差矩阵for i in range(self.K):# N * 1 * Ddelta = np.expand_dims(X, axis=1) - self.miu[i]# N * D * Dsigma = np.matmul(delta.transpose(0, 2, 1), delta)# D * Dself.sigma[i] = np.matmul(sigma.transpose(1, 2, 0),\self.Y[:, i]) / Y_sum[i]# 计算对数似然,用于判断迭代终止def log_likelihood(self, X):ll = 0for x in X:p = 0for i in range(self.K):p += self.pi[i] * gaussian.pdf(x, mean=self.miu[i],\cov=self.sigma[i])ll += np.log(p)return ll / self.N# 运行GMM算法的E步骤、M步骤迭代循环def fit(self, X):self.N = len(X)self.Y = np.zeros((self.N, self.K))ll = self.log_likelihood(X)print('开始迭代')for i in range(self.max_iter):self.E_step(X)self.M_step(X)new_ll = self.log_likelihood(X)print(f'第{i}步, log-likelihood = {new_ll:.4f}')if new_ll - ll < 1e-4:print('log-likelihood不再变化,退出程序')breakelse:ll = new_ll# 根据学习到的参数将一个数据点分配到概率最大的簇def transform(self, X):assert hasattr(self, 'Y') and len(self.Y) == len(X)return np.argmax(self.Y, axis=1)def fit_transform(self, X):self.fit(X)return self.transform(X)

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

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

相关文章

stm32MX+freertos在创建task时,选项的含义

任务名称&#xff08;Task Name&#xff09;&#xff1a; 用于标识任务的名称&#xff0c;便于调试和日志记录。 优先级&#xff08;Priority&#xff09;&#xff1a; 任务的执行优先级。FreeRTOS支持多个优先级&#xff0c;高优先级的任务会优先于低优先级的任务执行。 堆栈…

ubuntu20.04源码编译安装qemu(qemu8.2)

ubuntu20.04源码安装qemu8.2 本文用于记录在ubuntu20中源码编译安装qemu8.2&#xff0c;同时也希望能够对你有所帮助。 一、download qemu 根据自己的需求下载对应版本的qemu源码压缩包。 https://github.com/qemu/qemu/tags二、build qemu 解压缩后&#xff0c;执行下述命令。…

SpringBoot百万行Excel导入MySQL实践

在公司开发时&#xff0c;客户说需要支持大数据量excel导入&#xff0c;所以打算写一篇文章记录下思路和优化过程。 一、前期准备 首先我们选用的肯定是阿里出品的EasyExcel&#xff0c;对比poi和jxl占内存更少 easyexcel官方网站准备测试的数据库和excel文件&#xff0c;已经…

-Wl,-rpath= 编译器链接器指定动态库路径 与 LD_LIBRARY_PATH

实例先行&#xff0c; 1&#xff0c;情景 三互相依赖的小项目&#xff1a; &#xff08;1&#xff09;libbottom.so&#xff0c;无特别依赖&#xff0c;除系统文件 &#xff08;2&#xff09;libtop.so&#xff0c;依赖libbottom.so &#xff08;3&#xff09;app 可执行程…

springboot admin监控

服务端搭建 maven的依赖&#xff0c;包括服务端和客户端&#xff0c;以及注册到nacos上面 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XML…

AI绘制思维导图:使用SpringBoot和Vue实现智能可视化

目录 引言&#xff1a; 思维导图的重要性和应用场景&#xff1a; AI在思维导图绘制中的应用&#xff1a; 概述SpringBoot和Vue框架的特点&#xff1a; 第一部分&#xff1a;思维导图概述 思维导图的定义和历史 思维导图的结构和组成部分 思维导图在不同领域的应用案例 …

Linux 进程 | 进程地址空间

文章目录 进程地址空间程序地址空间进程地址空间 进程地址空间 程序地址空间 地址空间一共有如下的几个区域&#xff0c;从下到上地址逐渐增加&#xff0c;其中栈区的空间是从上往下使用&#xff0c;即从高地址往低地址增长&#xff1b;堆区的空间是从下往上使用&#xff0c;…

【鸿蒙学习】HarmonyOS应用开发者高级认证 - 应用DFX能力介绍(含闯关习题)

学完时间&#xff1a;2024年8月24日 学完排名&#xff1a;第1698名 一、Performance Analysis Kit简介 Performance Analysis Kit&#xff08;性能分析服务&#xff09;为开发者提供应用事件、日志、跟踪分析工具&#xff0c;可观测应用运行时状态&#xff0c;用于行为分析、…

Prometheus学习

监控架构介绍&#xff1a; 基本架构&#xff1a; Prometheus 和 Zabbix 的对比&#xff1a; 安装和使用&#xff1a; Prometheus 采集、存储数据Grafana 用于图表展示alertmanager 用于接收 Prometheus 发送的警告信息node-exporter 用于收集操作系统和硬件信息的 metrics …

Linux:Bash中的命令介绍(简单命令、管道以及命令列表)

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 在Bash中&#xff0c;命令执行的方式可以分为简单命令、管道和命令列表组成。这些结构提供了强大的工具&#xff0c;允许用户组合命令并精确控制其执行方式。以下是对这…

Ubuntu24.04安装MYSQL8.0

更新源 sudo apt update安装mysql服务 默认安装最新版本 sudo apt install mysql-server检查安装版本 mysql --version检查mysql运行状态 systemctl status mysql开启远程访问&#xff0c;在ubuntu下mysql默认是只允许本地访问 sudo vim /etc/mysql/mysql.conf.d/mysqld.…

新疆旅游今年为什么这么火热?

今年新疆旅游火爆全网&#xff0c;不夸张的说&#xff0c;打开朋友圈&#xff0c;几乎一半人在新疆旅游、还有一半人在去新疆旅游的路上。 大家也纷纷在小红书上晒出新疆相关的笔记&#xff0c;覆盖旅游、美食、穿搭、养生、摄影等众多热门行业&#xff0c;相关话题多次登上小…

【C++】12.智能指针

在上一篇博客【C】11.异常中我们知道有些时候会造成内存空间的未释放从而导致内存泄漏&#xff0c;因此本篇博客的内容就是如何减少内存泄漏——智能指针。 一、RAII RAII&#xff08;Resource Acquisition Is Initialization&#xff09;是一种利用对象生命周期来控制程序资…

垃圾分类笔记YOLOV5(一)-pip换源-口罩识别-训练自己的数据集

pip换源网址 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple不进行配置的是临时换源 1、从github上下载YOLOV5的代码 翻墙软件clash 数据集地址roboflow clash配置一键导入 哔哩哔哩视频地址 数据集的下载格式&#xff1a; 2、修改自己的数据…

Webots与ROS1、ROS2接口变迁-2024-

三大免费仿真器CoppeliaSim、Gazebo和Webots。 Gazebo接口总结&#xff1a; Gazebo与ROS1、ROS2接口变迁-2005-2024--CSDN博客 缺点&#xff1a;版本绑定策略 早期webots版本和ros版本绑定 后期&#xff0c;webots接口最新版本和ros特定版本最匹配。 例如&#xff1a; 最好按…

Scrapy 分布式爬虫框架 Scrapy-Redis

github官网代码示例&#xff1a;https://github.com/rmax/scrapy-redis/blob/master/example-project/example/spiders/myspider_redis.py 什么是 Scrapy-Redis Scrapy-Redis 是一个基于 Scrapy 的扩展&#xff0c;用于实现分布式爬虫。它利用 Redis 作为分布式队列来共享待爬…

R 语言学习教程,从入门到精通,R 绘图饼图(23)

1、R 绘图 条形图 条形图&#xff0c;也称为柱状图条形图&#xff0c;是一种以长方形的长度为变量的统计图表。 条形图可以是水平或垂直的&#xff0c;每个长方形可以有不同的颜色。 R 语言使用 barplot() 函数来创建条形图&#xff0c;格式如下&#xff1a; barplot(H,xlab,…

JavaScript初级——DOM和事件简介

一、什么是DOM&#xff1f; 二、模型 三、对象的 HTML DOM 树 四、节点 浏览器已经为我们提供了文档节点对象&#xff0c;这个对象是window属性&#xff0c;可以再网页中直接使用&#xff0c;文档节点代表的是整个网页。 五、事件简介 事件&#xff0c;就是用户和浏览器之间的交…

【每日一题】【素数筛板子题】又是一年毕业季 牛客小白月赛99 D题 C++

牛客小白月赛99 D题 又是一年毕业季 题目背景 牛客小白月赛99 题目描述 样例 #1 样例输入 #1 3 4 2 4 6 5 5 6 2 5 3 2333333 8 11 4 5 14 19 19 8 10样例输出 #1 3 7 2做题思路 首先观察到 即需要保证拍照的时刻 大于等于 2 那么就从2开始往上走&#xff0c;如果有人…

【精选】推荐7款AI论文一键生成论文、开题报告和文献综述网站

在当前的学术研究和写作中&#xff0c;AI技术的应用已经变得越来越普遍。特别是对于论文、开题报告和文献综述的生成&#xff0c;许多平台提供了便捷的一键生成服务。以下是七款推荐的AI论文一键生成工具&#xff0c;包括千笔-aipaperpass。 1. 千笔-aipaperpass 千笔-aipape…