IK分词器热刷新词库实践分享

目录

前言

什么是分词器?

ik分词器简介

ik分词器和默认分词器的对比

ik分词器介绍

ik分词器的分词问题

自定义词库

主配置解说

通过配置文件自定义词库

Step1: 新建自定义分词库

Step2: 将我们的自定义词添加到ik的配置文件中

Step3: 重启es,查看分词

配置化方式自定义词库存在的问题

热更新词库方案

ik分词器热更新词库实践

IK分词器源码下载

导入maven工程

源码中词典加载大体流程

修改源码

修调整elasticsearch.version

在pom文件中添加mysql驱动器依赖

创建数据库配置文件jdbc-reload.properties,放在IK项目的config文件夹下

新增HotDictReloadThread类

修改org.wltea.analyzer.dic.Dictionary#loadMainDict方法

修改org.wltea.analyzer.dic.Dictionary#loadStopWordDict方法

org.wltea.analyzer.dic.Dictionary#initial调用HotDictReloadThread方法

修改插件的权限

建立数据库表

打包

加入依赖

package

安装

测试验证

关键词验证

1. “水平思维”关键词验证

2. 网络流行语“他是显眼包”验证

3. 网络流行语“香菇蓝瘦”验证

停用词验证

1. “我是熊二呢”短语验证

2. “一个老流氓”短语验证

总结


前言

本篇文章介绍了ElasticSearch分词器相关内容,介绍了什么是分词器,什么是ik分词器,ik分词器目前存在的问题以及如何通过修改ik分词器的源码来实现热更新词库。

什么是分词器?

Elasticsearch是基于倒排索引来实现搜索功能,而倒排索引的基础就是分词。Elasticsearch默认的分词器支持英文的分词,因为分词很简单,基本基于空格就可以分出来,而汉语的分词则困难很多。分词是把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个 匹配操作。

ik分词器简介

ik分词器和默认分词器的对比

默认的中文分词器是将每个字看成一个词,比如"中国人很喜欢吃油条",会被分为“中 国 人 很 喜 欢 吃 油 条”这几个字,而采用IK分词器 可以分为“中国人 很 喜欢 吃 油条”,看下上面分词后的结果,肯定是 ik 的分词结果比较符合中文。

以“中国人很喜欢吃油条”这个句话为例,标准分词器会将这句话分为:“中”  “国”  “人”  “很”  “喜” “欢” “吃”  “油”  “条”,例如:

image.png

可以看出来,很不符合中文词的表述习惯,因为这段话不仅仅可以分为这10个字,还可以组成如:“中国”,“中国人”,“喜欢”等等。

我们来看看ik分词器的分词效果,以ik分词器的ik_max_word为例,“中国人很喜欢吃油条”这句话就可以拆成很多种,如:“中国人”,“中国”,“国人”,“很喜欢”等,例如:

image.png

从上面分词后的结果可以看出,肯定是ik分词结果比较符合中文习惯

ik分词器介绍

在搜索引擎领域,比较成熟和流行的中文分词器,就是ik分词器,它提供了2种分词的模式,分别为ik_max_word和ik_smart

  • ik_max_word:将需要分词的文本做最小粒度的拆分,尽量分更多的词

  • ik_smart:将需要分词的文本做最大粒度的拆分

ik_max_word 的分词效果

语句

POST _analyze
{
  "text": ["中国人很喜欢吃油条"], 
  "analyzer": "ik_max_word"
}

结果

{
  "tokens" : [
    {
      "token" : "中国人",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "中国",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "国人",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "很喜欢",
      "start_offset" : 3,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "喜欢吃",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "喜欢",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "吃油",
      "start_offset" : 6,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "油条",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 7
    }
  ]
}

ik_smart的分词效果

语句

POST _analyze
{
  "text": ["中国人很喜欢吃油条"], 
  "analyzer": "ik_smart"
}

结果

