LangChain+LLM大模型问答能力搭建与思考

1. 背景

最近,大模型(LLMs,Large Language Models)可谓是NLP领域,甚至整个科技领域最火热的技术了。凑巧的是,我本人恰好就是NLP算法工程师,面临着被LLMs浪潮淘汰的窘境,决定在焦虑之余,试着用新家伙,去解决解决老问题(缓解一下焦虑…)

所以是什么老问题呢?——那就是Bert解决了过、但问题依旧存在的那个——垂直领域问答

2. 原思路简介

由于目前的确已经有许多类似的、写得很优秀的大佬写的文章了,所以我本文不会过多涉及具体的代码。我更倾向于探讨一下我们怎么用这项**“新技术”**,来解决之前就有的、而且颇有价值的”老问题“

首先,最基础的架构我们还是要说一下(免得一段时间以后回顾的时候一脸懵逼,只剩吹牛了)

我们先回顾一下,Bert时代的垂直领域问答系统是怎么构建的?
Bert时代的垂直领域问答系统架构示意图

如上图所示,这就是个问答系统的大概面貌了。当然了,还有些其他辅助模块没在这里体现,这里只拿出了最关键的几个部分:

  1. query理解:充分理解query含义,挖掘query信号,给下一轮的doc(文档)”粉碎机“提供弹药!
  2. 文档召回:这里的召回方式大概可分为2大类,分别是基于query理解得到的信号召回,以及向量召回。
    1. 信号召回:基于ES或其他什么类ES自研框架(为什么要自研,还不是为了体现价值orz…)实现,可以简单理解为关键词召回,即从query和doc中分别找到关键词,然后进行匹配、打分;
    2. 向量召回:信号召回显然是基于”字面“的,而向量召回则是基于语义的。将doc提前向量化建库,然后query再向量化后进行向量检索。
    3. 最后,基于以上两路召回的文档得分,再结合一些其他trick(如质量打分)进行综合排序,取topK进入下一轮大逃杀!
  3. 答案抽取:使用预训练好的模型,分别对topK文档里的答案进行抽取。对于上一代Berter(哦不NLPer)而言,主模型都是Bert或其徒子徒孙。现在,则是最时髦的LLM
  4. 答案处理:后处理模块,可将得到的答案再次排序、可做答案融合、也可根据业务需要,进行合理的后处理,最后输出。

3. LLM出现以后的世界

3.1 LLM时代和Bert时代的差异

那么,在现如今ChatGPT、ChatGLM、Moss、LAMMA等大模型满天飞的世界,上述那套系统有什么变化了呢?

其实,这套系统整体流程变化并不大,只不过是将”答案抽取“模块的Bert时代模型替换成了LLMs时代的模型。而由于LLM在模型能力、允许输入长度等方面都比Bert强不少,所以一定程度上,LLMs时代这套系统对其他几个模块的要求也降低了

举个例子,在Bert时代,query理解是个要做得很重、异常重要的模块,毕竟如果这里能力不足,那下游模型就”巧妇难为无米之炊了“,我上面那张图里query理解部分每个子模块都能撑得起一大块工作。而大家都知道,端到端的模型是大家一直追求的(是吗?毕竟这样要我们NLPer还能做啥?),而且能力足够的端到端模型可以最大程度减少信息损失,所以能力更强的LLMs直接把这个模块的工作包揽了下来,原本的query分词、分类、纠错、关键词等工作变成了制定合适的Prompt然后调试,具体的query理解,就由LLM来搞定了。

下面,我再简介一下结合LLM时,垂直领域问答的架构的样子

3.2 LLM时代垂直领域知识库问答常用架构

LLM时代垂直领域知识库问答架构

架构异常简单,暂时能力所限,仅为博君一笑~

