当前位置: 首页 > news >正文

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。

在这里插入图片描述

相关文章:

python-NLP:1中文分词

文章目录 规则分词正向最大匹配法逆向最大匹配法双向最大匹配法 统计分词语言模型HMM模型 jieba分词分词关键词提取词性标注 规则分词 基于规则的分词是一种机械分词方法&#xff0c;主要是通过维护词典&#xff0c;在切分语句时&#xff0c;将语句的每个字符串与词表中的词进行…...

iOS 开发包管理之CocoaPods

CocoaPods&#xff08;Objective-C 时期&#xff0c;支持Objective-C和swift&#xff09;&#xff0c;CocoaPods下载第三方库源代码后会将其编译成静态库.a 文件 或动态库框架.framework 文件 的形式&#xff0c;并将它们添加到项目中&#xff0c;建立依赖关系&#xff0c;这种…...

Windows搭建RTMP视频流服务器

参考了一篇文章&#xff0c;见文末。 博客中nginx下载地址失效&#xff0c;附上一个有效的地址&#xff1a; Index of /download/ 另外&#xff0c;在搭建过程中&#xff0c;遇到的问题总结如下&#xff1a; 1 两个压缩包下载解压并重命名后&#xff0c;需要 将nginx-rtmp…...

VS2019安装MFC组件

VS2019支持的MFC版本是mfc140 ~ mfc142版本&#xff0c;它兼容VS2015、VS2017之前的老版本程序。 一、MFC的历史版本 MFC的历史版本如下&#xff1a; IDE发布时间工具集版本MSC_VERMSVCMFC版本dllVisual C6.01998V601200MSVC6.06.0mfc42.dll、mfcce400.dllVisual Studio 2002…...

Python学习—open函数,json与pickle知识点,Os模块详解

目录 1. Open函数 2.json与pickle模块 json模块 1. json.dumps() 2. json.dump() 3. json.loads() 4. json.load() pickle 模块 1. pickle.dumps() 2. pickle.dump() 3. pickle.loads() 4. pickle.load() 3.Os模块 1. Open函数 在Python中&#xff0c;open() 函数…...

基于SSM的高考志愿选择辅助系统

基于SSM的高考志愿选择辅助系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台 前台首页 院校展示 后台 后台首页 学校管理 摘要 随着高考制度的不断完…...

引领小模型潮流!OpenAI发布功能强大且成本低的GPT-4o mini

GPT-4o mini的成本比GPT-3.5 Turbo低了超过60%&#xff0c;其聊天表现优于Google的Gemini Flash和Anthropic的Claude Haiku。该模型从周四开始对ChatGPT的免费用户、ChatGPT Plus用户和团队订阅用户开放&#xff0c;并将在下周向企业用户开放。OpenAI计划未来将图像、视频和音频…...

【考研数学】线代满分经验分享+备考复盘

我一战二战复习都听了李永乐的线代课&#xff0c;二战的时候只听了一遍强化&#xff0c;个人感觉没有很乱&#xff0c;永乐大帝的课逻辑还是很清晰的。 以下是我听向量这一章后根据听课内容和讲义例题总结的部分思维导图&#xff0c;永乐大帝讲课的时候也会特意点到线代前后联…...

Java项目:基于SSM框架实现的海鲜自助餐厅系统【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的海鲜自助餐厅系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…...

前端面试题日常练-day97 【Less】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 在Less中&#xff0c;以下哪个功能用于处理文本字间距&#xff1f; a) letter-spacing() b) word-spacing() c) text-spacing() d) space-between() Less中的Variables可以存储哪些类型的值&#xff…...

压缩视频大小的方法 怎么减少视频内存大小 几个简单方法

随着4K、8K高清视频的流行&#xff0c;我们越来越容易遇到视频文件体积过大&#xff0c;导致存储空间不足、传输速度缓慢等问题。视频压缩成为解决这一问题的有效途径&#xff0c;但如何在减小文件大小的同时&#xff0c;保证视频质量不受影响呢&#xff1f;本文将为你揭晓答案…...

JVM:GraalVM

文章目录 一、介绍1、什么是GraalVM&#xff1a;2、GraalVM版本 二、两种使用模式 一、介绍 1、什么是GraalVM&#xff1a; GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。GraalVM的官网地址&#xff1a;https://www.graa…...

海外营销推广:快速创建维基百科(wiki)词条-大舍传媒

一、维基百科的永久留存问题 许多企业和个人关心维基百科是否能永久留存。实际上&#xff0c;只要企业和个人的行为没有引起维基百科管理方的反感&#xff0c;词条就可以长期保存。如果有恶意行为或被投诉&#xff0c;维基百科可能会对词条进行删除或修改。 二、创建维基百科…...

