python-NLP:1中文分词

文章目录

  • 规则分词
    • 正向最大匹配法
    • 逆向最大匹配法
    • 双向最大匹配法
  • 统计分词
    • 语言模型
    • HMM模型
  • jieba分词
    • 分词
    • 关键词提取
    • 词性标注


规则分词

  基于规则的分词是一种机械分词方法,主要是通过维护词典,在切分语句时,将语句的每个字符串与词表中的词进行逐一匹配,找到则切分,否则不予切分。
  按照匹配切分的方式,主要有正向最大匹配法、逆向最大匹配法以及双向最大匹配法三种方法。

正向最大匹配法

  基本思想为:假设分词词典中的最长词有i个汉字字符,则用被处理文档的当前字串中的前i个字作为匹配字段,查找字典。若字典中存在这样的一个i字词,则匹配成功,匹配字段被作为一个词切分出来。如果词典中找不到这样的一个i字词,则匹配失败,将匹配字段中的最后一个字去掉,对剩下的字串重新进行匹配处理。如此进行下去,直到匹配成功,即切分出一个词或剩余字串的长度为零为止。这样就完成了一轮匹配,然后取下一个i字字串进行匹配处理,直到文档被扫描完为止。
  其算法描述如下:
  1)从左向右取待切分汉语句的m个字符作为匹配字段,m为机器词典中最长词条的字符数。
  2)查找机器词典并进行匹配。若匹配成功,则将这个匹配字段作为一个词切分出来。若匹配不成功,则将这个匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词为止。
  比如我们现在有个词典,最长词的长度为5,词典中存在“南京市长”和“长江大桥”两个词。现采用正向最大匹配对句子“南京市长江大桥”进行分词,那么首先从句子中取出前五个字“南京市长江”,发现词典中没有该词,于是缩小长度,取前4个字“南京、市长”,词典中存在该词,于是该词被确认切分。再将剩下的“江大桥”按照同样方式切分,得到“江”“大桥”,最终分为“南京市长”“江”“大桥”3个词。显然,这种结果还不是我们想要的。

#正向最大匹配
class MM(object):def __init__(self, dic_path):self.dictionary = set()self.maximum = 0#读取词典with open(dic_path, 'r', encoding='utf8') as f:for line in f:line = line.strip()if not line:continueself.dictionary.add(line)if len(line) > self.maximum:self.maximum = len(line)def cut(self, text):result = []index = 0while index <len(text):word = Nonefor size in range(self.maximum, 0, -1):#先选取最长词,然后-1....if index + size > len(text): #当前索引+size>文本长度continue#退出本次for循环,不执行下面代码。执行size-1piece = text[index:index+size]#匹配的字段if piece in self.dictionary:#匹配成功word = pieceresult.append(word)index += size #break#退出for循环if word is None:index += 1return result[::]def main():text = "南京市长江大桥"tokenizer =MM('大桥文本.txt')print(tokenizer.cut(text))main()

运行结果
[‘南京市长’, ‘大桥’]

逆向最大匹配法

  逆向最大匹配(ReverseMaximum Match Method,RMM法)的基本原理与MM法相同,不同的是分词切分的方向与MM法相反。逆向最大匹配法从被处理文档的末端开始匹配扫描,每次取最末端的i个字符(i为词典中最长词数)作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配。相应地,它使用的分词词典是逆序词典,其中的每个词条都将按逆序方式存放。在实际处理时,先将文档进行倒排处理,生成逆序文档。然后,根据逆序词典,对逆序文档用正向最大匹配法处理即可。
  由于汉语中偏正结构较多,若从后向前匹配,可以适当提高精确度。所以,逆向最大匹配法比正向最大匹配法的误差要小。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245。比如之前的“南京市长江大桥”,按照逆向最大匹配,最终得到“南京市”“长江大桥”。当然,如此切分并不代表完全正确,可能有个叫“江大桥”的“南京市长”也说不定。