如图所示,能看得出,整体架构比Bert时代的简单很多。我们对照着之前的架构来说:

  1. query理解 VS提问模块:前面举过例子,目前提问模块在当前架构下已经几乎没有什么任务了,但如果你想增加一路关键词召回,那么这里也可以借助大模型的能力来解决,用大模型(当然,也可以是传统nlp模型或规则词表)帮你完成关键词提取,然后到下一步中进行使用ES做关键词召回

  2. 两版文档召回模块:这一部分差别其实不大,但随着LLMs的模型能力提升,对于召回质量的忍耐度也在提升。由于Bert时代模型往往有512 tokens的长度限制,所以我们要更加小心地做好召回文段排序和截断、文段之间overlap等事情。但随着大模型目前普遍将文本可输入长度扩到了8K、甚至是16K/32K(当然这里指的是字符,汉字字数会少一些),这就意味着如果需要,我们可将更多的文段喂给LLM。也正因为此,我们现如今往往只用向量召回(LangChain)即可达到要求。当然了,为了进一步提升召回文章的丰富度,开发额外的ES关键词召回、甚至更复杂的召回链路也是可行的。笔者之前有幸在某大厂负责过电商搜索引擎的召回模块,各路召回之复杂实在让人欲仙欲死,然而它们也确实是有用的,有些召回路径满足的是搜索的精准,有的召回路径满足的是物料的丰富,有的召回路径从用户历史兴趣角度考量,也有的召回路径从品类、产地、功能等多角度试图猜到用户所需。不过,由于知识库问答场景往往没有这么多目标,所以我们就尽可能做的轻一些——less is more

  3. 答案抽取模块VS大模型问答模块:虽然核心的模型从Bert变成了本地的微调过的ChatGLM、或ChatGPT-api,但整体思路是一致的。Bert时代首先需要将处理后的query和若干召回的doc拼接成类似[CLS]query[SEP]doc1, [CLS]query[SEP]doc2, …类似的样子,然后分别送给Bert进行答案抽取、输出;LLMs时代,则是将召回的doc和用户query装配成最终Prompt,类似的样子如下:

    """已知信息:
    {context} 
    
    根据上述已知信息,简洁和专业地回答用户问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题” 或 “没有提供足够的相关信息”,不允许在答案中添加编造成分,答案请使用中文。 问题是:{question}
    """
    

    以上Prompt模板参考链接。最后,LLM会将答案输出。

  4. 答案处理模块在LLM版本架构中,不再需要这一模块,因为LLM已经将输入资料整合并完成回答了。但Bert时代,由于多段资料分别和query拼接进行答案抽取,所以结果还要对多个答案进行排序。

4. LangChain+LLM实战心得体会

具体LangChain+LLM的代码,笔者参考该repo,并在上面进行了些细微的二次开发。由于该项目已经非常完备了,所以不再赘述。我在这里,主要说一下我在项目开发中遇到的问题和一点思考:

4.1 数据处理和清洗方面

  1. 关于目录:目录部分应提前识别并删除

    这部分关键词巨多(误命中)、各种标点符号巨多(误分段)、大多不是自然语言(用来做目录索引的,没实际的文本含义),引入目录,会在文档召回阶段通过向量或关键词产生大量误召回,建议直接咔嚓掉

  2. 文档分段长度:模型允许的情况下,能长则长;可根据数据酌情向后扩展

    在大模型可接受文本总字数有限的情况下,增加召回数量和增加单文档长度的权衡

    • 首先,由于我所处理的数据是相对干货的政策法规和企业规章,所以文章质量较高;其次,相似的内容较少出现在多个出处、而且有些政策文本会有不少1.xxx, 2.xxx, ..., 10.xxx这种不适合切割的超长内容,所以对我的数据而言,与其召回更多个短文本段,还不如召回更少的长文本段,以减少低相关杂质引入,也防止有用内容被截断。

    • 不过之前我也处理过各种政策解读、财经类新闻的语料,这种语料往往良莠不齐且同一件事有多个相似文章在描述,为了确保结果的全面性,则是召回更多个短文本段更好。

    关于分段截断的问题

    • 一般通用分段方式,是在固定max_length的基础上,对出现。/;/?/....../\n等等地方进行切割。

    • 但这种方式显然比较武断,面对特殊情况需要进一步优化。比如前面的那个1.xxx, 2.xxx, ..., 10.xxx超长内容的情况,直接按这种方法切割就会导致潜在的内容遗漏。

    • 对于这种候选语料”内聚性“很强的情况,容易想到,我们要么在切割语料时动手脚(不把连续数字符号所引领的多段文本切开);要么在切割时照常切割、但在召回时动手脚(若命中了带连续数字符号的这种长文本的开头,那么就一并把后面连续数字符号引领的多段文本一起召回)。笔者目前只想到了这两种方法且还没具体做实验,只是凭空想来,前者方案有较明显瑕疵,因为这样会——

      1. 相对于更短文段而言,长文段的语义更丰富,每个单独的语义点更容易被淹没,所以在有明确语义query的召回下这种长文段可能会吃亏;
      2. 长文段一旦被召回,只要不是针对整段文本的提问,那么也是引入了更多的噪声(不过鉴于LLM的能力,这可能也无伤大雅,就是费点显存or接口费用了)

      但后者就显得更灵活些,不过确实也不够聪明。暂时没想到其他办法,有好想法的人可以来交流一下~

    • 此外,有研究表明,长文本作为输入LLM输入时,LLM倾向于更关注长文本的开头、结尾处,然而中间部分的语义可能会被忽略。这里挖个小坑,下次再来关注一下这方面问题