【HarmonyOS】HarmonyOS NEXT学习日记:五、交互与状态管理

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;五、交互与状态管理 在之前我们已经学习了页面布局相关的知识&#xff0c;绘制静态页面已经问题不大。那么今天来学习一下如何让页面动起来、并且结合所学完成一个代码实例。 交互 如果是为移动端开发应用&#xff0c;那么交…...

处理uniapp刷新后,点击返回按钮跳转到登录页的问题

在使用uniapp的原生返回的按钮时&#xff0c;如果没有刷新会正常返回到对应的页面&#xff0c;如果刷新后会在当前页反复横跳&#xff0c;或者跳转到登录页。那个时候我第一个想法时&#xff1a;使用浏览器的history.back()方法。因为浏览器刷新后还是可以通过右上角的返回按钮…...

工厂方法模式java

文章目录 1. 概念2. 示例3. 代码示例 1. 概念 定义: 工厂方法模式又叫工厂模式,通过定义工厂父类创建对象的公共接口,而子类负责创建具体的对象 作用: 由工厂的子类来决定创建哪一个对象 缺点: 工厂一旦需要生成新的东西就需要修改代码,违背的开放封闭原则 2. 示例 3. 代码示…...

java模拟多ip请求【搬代码】

java模拟多ip请求 package url_demo;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.Random;public class HttpUtilTest…...

微软史诗级的蓝屏

本周经历了微软的蓝屏&#xff0c;一直到周末还在加班处理公司的问题。 个人终端受到的影响较大&#xff0c;服务器上也受到了影响。因为蓝屏的事情导致不少麻烦&#xff0c;据同事说因为蓝屏的问题&#xff0c;MGH 的手术安排也受到了影响。 目前我们也在着手处理有部署 Wind…...

HALCON数据结构

一、HALCON数据结构简介 1、HALCON中有两类参数&#xff1a;图形参数和控制参数。 2、HALCON算子参数中&#xff0c;图形输入参数、图形输出参数、控制输入参数和控制输出参数。 3、图形参数有&#xff1a;图像(image)、区域(region)和轮廓(XLD) 4、控制参数有&#xff1a;…...

数据库系统概论:事务与并发一致性问题

随着网络应用的普及&#xff0c;数据库并发问题变得越来越重要。数据库并发指的是多个用户或进程同时访问和操作数据库的能力。它是数据库系统性能优化的重要方面&#xff0c;旨在提高系统的吞吐量和响应时间&#xff0c;以满足多用户同时访问数据库的需求。然而&#xff0c;这…...

Python编程基础:元组类型、字典类型、集合类型

目录 元组类型创建/删除元组访问/操作元组元组生成式字典类型创建/删除字典访问/操作字典字典相关函数集合类型创建/删除集合集合相关操作符访问/操作集合元组类型 元组是Python中内置的不可变序列,这是它跟列表的不同之处,它没有一系列增删改等操作,只可以使用索引和for循环…...

day2 单机并发缓存

文章目录 1 sync.Mutex2 支持并发读写3 主体结构 Group3.1 回调 Getter3.2 Group 的定义3.3 Group 的 Get 方法 4 测试 本文代码地址&#xff1a; https://gitee.com/lymgoforIT/gee-cache/tree/master/day2-single-node 本文是7天用Go从零实现分布式缓存GeeCache的第二篇。 …...

ECMP等价多路由机制,大模型训练负载均衡流量极化冲突原因,万卡(大规模)集群语言模型(LLM)训练流量拥塞特点

大规模集群&#xff0c;大语言模型(LLM)训练流量特点&#xff0c;ECMP&#xff08;Equal-Cost Multi-Path Routing&#xff09;流量极化拥塞原因。 视频分享在这&#xff1a; 2.1 ECMP等价多路由&#xff0c;大模型训练流量特点&#xff0c;拥塞冲突极化产生原因_哔哩哔哩_bi…...

Linux 注意事项

Linux 与 Windows 是两个相互独立的操作系统&#xff0c;两者有较大差距&#xff1a; 1.1 Linux 严格区分大小写&#xff08;Windows不严格区分大小写&#xff09;&#xff1b; 1.2 Linux 中所有内容&#xff0c;硬件设备都以文件形式保存在 /dev 目录下&#xff08;万物皆文件…...

力扣SQL50 指定日期的产品价格 双重子查询 coalesce