# 逆向最大匹配
class IMM(object):def __init__(self, dic_path):self.dictionary = set()self.maximum = 0# 读取词典with open(dic_path, 'r', encoding='utf8') as f:for line in f:line = line.strip()if not line:continueself.dictionary.add(line)if len(line) > self.maximum:self.maximum = len(line)def cut(self, text):result = []index = len(text)while index > 0:word = Nonefor size in range(self.maximum, 0, -1):if index - size < 0:continuepiece = text[(index - size):index]if piece in self.dictionary:word = pieceresult.append(word)index -= sizebreakif word is None:index -= 1return result[::-1]def main():text = "南京市长江大桥"tokenizer = IMM('大桥文本.txt')print(tokenizer.cut(text))
main()

运行结果
[‘南京市’, ‘长江大桥’]

双向最大匹配法

  双向最大匹配法(Bi-directction Matching method)是将正向最大匹配法得到的分词结果和逆向最大匹配法得到的结果进行比较,然后按照最大匹配原则,选取词数切分最少的作为结果。据SunM.S.和Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子,正向最大匹配法和逆向最大匹配法完全重合且正确,只有大概9.0%的句子两种切分方法得到的结果不一样,但其中必有一个是正确的(歧义检测成功),只有不到1.0%的句子,使用正向最大匹配法和逆向最大匹配法的切分虽重合却是错的,或者正向最大匹配法和逆向最大匹配法切分不同但两个都不对(歧义检测失败)。这正是双向最大匹配法在实用中文信息处理系统中得以广泛使用的原因。
  前面举例的“南京市长江大桥”,采用该方法,中间产生“南京市/长江/大桥”和“南京市/长江大桥”两种结果,最终选取词数较少的“南京市/长江大桥”这一结果。

统计分词

  随着大规模语料库的建立,统计机器学习方法的研究和发展,基于统计的中文分词算法渐渐成为主流。
  其主要思想是把每个词看做是由词的最小单位的各个字组成的,如果相连的字在不同的文本中出现的次数越多,就证明这相连的字很可能就是一个词。因此我们就可以利用字与字相邻出现的频率来反应成词的可靠度,统计语料中相邻共现的各个字的组合的频度,当组合频度高于某一个临界值时,我们便可认为此字组可能会构成一个词语。
  基于统计的分词,一般要做如下两步操作:
  1)建立统计语言模型。
  2)对句子进行单词划分,然后对划分结果进行概率计算,获得概率最大的分词方式。这里就用到了统计学习算法,如隐含马尔可夫(HMM)、条件随机场(CRF)等。
  下面针对其中的一些相关技术做简要介绍。