4.2 模型方面

  1. 调整temperature参数规避模型”知识幻觉“

    • 对于知识库问答而言,知识幻觉(一本正经的胡说八道)是最头疼的事情。对于ChatGPT(gpt-3.5-turbo)而言,笔者实验过,当temperature<=0.1,可以有效避免“知识幻觉”(即Prompt中没有问题答案,ChatGPT就会回答”根据已知信息无法回答该问题“),不过这也可能让模型过分谨慎(即使有语义类似的答案,模型也倾向于那不是提问范围内的)。建议可以再尝试一些0.1~0.5之间的temperature,在最大化模型联想能力的同时,确保回复的可靠性

    • 但对于ChatGLM-6B(v1),该模型temperature取值范围在[0, 1],笔者尝试过0.1、0.01等数值,仍然会出现较为严重的模型幻觉。不知道ChatGLM2-6B效果会不会好些。不过6B的打不过号称175B的ChatGPT,也是正常

4.3 问题解决思路方面

这部分只是个人在问题解决过程中的一点想法,与大家分享。

  1. 明确多文档下的知识点问答,和单文档总结之间的区别

    • 该项目LangChain+LLM的思路,是针对多文档下的知识点问答的,目标是在海量语料中精准找到几小段参考文档然后总结出答案;
    • 而单文档总结,即类似ChatPDF的需求,和本项目目标不一致。ChatPDF的目标是尽可能全面地总结出整篇文档的信息。这个需求以目前ChatGPT可接受的16K上下文而言,不少文档可以直接丢进去问答,无需使用召回工具先做知识检索,不完全属于该项目解决的问题范围。
  2. 对于效果不佳的情况,首先应该从更高的角度思考,到底是当前技术不达标,还是使用场景不契合。用检索+问答这种范式解决其不擅长的问题、然后再此基础上搞一大批trick,是非常不可取的,应尽量避免

    • 举个例子,有人问这种问答模式能否解决Excel表格问答?这当然可以试试,结果对表格进行问答效果很差——这个结果很容易预期,毕竟CoT的思想就提到过,做推理、算数学题,这种需要一步步思考的任务在加以一步步引导的情况下,LLM才能得到不错的结果。那么,我们应该在检索+LLM这个项目上做优化以解决Excel表格的问答问题吗?非也。我们应该意识到Excel、或者其他文件中的表结构本身属性是表格,表格是结构化数据、文本是非结构化的,而检索系统(文本召回系统)本身就是为非结构化数据准备的。所以要解决excel文件问答的问题,或许可以把它归类到“NL2SQL”上,用代码/SQL的方式去解决。

    • 我做了简单的尝试,供大家参考,后台模型gpt-3.5-turbo-16K:

      来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?直接给出答案


      来自 ChatGPT 的消息:

      以上这些人中,贾-莫兰特的出战场次最多,共计61场。

      所有人的平均出战场次为63.1场。


      来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?使用pandas计算,给出可执行代码,无需将全部数据重新列举一遍


      来自 ChatGPT 的消息:

      您可以使用以下代码来计算出战场次最多和平均出战场次:

      import pandas as pd
      
      # 创建数据表
      data = {
          '排名': [1, 2, 3, 4, 5, 6, 7, 8, 9],
          '球员': ['乔尔-恩比德', '卢卡-东契奇', '达米安-利拉德', '谢伊-吉尔杰斯-亚历山大', '扬尼斯-阿德托昆博', '杰森-塔特姆', '多诺万-米切尔', '杰伦-布朗', '贾-莫兰特'],
          '球队': ['76人', '独行侠', '开拓者', '雷霆', '雄鹿', '凯尔特人', '骑士', '凯尔特人', '灰熊'],
          '得分': [33.10, 32.40, 32.20, 31.40, 31.10, 30.10, 28.30, 26.60, 26.20],
          '命中-出手': ['11.00-20.10', '10.90-22.00', '9.60-20.70', '10.30-20.30', '11.20-20.30', '9.80-21.10', '10.00-20.60', '10.10-20.60', '9.30-19.90'],
          '命中率': ['54.8%', '49.6%', '46.3%', '51%', '55.3%', '46.6%', '48.4%', '49.1%', '46.6%'],
          '命中-三分': ['1.00-3.00', '2.80-8.20', '4.20-11.30', '0.90-2.50', '0.80-2.70', '3.20-9.30', '3.60-9.30', '2.40-7.30', '1.50-4.90'],
          '三分命中率': ['33%', '34.2%', '37.1%', '34.5%', '27.5%', '35%', '38.6%', '33.5%', '30.7%'],
          '命中-罚球': ['10.00-11.70', '7.80-10.50', '8.80-9.60', '9.80-10.90', '7.90-12.20', '7.20-8.40', '4.70-5.40', '3.90-5.10', '6.10-8.10'],
          '罚球命中率': ['85.7%', '74.2%', '91.4%', '90.5%', '64.5%', '85.4%', '86.7%', '76.5%', '74.8%'],
          '场次': [66, 66, 58, 68, 63, 74, 68, 67, 61],
          '上场时间': [34.60, 36.20, 36.30, 35.50, 32.10, 36.90, 35.80, 35.90, 31.90]
      }
      
      df = pd.DataFrame(data)
      
      # 找出出战场次最多的球员
      max_appearances = df['场次'].max()
      player_with_max_appearances = df.loc[df['场次'] == max_appearances, '球员'].values[0]
      
      print("出战场次最多的球员是:", player_with_max_appearances)
      
      # 计算平均出战场次
      average_appearances = df['场次'].mean()
      
      print("所有球员的平均出战场次是:", average_appearances)
      

      输出结果为:

      出战场次最多的球员是: 杰森-塔特姆
      所有球员的平均出战场次是: 64.33333333333333
      

      ###来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?使用sql计算,无需将全部数据重新列举一遍


      ###来自 ChatGPT 的消息:

      根据给出的数据,可以使用SQL查询来计算出战场次最多的球员和平均出战场次。

      出战场次最多的球员可以通过查询最大的场次数来得到:

      SELECT 球员, MAX(场次) AS 最多场次
      FROM 表名;
      

      平均出战场次可以通过查询所有球员的场次数并计算平均值来得到:

      SELECT AVG(场次) AS 平均场次
      FROM 表名;
      

      请将"表名"替换为实际的表名,然后执行上述SQL查询即可得到结果。

      总结一下:

      1. 以上这些人谁的出战场次最多?所有人平均出战多少场次?”这2个问题的答案分别是“杰森塔图姆”和65.67场
      2. 我分别让模型用3种方式输出结果:1-直接输出、2-给出pandas代码后输出、3-只给SQL代码。
      3. 三种方式里,方法1直接错误,两个问题皆错;方法2最后给出答案时,问题2“平均出战场次”算错了。但它给出了正确的pandas代码,执行后两个问题都能得到正确结果;方法3我禁止其输出答案,只给出SQL代码,最后验证sql代码准确无误;
      4. 此外,为了减少大量数据反复传给LLMs增加其负担,实际上可以只给它带表头的2~3行数据,让其明白数据格式即可。

      所以由此可见,与其让它自己推理复杂计算,还不如让它给出代码,然后你自己去执行代码。当然,这里的问题确实是超级简单了,大家可以再试试上难度的统计问题

    • 此外,据了解,OpenAI官方推出的Code Interpreter就是专门干这个的(你可以把它当成个Data Analyzer,感兴趣的童鞋可以试试:OpenAI-Code Interpreter)