Problem: 1164. 指定日期的产品价格 coalesce 的使用 简洁版 &#x1f468;‍&#x1f3eb; 参考题解 select distinct p1.product_id,coalesce((select p2.new_pricefrom Products p2where p2.product_id p1.product_id and p2.change_date < 2019-08-16order by p2.…...

MySQL8的备份方案——全量(完全)备份(CentOS)

MySQL8的全量备份 一、安装备份工具二、备份数据三、恢复备份 点击跳转增量备份 点击跳转差异备份 点击跳转压缩备份 一、安装备份工具 官网 下载地址 备份所用工具为percona-xtrabackup 如果下方安装工具的教程失效&#xff0c;请点击上方下载地址转到官方文档查看 下载该工…...

JVM监控及诊断工具-命令行篇--jcmd命令介绍

JVM监控及诊断工具-命令行篇5-jcmd&#xff1a;多功能命令行 一 基本情况二 基本语法jcmd -ljcmd pid helpjcmd pid 具体命令 一 基本情况 在JDK 1.7以后&#xff0c;新增了一个命令行工具jcmd。它是一个多功能的工具&#xff0c;可以用来实现前面除了jstat之外所有命令的功能…...

c++信号和槽机制的轻量级实现,sigslot 库介绍及使用

Qt中的信号与槽机制很好用&#xff0c;然而只在Qt环境中。在现代 C 编程中&#xff0c;对象间的通信是一个核心问题。为了解决这个问题&#xff0c;许多库提供了信号和槽&#xff08;Signals and Slots&#xff09;机制。今天推荐分享一个轻量级的实现&#xff1a;sigslot 库。…...

云原生项目纪事系列 - 项目管理的鲜活事例

大规模云原生系统的新颖性、建设性和挑战性&#xff0c;吸引着许多有数学思想、哲学意识和美学观念的系统架构师&#xff0c;老模也是其中一员。 老模即是文史家庭出身&#xff0c;又有理工学业背景&#xff0c;他基于平时记录的翔实细节&#xff0c;秉持客观原则&#xff0c;使…...

【Vite】快速入门及其配置

概述 Vite是前端构建工具。vite 相较于webpack,vite采用了不同的运行方式&#xff1a; 开发时&#xff0c;并不对代码打包&#xff0c;而是直接采用ESM的方式来运行项目在项目打包部署时&#xff0c;使用 rollup 对项目进行打包除了速度外&#xff0c;vite使用起来也更加方便…...

网站开发形象设计要求/怎样联系百度客服

window.history 我们可以通过window.history的两个方法来控制浏览器的路由改变&#xff0c;但不会让浏览器刷新页面。 pushState 会追加浏览器的路由历史&#xff0c;但不会刷新页面&#xff0c;可以用这种方式来实现前端路由的控制。 history.pushState(state, title[, ur…...

建设部门户网站/自己怎么做关键词优化

一、前言最近公司在预研设备app端与服务端的交互方案&#xff0c;主要方案有服务端和app端通过阿里iot套件实现消息的收发&#xff1b;服务端通过极光推送主动给app端推消息&#xff0c;app通过rest接口与服务端进行交互&#xff1b;服务端与app通过mqtt消息队列来实现彼此的消…...

永久免费企业网站建设/深圳seo招聘

props.load(new FileInputStream("db.properties ")); 是读取当前目录的db.properties 文件 getClass.getResourceAsStream("db.properties "); 是读取当前类所在位置一起的db.properties 文件 getClass.getResourceAsStream("/db.properties ")…...

广州自助企业建站模板/免费制作网站平台

GCD里就有三种queue(分派队列)来处理. 1. Main queue&#xff1a;(主队列) 顾名思义,运行在主线程,由dispatch_get_main_queue获得.和ui相关的就要使用Main Queue. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗时的操作 dispatch_…...

企业网站建设合同(一)/杭州网站seo

文章目录数据集格式基于线性回归sigmoid实现二分类的表达式链式法则求导链式表达式求解∂l∂oj^\frac{\partial l}{\partial \hat{o_j}}∂oj​^​∂l​求解∂oj∂wij\frac{\partial o_j}{\partial w_{ij}}∂wij​∂oj​​求解∂oj∂bj\frac{\partial o_j}{\partial b_j}∂bj​∂…...

网站建设费用构成/如何宣传自己的网站

1、why&#xff1a; 为啥学NDK开发&#xff0c;其实是为了项目需要调用底层的一些C/C的一些东西&#xff1b;另外就是为了效率更加高些&#xff1b;Android ndk 提供 了 opengls2、what 是什么The NDK is a toolset that allows you to implement parts of your app using nati…...