语言模型

  语言模型在信息检索、机器翻译、语音识别中承担着重要的任务。用概率论的专业术语描述语言模型就是:为长度为m的字符串确定其概率分布P(ω1, ω2,*…,∞m),其中ω1到ωm依次表示文本中的各个词语。一般采用链式法则计算其概率值,如式所示:

  观察上式易知,当文本过长时,公式右部从第三项起的每一项计算难度都很大。为解决该问题,有人提出n元模型(n-gram model)降低该计算难度。所谓n元模型就是在估算条件概率时,忽略距离大于等于n的上文词的影响,因此 P(ω¡|ω1,ω₂,…,ωi-1) 的计算可简化为:

  当n=1时称为一元模型(unigrammodel),此时整个句子的概率可表示为:P(ω),ω2,0m) = P(ω1)P(w2)…P(ωm)观察可知,在一元语言模型中,整个句子的概率等于各个词语概率的乘积。言下之意就是各个词之间都是相互独立的,这无疑是完全损失了句中的词序信息。所以一元模型的效果并不理想。
  当n=2时称为二元模型(bigram model),变为P(ωi|ω1,ω2,…,ωi-1)=P(ω¡|W¡-1)。当n=3时称为三元模型(trigram model),变为 P(ω¡|ω1,ω2, …", ωi-1) =P(w¡|W¡-2,ωi-1)。显然当n≥2时,该模型是可以保留一定的词序信息的,而且n越大,保留的词序信息越丰富,但计算成本也呈指数级增长。一般使用频率计数的比例来计算n元条件概率,如式所示:

  式中 count(ωi-(n-1), …, ωi-1) 表示词语ω i-(n-1), …, ωi-1在语料库中出现的总次数。
  由此可见,当n越大时,模型包含的词序信息越丰富,同时计算量随之增大。与此同时,长度越长的文本序列出现的次数也会减少,如按照上式估计n元条件概率时,就会出现分子分母为零的情况。因此,一般在n元模型中需要配合相应的平滑算法解决该问题,如拉普拉斯平滑算法等。

HMM模型

  隐含马尔可夫模型(HMM)是将分词作为字在字串中的序列标注任务来实现的。其基本思路是:每个字在构造一个特定的词语时都占据着一个确定的构词位置(即词位),现规定每个字最多只有四个构词位置:即B(词首)、M(词中)、E(词尾)和S(单独成词),那么下面句子1)的分词结果就可以直接表示成如2)所示的逐字标注形式:
  1)中文/分词/是/文本处理/不可或缺/的/一步!
  2)中/B文/E分/B词/E是/S文/B本/M处/M理/E不/B可/M或/M缺/E的/S一/B步/E!/S