5. 总结

本文从实战角度出发,对垂直领域知识库问答这个问题,在Bert时代和LLMs时代的解决方案均做了简述。此外,本文还对LLM时代的LangChain+LLM的方案在实战中出现的问题进行了探讨,最后,还简单尝试了一下ChatGPT在数据分析方面的潜力。

欢迎大家多多点赞关注,一起交流学习吧😊

PS,转载请注明出处哦!

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

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

相关文章

配置jenkins 服务器与目标服务器自动化部署

在配置完远程构建后可以通过添加post-build step 执行shell脚本的方式将包传到远程服务器等一系列操作。 通过scp传输打包好的项目到目标服务器 按照链接 方式配置免密操作&#xff0c;需要注意的是要在jenkins 用户目录下配置生成私钥密钥&#xff0c;配置jenkins 的免密&…

我的踩坑记录!!!积累中......

bug记录&#xff1a; 解决 nodejs安装后&#xff0c;在安装目录下【nodejs】创建两个文件夹【node_global】及【node_cache】用来配置全局环境变量。 之后&#xff0c;打开cmd命令窗口&#xff0c;输入 npm config set prefix ”D:\Program Files\nodejs\node_global” npm con…

YOLO-V5分类实战系列 —— 调优自己的数据集+RK1808部署