{
  "tokens" : [
    {
      "token" : "中国人",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "很喜欢",
      "start_offset" : 3,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "吃",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "CN_CHAR",
      "position" : 2
    },
    {
      "token" : "油条",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

ik分词器的分词问题

虽然通过ik_smart和ik_max_word可以做到中文分词效果,但是如果对于一些网络流行语或者我们公司内部的一些自定义的短语,无法做到分词的效果,如网络流行语:“香菇蓝瘦”,我们期望的是“香菇蓝瘦”也是其中的一个词,然后并没有

image.png

如公司的一些短语,如“星云思维”、“水平思维”,我们期望它成为一个完整的词,然后确没有

image.png

image.png

那么如何去按照我们定义的词去进行分词自适应呢?

自定义词库

主配置解说

ik配置文件地址:/usr/share/elasticsearch/plugins/ik/config 目录下都是存放配置文件

image.png

下面是这些主要配置文件含义:

  • IKAnalyzer.cfg.xml:用来配置自定义词库

  • main.dic:原生内置的中文词库,总共有27万多条,只要是这些单词,都会被分在一起,每个单词占据一行

  • quantifier.dic:放了一些单位相关的词

  • suffix.dic:放了一些后缀

  • surname.dic:中国的姓氏

  • stopword.dic:英文停用词

  • preposition.dic:介词词典

IKAnalyzer.cfg.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict"></entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

ik原生最重要的两个配置文件

  • main.dic:包含了原生的中文词语,会按照这个里面的词语去分词

  • stopword.dic:包含了英文的停用词。custom/ext_stopword.dic 中包含了中文的一些扩展词

什么是停用词?与其他词相比,功能词没有什么实际含义,比如'the'、'is'、'at'、'which'、'on'等。

通过配置文件自定义词库

通过配置化的方式新增词库主要分为3步,分别为:

1. 新建自定义分词库

2. 添加到ik的配置文件中

3. 重启es,查看分词

下面介绍一下这3步的具体配置

Step1: 新建自定义分词库

我们在/usr/share/elasticsearch/plugins/ik/config目录下新建一个文件夹custom,然后建一个dic文件(zj.dic),如:

image.png

把这些热门词放到该文件中,如:

image.png

Step2: 将我们的自定义词添加到ik的配置文件中

image.png

Step3: 重启es,查看分词

重启es,然后在kibana上查看分词

image.png

image.png

这样我们通过配置化的方式实现了分词效果

配置化方式自定义词库存在的问题

我们使用配置化的方式自定义词库的时候,每次都得重启,而且得逐个节点依次修改,是不是有点不方便呢?这种方式的主要缺点有:

  • 每次添加完词库,都要重启es才能生效,非常麻烦

  • es是分布式的,生产环境一般几十个个es节点,每次添加完词库,然后重启节点,可想而知......

热更新词库方案

目前ik分词器热更新词库的方案有两种

  • 修改ik分词器源码,后台启动一个线程,每隔一段时间从MySQL数据库中,抽取数据,进行自动加载词库

  • 基于ik分词器原生的热更新方案,部署一个web服务器,提供一个http接口,通过modified和tag两个http响应头,来提供词语的热更新

推荐第一种方案修改ik分词器源码, 第二种方案ik git社区官方都不建议采用,不太稳定。下面也是围绕着第一种方案进行源码改造来实现热更新词库

ik分词器热更新词库实践

IK分词器源码下载

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

我选择的版本是7.9.3的版本,选中图中的Source code(zip)进行下载

image.png

导入maven工程

image.png

源码中词典加载大体流程

ik分词器实现了ES的AnalysisPlugin接口,通过工厂方法初始化词典,加载默认配置

image.png

image.png

image.png

默认会根据DefaultConfiguration找到主词典和中文量词词典路径,同时DefaultConfiguration会根据classpath下配置文件IKAnalyzer.cfg.xml,找到扩展词典和停止词典路径,用户可以在该配置文件中配置自己的扩展词典和停止词典。找到个词典路径后,初始化Dictionary.java,Dictionary是单例的。在Dictionary的构造函数中加载词典。Dictionary是IK的词典管理类,真正的词典数据是存放在DictSegment中,该类实现了一种树结构,如下图。

image.png

举个例子,要对字符串“A股市场”进行分词,首先拿到字符串的第一个字符'A',在上面的tree中可以匹配到A节点,然后拿到字符串第二个字符'股',首先从前一个节点A往下找,我们找到了股节点,股是一个终点节点。所以,“A股“是一个词。

Dictionary加载主词典,以,将主词典保存到它的_MainDict字段中,加载完主词典后,立即加载扩展词典,扩展词典同样保存在_MainDict中。

image.png

fillSegment方法是DictSegment加载单个词的核心方法,charArray是词的字符数组,先是从存储节点搜索词的第一个字符开始,如果不存在则创建一个节点用于存储第一个字符,后面递归存储,直到最后一个字符。

image.png

image.png

因此,我们只需要在加载加载主词典及扩展词典的时候,通过fillSegment方法填充词典即可,下面介绍具体的源码修改流程。

修改源码

简单说下整体思路: 开启一个后台线程,扫描mysql中定义的表,加载数据。

修调整elasticsearch.version

本次下载的是7.9.3版本,但是下载下来后是7.4.0版本,因为我用的是7.9.3版本的ES这里需要改一下版本

image.png

修改为:

image.png

在pom文件中添加mysql驱动器依赖

<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>

创建数据库配置文件jdbc-reload.properties,放在IK项目的config文件夹下

jdbc.url=jdbc:mysql://10.xxx.xxx.XX:3306/canal-test?serverTimezone=UTC
jdbc.user=ueranme
jdbc.password=password
jdbc.reload.extend.sql=select word from es_extra_main
jdbc.reload.stop.sql=select word from es_extra_stopword
# 间隔时间 毫秒
jdbc.reload.interval=10000

reload间隔,1秒钟轮训一次

新增HotDictReloadThread类

在org.wltea.analyzer.dic目录下,新增一个HotDictReloadThread类,死循环去调用Dictionary.getSingleton().reLoadMainDict(),重新加载词典,HotDictReloadThread结构如下:

package org.wltea.analyzer.dic;

import org.wltea.analyzer.help.ESPluginLoggerFactory;


/**
 * @author 
 * @version 1.0
 * @date 2024/1/12 下午7:21
 * <p>Copyright: Copyright (c) 2024<p>
 */
public class HotDictReloadThread implements Runnable {

    private static final org.apache.logging.log4j.Logger logger = ESPluginLoggerFactory.getLogger(HotDictReloadThread.class.getName());

    @Override
    public void run() {
        while (true) {
            logger.info("[======HotDictReloadThread======] begin to reload hot dict from dataBase......");
            Dictionary.getSingleton().reLoadMainDict();
        }
    }
}

看下reLoadMainDict这个方法的执行逻辑

image.png

reLoadMainDict方法的核心逻辑有两块:

  • tmpDict.loadMainDict():加载主词库

  • tmpDict.loadStopWordDict():加载停用词词库

由此可以看出,只要我们把读取数据库的逻辑放到这两个方法里面就可以了,下面我们分别来修改这两个方法。

修改org.wltea.analyzer.dic.Dictionary#loadMainDict方法

通过修改loadMainDict来读取MySQL中的主词库,来实现热加载,修改的点如下:

增加this.loadMySQLExtDict(),该方法就是将MySQL表中的数据加载到词库中

image.png

loadMySQLExtDict()方法的主体逻辑是通过JDBC查询MySQL

代码如下:

private static Properties prop = new Properties();

static {
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        logger.error("error", e);
    }
}

/**
 * 从mysql加载热更新词典
 */
private void loadMySQLExtDict() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
        Path file = PathUtils.get(getDictRoot(), "jdbc-reload.properties");
        prop.load(new FileInputStream(file.toFile()));

        logger.info("[==========]jdbc-reload.properties");
        for(Object key : prop.keySet()) {
            logger.info("[==========]" + key + "=" + prop.getProperty(String.valueOf(key)));
        }

        logger.info("[==========]query hot dict from mysql, " + prop.getProperty("jdbc.reload.extend.sql") + "......");

        conn = DriverManager.getConnection(
                prop.getProperty("jdbc.url"),
                prop.getProperty("jdbc.user"),
                prop.getProperty("jdbc.password"));
        stmt = conn.createStatement();
        rs = stmt.executeQuery(prop.getProperty("jdbc.reload.extend.sql"));

        while(rs.next()) {
            String theWord = rs.getString("word");
            logger.info("[==========]hot word from mysql: " + theWord);
            _MainDict.fillSegment(theWord.trim().toCharArray());
        }

        Thread.sleep(Integer.valueOf(String.valueOf(prop.get("jdbc.reload.interval"))));
    } catch (Exception e) {
        logger.error("erorr", e);
    } finally {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
        if(stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
    }
}

修改org.wltea.analyzer.dic.Dictionary#loadStopWordDict方法

在loadStopWordDict方法中增加loadMySQLStopWordDict,该方法实现从MySQL中加载停用词到词典中

image.png

loadMySQLStopWordDict实现代码为:

/**
 * 从mysql加载停用词
 */
private void loadMySQLStopWordDict() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
        Path file = PathUtils.get(getDictRoot(), "jdbc-reload.properties");
        prop.load(new FileInputStream(file.toFile()));

        logger.info("[====loadMySQLStopWordDict======] jdbc-reload.properties");
        for(Object key : prop.keySet()) {
            logger.info("[==========]" + key + "=" + prop.getProperty(String.valueOf(key)));
        }

        logger.info("[==========]query hot stop word dict from mysql, " + prop.getProperty("jdbc.reload.stop.sql") + "......");

        conn = DriverManager.getConnection(
                prop.getProperty("jdbc.url"),
                prop.getProperty("jdbc.user"),
                prop.getProperty("jdbc.password"));
        stmt = conn.createStatement();
        rs = stmt.executeQuery(prop.getProperty("jdbc.reload.stop.sql"));

        while(rs.next()) {
            String theWord = rs.getString("word");
            logger.info("[==========]hot stop word from mysql: " + theWord);
            _StopWords.fillSegment(theWord.trim().toCharArray());
        }

        Thread.sleep(Integer.valueOf(String.valueOf(prop.get("jdbc.reload.interval"))));
    } catch (Exception e) {
        logger.error("error", e);
    } finally {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
        if(stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                logger.error("error", e);
            }
        }
    }
}