----
class HMM(object):def __init__(self):"""方法:初始化参数"""import os# 主要是用于存取算法中间结果,不用每次都训练模型self.model_file = 'hmm_model.pkl'# 状态值集合self.state_list = ['B', 'M', 'E', 'S']# 参数加载,用于判断是否需要重新加载model_fileself.load_para = Falsedef try_load_model(self, trained):"""方法:用于加载已计算的中间结果,当需要重新训练时,需初始化清空结果输入:trained :是否已经训练好"""if trained:import picklewith open(self.model_file, 'rb') as f:self.A_dic = pickle.load(f)self.B_dic = pickle.load(f)self.Pi_dic = pickle.load(f)self.load_para = Trueelse:# 状态转移概率(状态->状态的条件概率)self.A_dic = {}# 发射概率(状态->词语的条件概率)self.B_dic = {}# 状态的初始概率self.Pi_dic = {}self.load_para = Falsedef train(self, path):"""方法:计算转移概率、发射概率以及初始概率输入:path:训练材料路径"""# 重置几个概率矩阵self.try_load_model(False)# 统计状态出现次数,求p(o)Count_dic = {}# 初始化参数def init_parameters():for state in self.state_list:self.A_dic[state] = {s: 0.0 for s in self.state_list}self.Pi_dic[state] = 0.0self.B_dic[state] = {}Count_dic[state] = 0def makeLabel(text):"""方法:为训练材料每个词划BMES输入:text:一个词输出:out_text:划好的一个BMES列表"""out_text = []if len(text) == 1:out_text.append('S')else:out_text += ['B'] + ['M'] * (len(text) - 2) + ['E']return out_textinit_parameters()line_num = -1# 观察者集合,主要是字以及标点等words = set()with open(path, encoding='utf8') as f:for line in f:line_num += 1line = line.strip()if not line:continueword_list = [i for i in line if i != ' ']words |= set(word_list)  # 更新字的集合linelist = line.split()line_state = []for w in linelist:line_state.extend(makeLabel(w))assert len(word_list) == len(line_state)for k, v in enumerate(line_state):Count_dic[v] += 1if k == 0:self.Pi_dic[v] += 1  # 每个句子的第一个字的状态,用于计算初始状态概率else:self.A_dic[line_state[k - 1]][v] += 1  # 计算转移概率self.B_dic[line_state[k]][word_list[k]] = \self.B_dic[line_state[k]].get(word_list[k], 0) + 1.0  # 计算发射概率self.Pi_dic = {k: v * 1.0 / line_num for k, v in self.Pi_dic.items()}self.A_dic = {k: {k1: v1 / Count_dic[k] for k1, v1 in v.items()}for k, v in self.A_dic.items()}# 加1平滑self.B_dic = {k: {k1: (v1 + 1) / Count_dic[k] for k1, v1 in v.items()}for k, v in self.B_dic.items()}# 序列化import picklewith open(self.model_file, 'wb') as f:pickle.dump(self.A_dic, f)pickle.dump(self.B_dic, f)pickle.dump(self.Pi_dic, f)return selfdef viterbi(self, text, states, start_p, trans_p, emit_p):"""方法:维特比算法,寻找最优路径,即最大可能的分词方案输入:text:文本states:状态集start_p:第一个字的各状态的可能trans_p:转移概率emit_p:发射概率输出:prob:概率path:划分方案"""V = [{}]  # 路径图path = {}for y in states:  # 初始化第一个字的各状态的可能性V[0][y] = start_p[y] * emit_p[y].get(text[0], 0)path[y] = [y]for t in range(1, len(text)):  # 每一个字V.append({})newpath = {}# 检验训练的发射概率矩阵中是否有该字neverSeen = text[t] not in emit_p['S'].keys() and \text[t] not in emit_p['M'].keys() and \text[t] not in emit_p['E'].keys() and \text[t] not in emit_p['B'].keys()for y in states:  # 每个字的每个状态的可能emitP = emit_p[y].get(text[t], 0) if not neverSeen else 1.0  # 设置未知字单独成词# y0上一个字可能的状态,然后算出当前字最可能的状态,prob则是最大可能,state是上一个字的状态(prob, state) = max([(V[t - 1][y0] * trans_p[y0].get(y, 0) *emitP, y0)for y0 in states if V[t - 1][y0] > 0])V[t][y] = probnewpath[y] = path[state] + [y]  # 更新路径path = newpathif emit_p['M'].get(text[-1], 0) > emit_p['S'].get(text[-1], 0):  # 最后一个字是词中的可能大于单独成词的可能(prob, state) = max([(V[len(text) - 1][y], y) for y in ('E', 'M')])else:  # 否则就直接选最大可能的那条路(prob, state) = max([(V[len(text) - 1][y], y) for y in states])return (prob, path[state])# 用维特比算法分词,并输出def cut(self, text):import osif not self.load_para:self.try_load_model(os.path.exists(self.model_file))prob, pos_list = self.viterbi(text, self.state_list, self.Pi_dic, self.A_dic, self.B_dic)begin, next = 0, 0for i, char in enumerate(text):pos = pos_list[i]if pos == 'B':begin = ielif pos == 'E':yield text[begin: i + 1]next = i + 1elif pos == 'S':yield charnext = i + 1if next < len(text):yield text[next:]hmm = HMM()
hmm.train('HMM模型训练.txt')text = '南京市长江大桥'
res = hmm.cut(text)
print(text)
print(str(list(res)))

HMM训练数据集

jieba分词

分词

import jiebasent = '中文分词是文本处理不可或缺的一步!'
seg_list = jieba.cut(sent, cut_all=True)
print('全模式:', '/ ' .join(seg_list)) 
seg_list = jieba.cut(sent, cut_all=False)
print('精确模式:', '/ '.join(seg_list)) 
seg_list = jieba.cut(sent)  
print('默认精确模式:', '/ '.join(seg_list))
seg_list = jieba.cut_for_search(sent)  
print('搜索引擎模式', '/ '.join(seg_list))import jieba.posseg as psg
sent = '中文分词是文本处理不可或缺的一步!'
seg_list = psg.cut(sent)#标注词性
print(' '.join(['{0}/{1}'.format(w, t) for w, t in seg_list]))

运行结果

加载自定义词典