YOLO-V5分类实战系列 —— 调优自己的数据集 1、保存训练和测试图片2、数据归一化3、数据增强3.1、数据增强库&#xff1a;albumentations3.2、数据增强库&#xff1a;torchvision 4、ONNX CPU 推理4.1、Pt 模型转为 ONNX4.2、ONNX 推理验证4.3、 ONNX CPU推理&#xff08;C&am…

蓝桥杯专题-真题版含答案-【生命之树】【消除尾一】【密码脱落】【生日蜡烛】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

使用GGML和LangChain在CPU上运行量化的llama2

Meta AI 在本周二发布了最新一代开源大模型 Llama 2。对比于今年 2 月发布的 Llama 1&#xff0c;训练所用的 token 翻了一倍&#xff0c;已经达到了 2 万亿&#xff0c;对于使用大模型最重要的上下文长度限制&#xff0c;Llama 2 也翻了一倍。 在本文&#xff0c;我们将紧跟趋…

回归预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现TCN-LSTM时间卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.Matlab实现TCN-LSTM时间卷积神经网络结合长…

pytorch学习——第二个模型(逻辑回归)

参考该博客系统学习Pytorch笔记二&#xff1a;Pytorch的动态图、自动求导及逻辑回归 c l a s s { 0 0.5 > y 1 0.5 ≤ y class\left\{ \begin{array}{rcl} 0 & & {0.5 > y}\\ 1 & & {0.5 \le y}\\ \end{array} \right. class{01​​0.5>y0.5≤y​ 根…

伦敦金投资仓位控制的方法

留意本栏目过去的文章的朋友都会发现&#xff0c;其实小编认为资金管理很重要&#xff0c;甚至重要性超过技术分析找到入场机会。在资金管理中&#xff0c;关于仓位的控制是一门很大的学问&#xff0c;在伦敦金投资中&#xff0c;仓位的控制关系到我们盈亏的多少&#xff0c;甚…

数据仓库设计理论

数据仓库设计理论 一、数据仓库基本概念 1.1、数据仓库介绍 数据仓库是一个用于集成、存储和分析大量结构化和非结构化数据的中心化数据存储系统。它旨在支持企业的决策制定和业务分析活动。 1.2、基本特征 主题导向&#xff1a;数据仓库围绕特定的主题或业务领域进行建模…

探索物联网HMI的端口转发和NAT功能