org.wltea.analyzer.dic.Dictionary#initial调用HotDictReloadThread方法

image.png

修改插件的权限

image.png

grant {
  // needed because of the hot reload functionality
  permission java.net.SocketPermission "*", "connect,resolve";
  permission java.lang.RuntimePermission "setContextClassLoader";
};

如何还不行的话,切换到/usr/share/elasticsearch/jdk/conf/security目录下,在java.policy文件最后一行加上

permission java.lang.RuntimePermission "setContextClassLoader";

如果还有java.net.SocketPermission的报错,则在java.policy文件的后面再加上

permission java.net.SocketPermission "*", "connect,resolve";

image.png

建立数据库表

CREATE TABLE `es_extra_main`
(
    `id`          int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `word`        varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '词',
    `is_deleted`  tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
    `update_time` timestamp(6)                       NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP (6) COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `es_extra_stopword`
(
    `id`          int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `word`        varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '词',
    `is_deleted`  tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已删除',
    `update_time` timestamp(6)                       NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP (6) COMMENT '更新时间',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

打包

加入依赖

将MySQL的jar包依赖加入进来,否则打包会缺少jar包保持错。

image.png

<include>mysql:mysql-connector-java</include>

package

打包成zip文件,然后加压成文件夹

image.png

安装

将elasticsearch-analysis-ik-7.9.3.zip文件拷贝到/usr/share/elasticsearch/plugins/ik目录下:

cp elasticsearch-analysis-ik-7.9.3.zip /usr/share/elasticsearch/plugins/ik/

解压

unzip elasticsearch-analysis-ik-7.9.3.zip

image.png

然后重启es和kibana,可以看到es已经开始加载词库了

image.png

测试验证

在数据库表中中新增下面自己的想要的关键词,然后去Kibana中做测试验证

关键词验证

1. “水平思维”关键词验证

未在数据中插入词库验证

image.png

在数据中插入词库验证,插入“水平思维”

image.png

image.png

分词的效果

image.png

2. 网络流行语“他是显眼包”验证

在数据中插入网络流行语“显眼包”验证,插入“他是显眼包”

插入之前

image.png

数据库中增加“显眼包”,验证

image.png

image.png

3. 网络流行语“香菇蓝瘦”验证

image.png

image.png

image.png

停用词验证

停用词指的是有些词是关键词,但是出于某些业务场景,不想使用这些关键词被检索到,可以将这些词语放到停用词典

1. “我是熊二呢”短语验证

验证前,测试短语“我是熊二呢”

image.png

我们将“呢”、“二”放到停用词中

image.png

在kibana上验证,发现“呢”、“二”已经没了

image.png

2. “一个老流氓”短语验证

验证前,测试短语“一个老流氓”,分词后的效果为:

image.png

我们发现“流氓”也在其中,对于这种污秽的言辞,我们希望屏蔽它,营造一个良好的网络环境,我们将“流氓”加到停用词库中,再进行测试

image.png

我们再次运行,发现“流氓”已经没了,达到了我们验证的效果

image.png

总结

本文主要讲解了什么是ik分词器,如何通过配置化的方式实现自定义词库,配置化方式存在的一些问题,以及如何通过修改ik分词器源码来实现扩展词库以及停用词库热刷新,该实践证明了通过该方案实现的可行性,后续有项目需要基于es分词器实现热刷新,可以借鉴。

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

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

相关文章

css 文字下划线 text-decoration

背景&#xff1a; 在某些时候需要给文字添加特殊样式。使用 text-decoration: underline; 来为段落文字添加下划线。也有其它文本装饰样式&#xff0c;例如&#xff1a; none&#xff1a;无装饰&#xff08;去掉装饰&#xff09;overline&#xff1a;上划线line-through&…

【学习笔记】MySQL(Ⅱ)

MySQL(Ⅱ) 7、 进阶篇 —— 存储引擎 7.1、MySQL 体系结构 7.2、存储引擎 7.2.1 InnoDB 7.2.2 MyISAM 7.2.3 Memory 7.2.4 InnoDB、MyISAM、Memory 的比较8、 拓展篇 —— 在 Linux 上安装数据库9、进阶篇 —— 索引 …

快速欧氏聚类与普通欧氏聚类比较

1、前言 文献《FEC: Fast Euclidean Clustering for Point Cloud Segmentation》介绍了一种快速欧氏聚类方法,大概原理可以参考如下图,具体原理可以参考参考文献。 2、时间效率比较:快速欧氏聚类VS普通欧氏聚类 网上搜集的快速欧式聚类,与自己手写的普通欧式聚类进行对比,…

MapStruct对象转换

MapStruct是一个Java注解处理器&#xff0c;用于简化对象的转换 遇到的问题&#xff1a; java: Internal error in the mapping processor: java.lang.NullPointerException 解决方案&#xff1a;修改编辑器配置 -Djps.track.ap.dependenciesfalse

简单通用防篡改水印组件封装(vue3)

一、项目结构 二、项目代码 1.App.vue <template><div class"container"><Watermark text"版权所有"><div class"content"></div></Watermark><Watermark text"禁止转载" style"backgr…

docker 中 File Sharing 和Volumes 的区别

在 Docker 中&#xff0c;File Sharing 和 Volumes 都涉及到将文件和目录从主机系统映射到容器中&#xff0c;但它们的用途和实现方式有一些重要的区别&#xff1a; 一、简介 File Sharing 是 Docker Desktop 在 Windows 和 macOS 上的一项功能&#xff0c;允许你将主机文件系…

了解振弦采集仪在建筑物安全监测中的应用与研究

了解振弦采集仪在建筑物安全监测中的应用与研究 摘要&#xff1a;河北稳控科技振弦采集仪是一种常用的结构物安全监测设备&#xff0c;广泛应用于建筑物、桥梁、塔楼等工程结构的监测。本文将从振弦采集仪的原理、应用案例和研究进展等方面进行详细介绍&#xff0c;以便更好地…

Web开发技术大作业(HTML\CSS\PHP\MYSQL\JS)

从6月13日到6月15日&#xff0c;经过一系列的操作&#xff0c;终于把老师布置的大作业写完了&#xff0c;虽然有很多水分&#xff0c;很多东西都是为了应付&#xff08;特别是最后做的那几个网页&#xff09;&#xff0c;真的是惨不忍睹&#xff0c;不过既然花时间写了&#xf…

振动分析-4-振动传感器的安装部署

参考(电机、减速机、风机)振动传感器部署指南 设备状态监测的测点通常选在设备轴承或靠近轴承的位置&#xff0c;通过在轴向、垂直方向、水平方向部署振动传感器来实现设备振动信号的采集。但在实际工作中&#xff0c;考虑安装空间和硬件成本&#xff0c;部署过程通常被两个问题…

两个方法教你如何查看隐藏文件!

在日常使用电脑的过程中&#xff0c;我们可能会遇到一些被隐藏起来的文件&#xff0c;这些文件可能是由于系统设置、安全考虑或是其他原因而被隐藏。 虽然这些隐藏文件通常不会影响我们日常使用电脑&#xff0c;但在某些情况下&#xff0c;我们可能需要查看或访问这些文件。那…

电脑剪辑软件推荐哪个?分享4款剪辑工具

电脑剪辑软件推荐哪个&#xff1f;在选择电脑剪辑软件时&#xff0c;我们不仅要考虑软件的功能性和易用性&#xff0c;还要关注其是否能够方便地扩充我们的创作资源和技能。优秀的剪辑软件应提供丰富的素材库、模板和插件&#xff0c;让我们能够轻松获取所需的音频、视频、滤镜…

MYSQL数据库安装

一.编译安装MySQL服务 1.安装环境依赖包 2.将安装mysql 所需软件包传到/opt目录下 mysql-boost-5.7.44.tar tar zxvf mysql-boost-5.7.44.tar.gz 3.配置软件模块 cd /opt/mysql-5.7.44/ cmake \ -DCMAKE_INSTALL_PREFIX/usr/local/mysql \ -DMYSQL_UNIX_ADDR/usr/local/mysq…

Java switch case 语句

Java switch case 语句 switch case 语句判断一个变量与一系列值中某个值是否相等&#xff0c;每个值称为一个分支。 语法 switch case 语句语法格式如下&#xff1a; switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任…

05眼动识别软件详情2波形优化-滤波

对应视频链接点击直达 01项目点击下载&#xff0c;可直接运行&#xff08;含数据库&#xff09; 05眼动识别软件详情2 对应视频链接点击直达期望的数据展示数据波形对比如何实现几种常用滤波介绍维纳滤波巴特沃斯滤波器中值滤波排序滤波 推荐 结语其他以下是废话 原始数据的波…

多种总部文件下发方式比较,哪一种既相应业务效率又保证安全?

大型企业在全国甚至全球都会设有分公司、办事处、生产工厂、研发中心等不同形式的分支机构&#xff0c;在日常经营中&#xff0c;存在多种总部文件下发的场景&#xff0c;如将公司战略规划与考核、规章制度、新产品信息及定价策略、业务培训指导材料、客户数据及资料、内部通知…

自学【大模型】的,能骂醒一个算一个!

为啥说胡乱自学大模型的&#xff0c;能骂醒一个算一个。因为很多人学会个AI工具就觉得自己会玩大模型了&#xff0c;其实你才刚入门&#xff01; 想要完全了解大模型&#xff0c;你首先要了解市面上的LLM大模型现状&#xff0c;学习Python语言、Prompt提示工程&#xff0c;然后…

成都跃享未来教育抖音小店,一站式平台!

在如今的教育市场上&#xff0c;成都跃享未来教育咨询有限公司以其独特的经营理念和创新的教育模式&#xff0c;吸引了众多家长和学生的关注。特别是在抖音小店这一新兴电商平台上&#xff0c;跃享未来教育更是展现出了非凡的魅力和潜力&#xff0c;成为了成都教育咨询领域的一…

需要用来做3D家具展示的软件哪个网站更专业?

国内外的3D家具展示软件网站并且值得推荐的也就那么几家&#xff1a; 1、Cedreo&#xff0c;Cedreo 是一个在线3D家居设计平台&#xff0c;适合专业的房屋建筑商、改造商和室内设计师。它允许用户创建2D和3D平面图以及室内外效果图&#xff0c;拥有7000多件可定制的3D家具、材…

视频融合平台LntonCVS视频监控汇聚平台:构建多元接入与智能管理的安防新生态

一、视频融合平台概述 视频融合平台支持多种协议和设备类型的接入&#xff0c;包括GB28181、Onvif、RTSP、RTMP、海康SDK、Ehome、大华SDK、宇视SDK等。它能够统一整合和管理来自不同品牌、不同协议的视频资源&#xff0c;构建视频数据资源池&#xff0c;并通过视频资源目录为…

使用LangChain+Ollama自己做的一个和大语言模型聊天的网站支持上下文对话,学习记录。

0.引言 在自己学习的过程中可以自己做一个和聊天大模型对话的一个小网站&#xff0c;成就感不亚于人生第一次跑完10km。 1.项目介绍 前端代码&#xff1a;Vue3, MarkDownIT. 后端代码&#xff1a;Python3, Fernet库, OpenAPI, LangChain, Ollama. Ollama 本地模型的部署和管理…