import jiebasent = 'jieba分词非常好用,可以自定义金融词典!'
seg_list = jieba.cut(sent)
print('加载词典前:', '/ '.join(seg_list))jieba.load_userdict('user_dict.txt')
seg_list = jieba.cut(sent)
print('加载词典后:', '/ '.join(seg_list))

关键词提取

  关键词提取使用jieba中的analyse模块,基于两种不同的算法,提供了两个不同的方法。
  1.基于TF-IDF算法的关键词提取

from jieba import analysetest_content="""
变压器中性点的接地方式变化后其保护应相应调整,即是变压器中性点接地运行时,投入中性点零序过流保护,停用中性点零序过压保护及间隔零序过流保护;变压器中性点不接地运行时,投入中性点零序过压保护及间隔零序保护,停用中性点零序过流保护,否则有可能造成保护误动作。
"""
key_word = analyse.extract_tags(test_content, topK=5)
print('[key_word]:', list(key_word))
key_word = analyse.extract_tags(test_content, topK=5, withWeight=True)
print('[key_word]:', list(key_word))
key_word = analyse.extract_tags(test_content, topK=5, withWeight=True,allowPOS="n")
print('[key_word]:', list(key_word))

  extract_tags()方法有四个参数,sentence为待提取的文本;topK为返回最大权重关键词的个数,默认值为20;withWeight表示是否返回权重,是的话返回(word, weight)的list,默认为False;allowPOS为筛选指定词性的词,默认为空,即不筛选。

  2.基于TextRank算法的关键词提取

from jieba import analysetest_content="""
变压器中性点的接地方式变化后其保护应相应调整,即是变压器中性点接地运行时,投入中性点零序过流保护,停用中性点零序过压保护及间隔零序过流保护;变压器中性点不接地运行时,投入中性点零序过压保护及间隔零序保护,停用中性点零序过流保护,否则有可能造成保护误动作。
"""
key_word = analyse.textrank(test_content, topK=3)
print('[key_word]:', list(key_word))
allow = ['ns', 'n', 'vn', 'v', 'a', 'm', 'c']
key_word = analyse.textrank(test_content, topK=3, allowPOS=allow)
print('[key_word]:', list(key_word))

  textrank()方法与extract_tags()方法用法相似,需要注意的是allowPOS有默认值(‘ns’, ‘n’, ‘vn’, ‘v’),默认筛选这四种词性的词,可以自己设置。其他参数都与extract_tags()方法相同。

词性标注

  词性标注使用jieba中的posseg模块,标注分词后每个词的词性,采用和ictclas兼容的标记法。

from jieba import posseg
test_content="""
变压器停、送电操作时,应先将该变压器中性点接地,对于调度要求不接地的变压器,在投入系统后应拉开中性点接地刀闸。
"""
pos_word = posseg.lcut(test_content)
print(pos_word)

[pair(‘\n’, ‘x’), pair(‘变压器’, ‘n’), pair(‘停’, ‘v’), pair(‘、’, ‘x’), pair(‘送电’, ‘v’), pair(‘操作’, ‘v’), pair(‘时’, ‘n’), pair(‘,’, ‘x’), pair(‘应先’, ‘vn’), pair(‘将’, ‘d’), pair(‘该’, ‘r’), pair(‘变压器’, ‘n’), pair(‘中性点’, ‘n’), pair(‘接地’, ‘v’), pair(‘,’, ‘x’), pair(‘对于’, ‘p’), pair(‘调度’, ‘n’), pair(‘要求’, ‘v’), pair(‘不’, ‘d’), pair(‘接地’, ‘v’), pair(‘的’, ‘uj’), pair(‘变压器’, ‘n’), pair(‘,’, ‘x’), pair(‘在’, ‘p’), pair(‘投入’, ‘v’), pair(‘系统’, ‘n’), pair(‘后’, ‘f’), pair(‘应’, ‘v’), pair(‘拉开’, ‘v’), pair(‘中性点’, ‘n’), pair(‘接地’, ‘v’), pair(‘刀闸’, ‘n’), pair(‘。’, ‘x’), pair(‘\n’, ‘x’)]