前言 端口转发和NAT功能常用于内网穿透&#xff0c;实现内部网络和外部网络之间的数据传输&#xff0c;工作人员通过外部网络便可安全访问到内网设备&#xff0c;实现设备的状态监测。接下来小编将为大家介绍支持端口转发和NAT功能的虹科物联网HMI是如何帮助用户实现内网穿透。…

2023年Q2京东洗衣机行业品牌销售排行榜(京东销售数据分析)

鲸参谋电商大数据2023年Q2京东平台“洗衣机”品类完整销售数据榜单出炉&#xff01; 根据鲸参谋电商数据显示&#xff0c;今年Q2京东平台上洗衣机行业的销量超过380万&#xff0c;环比下降19%&#xff0c;同比上升约2%&#xff1b;行业销售额达63亿&#xff0c;环比下降约14%&a…

Vue3通透教程【十六】TS编译配置

文章目录 &#x1f31f; 写在前面&#x1f31f; 初始化配置文件⭐ target⭐ module⭐ lib⭐ types/node⭐ include⭐ outDir&#x1f31f; 写在最后 &#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更…

LeetCode383.赎金信

383.赎金信 哈希解法 题目中说明只有小写字母&#xff0c;那我们可以采取用时间换空间的策略&#xff0c;用一个长度为26的数组来记录magazine中字母出现的次数 然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母 依然是数组在哈希法中的应用 不了解的…

Maven 基础之简介,基础配置

Maven 基本概念 Maven 是基于项目对象模型&#xff08;Project Object Model&#xff09;&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的软件项目管理工具。 Maven 主要有 2 个功能&#xff1a;「项目构建」和「依赖管理」。 &#x1f58b; 说…

基于 Junit 的接口自动化测试框架实现

目录 前言&#xff1a; 分层的自动化测试 接口测试的意义 接口测试框架选型 我们封装的接口测试框架 接口测试关键实践 测试代码规范 (仅供参考) 前言&#xff1a; 基于JUnit的接口自动化测试框架可以实现对接口进行自动化测试&#xff0c;并提供了丰富的断言和报告功能…

分类预测 | MATLAB实现基于Attention-LSTM的数据分类预测多特征分类预测(长短期记忆网络融合注意力机制分类预测,含混淆矩阵图、分类图)

分类预测 | MATLAB实现基于Attention-LSTM的数据分类预测多特征分类预测(长短期记忆网络融合注意力机制分类预测&#xff0c;含混淆矩阵图、分类图) 目录 分类预测 | MATLAB实现基于Attention-LSTM的数据分类预测多特征分类预测(长短期记忆网络融合注意力机制分类预测&#xff…

【JAVA】数组的概念;数组的使用;引用;内存分区;数组练习题

&#x1f349;内容专栏&#xff1a;【JAVA从0到入门】 &#x1f349;本文脉络&#xff1a;数组的概念&#xff1b;数组的使用&#xff1b;引用&#xff1b;内存分区&#xff1b;数组练习题 &#x1f349;本文作者&#xff1a;Melon_西西 &#x1f349;发布时间 &#xff1a;202…

Python案例分析|使用Python图像处理库Pillow处理图像文件

本案例通过使用Python图像处理库Pillow&#xff0c;帮助大家进一步了解Python的基本概念&#xff1a;模块、对象、方法和函数的使用 使用Python语言解决实际问题时&#xff0c;往往需要使用由第三方开发的开源Python软件库。 本案例使用图像处理库Pillow中的模块、对象来处理…

JVM学习之内存与垃圾回收篇1

文章目录 1 JVM与Java体系结构1.0 Java发展重大事件1.1 虚拟机和Java虚拟机1.3 JVM整体结构1.4 Java代码执行流程1.5 JVM架构模型1.6 JVM的生命周期1.7 JVM发展历程 2 类加载子系统2.1 ClassLoader2.2 用户自定义类加载器2.2.1 为什么需要自定义类加载器2.2.2 自定义类加载器的…

kafka第三课-可视化工具、生产环境问题总结以及性能优化

一、可视化工具 https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 下载解压之后&#xff0c;编辑该文件&#xff0c;修改zookeeper地址&#xff0c;也就是kafka注册的zookeeper的地址&#xff0c;如果是zookeeper集群&#xff0c;以逗号分开 vi conf/application.conf 启…