posseg.lcut()有两个参数,sentence和HMM。

在这里插入图片描述

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

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

相关文章

Java代码基础算法练习-字符串分类统计-2024.07.24

任务描述&#xff1a; 输入一行字符&#xff08;字符串长度不超过255&#xff09;&#xff0c;分别统计出其中英文字母、数字、空格和其他 字符的个数。&#xff08;提示&#xff0c;空格ASCALL码值为32&#xff09; 解决思路&#xff1a; 输入一字符串&#xff0c;先判断是否…

对递归的一些理解。力扣206题:翻转链表

今天在刷力扣的时候&#xff0c;在写一道翻转链表的题目的过程中&#xff0c;在尝试使用递归解决该问题的时候&#xff0c;第一版代码却每次都返回的是null&#xff0c;这个错误让我尝试去debug了一下&#xff0c;最终找出了问题&#xff0c;并且让我对递归有了一些更深的理解&…

顶级电子合同平台推荐:2024年精选

本文将介绍以下10款工具&#xff1a;e签宝、法大大、上上签、金格签约、契约锁、DocuSign、Concord、PandaDoc、Agiloft、Evisort。 在当今数字化时代&#xff0c;选择一个合适的电子合同平台可能会让人感到困惑&#xff0c;如何判断哪个平台最适合企业的需求&#xff1f;电子合…

Java之数组应用-选择排序-插入排序

已经完全掌握了冒泡排序和二分查找的同学&#xff0c;可以自己尝试学习选择、插入排序。不要求今天全部掌握&#xff0c;最近2-3天掌握即可&#xff01; 1 选择排序 选择排序(Selection Sort)的原理有点类似插入排序&#xff0c;也分已排序区间和未排序区间。但是选择排序每次…

超低功耗ARM Cortex-M33 TZ MCU STM32WBA54、STM32WBA55:通过提升无线性能实现更出色的用户体验

摘要 STM32WBA54、STM32WBA55产品系列同时支持多种无线标准&#xff0c;包括Bluetooth低功耗 5.4&#xff08;已认证&#xff09;、Zigbee、Thread以及可用作Thread边界路由器的Matter。 该产品系列具有出色的灵活性和更强的安全性&#xff0c;可帮助开发人员应对不断变化的无…

24暑假算法刷题 | Day21 | LeetCode 669. 修剪二叉搜索树,108. 将有序数组转换为二叉搜索树,538. 把二叉搜索树转换为累加树

目录 669. 修剪二叉搜索树题目描述题解 108. 将有序数组转换为二叉搜索树题目描述题解 538. 把二叉搜索树转换为累加树题目描述题解 669. 修剪二叉搜索树 点此跳转题目链接 题目描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪…

vite环境下使用bootstrap

环境 nodejs 18 pnpm 初始化 pnpm init pnpm add -D vite --registry http://registry.npm.taobao.org pnpm add bootstrap popperjs/core --registry http://registry.npm.taobao.org pnpm add -D sass --registry http://registry.npm.taobao.org新建vite.config.js cons…

用三行代码“偷袭白嫖党”,保护自己的代码(多语言实现)

计算机科学专业的同学们最近遇到了一件烦心事。教授布置了一系列具有挑战性的编程作业&#xff0c;需要大家运用所学知识来完成。然而&#xff0c;一些同学却动起了歪脑筋&#xff0c;想要通过抄袭他人的代码来轻松完成任务。 小李、小王和小张是同宿舍的好友&#xff0c;他们…

四、GD32 MCU 常见外设介绍(1)RCU 时钟介绍

系统架构 1.RCU 时钟介绍 众所周知&#xff0c;时钟是MCU能正常运行的基本条件&#xff0c;就好比心跳或脉搏&#xff0c;为所有的工作单元提供时间 基数。时钟控制单元提供了一系列频率的时钟功能&#xff0c;包括多个内部RC振荡器时钟(IRC)、一个外部 高速晶体振荡器时钟(H…

如何提升短视频的曝光量和获客效能?云微客来解决

在流量至上的当下&#xff0c;短视频凭借其优势&#xff0c;迅速成为了众多企业获客引流的核心营销手段。进入短视频赛道后&#xff0c;如何提升短视频的曝光量和获客效能&#xff0c;就成为了众多企业亟待解决的焦点。 如果你不想投入大量的广告预算&#xff0c;还想在短视频平…

【Linux】进程间通信及管道详细介绍(上)

前言 本节我们开始学习进程间通信相关的知识&#xff0c;并详细探讨一下管道&#xff0c;学习匿名管道和命名管道的原理和代码实现等相关操作… 目录 1. 进程间通信背景1.1 进程通信的目的&#xff1a; 2 管道的引入&#xff1a;2.1 匿名管道&#xff1a;2.1.1 匿名管道的原理&…

【中项】系统集成项目管理工程师-第5章 软件工程-5.1软件工程定义与5.2软件需求

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

【数据结构】AVL树(图文解析 + 代码实现)

目录 1、AVL树的概念 2、AVL树结点的定义 3、AVL树的插入 4、AVL树的旋转 4.1 左单旋 4.2 右单旋 4.3 右左双旋 4.4 左右双旋 5、AVL树的验证 6、AVL树的性能 前面对map/multimap/set/multiset进行了简单的介绍&#xff0c;会大仙&#xff0c;这几个容器有个共同点是…

【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !

目录 C语言指针精讲1. 什么是指针&#xff1f;1.1 指针的内存模型1.1.1 指针演示输出 1.2 指针运算1.2.1 指针算术运算输出1.2.2 指针与数组的关系输出 1.3 指针类型1.3.1 不同类型的指针示例输出1.3.2 void 指针输出 1.4 指针与内存管理动态内存分配输出 1.5 指针与内存泄漏1.…

vue 两个页面切换, 再回到当前页,还是离开前的数据

1、要保证页面的name 和 建路由的大小写一致 2、页面不用生命周期--activated 调接口刷新

在 Kubernetes 中设置 Pod 优先级及其调度策略详解

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

【论文解读】大模型算法发展

一、简要介绍 论文研究了自深度学习出现以来&#xff0c;预训练语言模型的算法的改进速度。使用Wikitext和Penn Treebank上超过200个语言模型评估的数据集(2012-2023年)&#xff0c;论文发现达到设定性能阈值所需的计算大约每8个月减半一次&#xff0c;95%置信区间约为5到14个月…

雪花算法 集群uid重复问题 uid-generator-spring-boot-starter

1、在生成环境 在某个业务使用该插件生成uid,由于业务整合了 mybatis-plus模块 2、该业务是分部署集群部署以及使用的多线程获取uid&#xff0c;使用中发现唯一建冲突&#xff0c;生成的uid有重复。 然后查看日志发现 workerId 始终为0 怀疑是生成workerId出了问题。 查看跟…

开发日志:windows修复SSL漏洞CVE-2016-2183(3389端口)

漏洞危害&#xff1a; 具有足够资源的中间人攻击者可利用此漏洞,通过“birthday”攻击检测会在固定密码与已知纯文本之间泄露 XOR 的冲突,进而泄露密码文本(例如安全 HTTPS Cookie),并可能导致劫持经认证的会话。 参见《支持SSL 64位块大小的密码套件(SWEET32)-修复方案》 参考…

主流树模型讲解、行列抽样、特征重要性梳理总结

本文旨在总结一下常见树模型的行、列抽样特点以及特征重要性的计算方式&#xff0c;也会带着过一遍算法基本原理&#xff0c;一些细节很容易忘记啊。 主要是分类和回归两类任务&#xff0c;相信能搜索这篇文章的你&#xff0c;应该对树模型有一定的了解。 可以搜索 总结 &…