C#从零搭建微信机器人(二)分词匹配组件【jieba】的使用

news2024/12/25 9:32:30

上篇文章我们讲解了微信机器人的环境搭建及演示,这期我们来说一下其中在模糊匹配搜索时用到的Segement子项目,也就是其中的中文分词匹配器。

一、原理介绍:

其实这个子项目中的分词插件和solr的IK分词器类似,都是可以支持将一句完整的中文拆成多个单词。例如:我是中国人。 分词器会拆分成:我,是,中国,中国人。然后将拆分的词组和你要匹配的内容进行一个相似度匹配。如果超过预设的匹配值。则匹配成功。

二、分词组件的引用:

首先我们需要再创建一个子项目Segements,然后在项目中引用jieba这个组件,这里需要使用nuget(你可以理解是c#的maven),在nuget中搜索jieba,然后选择安装。
在这里插入图片描述
安装后在项目中查看是否引用到,如下图所示
在这里插入图片描述

三、使用代码详解

using JiebaNet.Segmenter.PosSeg;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Segments
{
    public class Segments
    {
       public static double CalculateCosineSimilarity(List<String> array1, List<String> array2)
        {
            Dictionary<string, int> wordCount1 = new Dictionary<string, int>();
            Dictionary<string, int> wordCount2 = new Dictionary<string, int>();

            foreach (string word in array1)
            {
                if (wordCount1.ContainsKey(word))
                    wordCount1[word]++;
                else
                    wordCount1[word] = 1;
            }

            foreach (string word in array2)
            {
                if (wordCount2.ContainsKey(word))
                    wordCount2[word]++;
                else
                    wordCount2[word] = 1;
            }

            double dotProduct = 0;
            double magnitude1 = 0;
            double magnitude2 = 0;

            foreach (KeyValuePair<string, int> entry in wordCount1)
            {
                int count1 = entry.Value;
                int count2 = wordCount2.ContainsKey(entry.Key) ? wordCount2[entry.Key] : 0;

                dotProduct += count1 * count2;
                magnitude1 += count1 * count1;
            }

            foreach (KeyValuePair<string, int> entry in wordCount2)
            {
                int count2 = entry.Value;
                magnitude2 += count2 * count2;
            }

            magnitude1 = Math.Sqrt(magnitude1);
            magnitude2 = Math.Sqrt(magnitude2);

            if (magnitude1 == 0 || magnitude2 == 0)
                return 0;

            return dotProduct / (magnitude1 * magnitude2);
        }

        private static string getErrorCode(string question)
        {
            string pattern = @"\d+";
            Match match = Regex.Match(question, pattern);
            if (match.Success)
            {
                return match.Value;
            }
            else
            {
                return "";
            }
        }

        public static List<JObject> selectQuestion(string userInput, List<JObject> param2)
        {
            //问题答案表
            var questionAnswerTable = new Dictionary<string, JObject> { };
            String temp = getErrorCode(userInput);
            if (!temp.Equals(""))
            {
                userInput = temp;
            }
            for (int i = 0; i < param2.Count; i++)
            {
                String matchStr = "";
                    matchStr = ""+param2[i]["errorCode"] + param2[i]["errorDetail"];

                if (!questionAnswerTable.ContainsKey(matchStr)) { 
                questionAnswerTable.Add(matchStr, param2[i]);
                }
            }


            //  用户输入问题
            //  string userInput = "好像是什么检查好像失败不正确?";
            //使用PosSegmenter对用户输入进行分词和词性标注

            PosSegmenter segmenter = new PosSegmenter();
            var segments = segmenter.Cut(userInput);
            //构造分词列表
            var queryTokens = segments.Select(segment => segment.Word).ToList();
            //在问题答案表中进行匹配
            string bestMatchAnswer = "";

            String mMostMatch_Sentence = "";
            //*******************************【相似匹配度设置】**************************************
            double mMostMatch_Sentence_double = 0.1;
            List<JObject> answerList = new List<JObject>();
            foreach (var kvp in questionAnswerTable)
            {
                var question = kvp.Key;
                var answer = kvp.Value;
                //使用PosSegmenter对问题进行分词和词性标注
                var questionSegments = segmenter.Cut(question);
                //构造问题的分词列表
                var questionTokens = questionSegments.Select(segment => segment.Word).ToList();
                //进行分词匹配,这里可以使用自定义的相似度算法

                //if (queryTokens.SequenceEqual(questionTokens))
                {
                    if (mMostMatch_Sentence_double < CalculateCosineSimilarity(queryTokens, questionTokens))
                    {
                        mMostMatch_Sentence_double = CalculateCosineSimilarity(queryTokens, questionTokens);
                        mMostMatch_Sentence = kvp.Key;
                        if (answerList.Count >= 10)
                        {
                            break;
                        }
                        JObject tempObj =  kvp.Value;
                        tempObj.Add("similar",mMostMatch_Sentence_double);
                        answerList.Add(kvp.Value);
                    }
                    else
                    {

                    }


                    //bestMatchAnswer = answer;
                    // break;
                }
            }

            //string[] array1 = { "我", "爱", "自然语言处理技术" };
            //string[] array2 = { "我", "喜欢", "自然语言处理技术" };

            //double similarity = CalculateCosineSimilarity(array1, array2);
            //Console.WriteLine("相似度: " + similarity);
            answerList = answerList.OrderByDescending(obj => (int)obj["similar"]).ToList();
            return answerList;
        }
    }
}

主要的使用逻辑在这个方法中:
List <JObject> selectQuestion(string userInput, List<JObject> param2)
传入参数有两个:用户提出的问题,和待匹配语料集合。
返回参数:匹配到的语料集合。

            var questionAnswerTable = new Dictionary<string, JObject> { };

这里的questionAnswerTable的key为待匹配的问题,value为整个问题实体。下面会先填充这个集合。然后遍历它与userInput进行匹配。

 //*******************************【相似匹配度设置】**************************************
            double mMostMatch_Sentence_double = 0.1;

注意这里是配置相似度的地方。大家在调试的时候可以通过修改它来控制匹配的精确程度。

差不多就是这些。剩下的代码基本都有注释。大家可以慢慢学习。

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

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

相关文章

TP4066L是一款完整的单节锂离子电池采用恒定电流/恒定电压线性充电器。

TP4066L 采用ESOP8/DFN2*2-8封装 1A线性锂离子电池充电器 描述&#xff1a; TP4066L是一款完整的单节锂离子电池采用恒定电流/恒定电压线性充电器。其底部带有散热片的ESOP8DFN2*2-8封装与较少的外部元件数目使得TP4066L成为便携式应用的理想选择。TP4066L可以适合USB电源和适…

桐庐县数据资源管理局领导一行莅临美创科技并带来感谢信

11月23日&#xff0c;浙江桐庐县数据资源管理局党组成员、副局长朱勃一行到访美创科技总部参观交流&#xff0c;并带来感谢信&#xff0c;对美创圆满完成护航亚运政务外网数据网站安全保障工作表示充分肯定。美创科技联合创始人、副总裁胡江涛等进行热情接待并开展交流座谈。 图…

微信ipad协议8.0.37/8.0.40新版本

功能如下&#xff0c;如有定制功能请在官网联系我们。 登录 创建新设备 获取登录er维码 执行登录 注销登录 消息 消息回调 消息撤回 发送app类型消息 发送小程序 发送CDN文件 发送CDN图片 发送CDN视频 发送emoji 发送文件 发送图片 发送链接 发送消息 发送视频 发送语音 …

2021年全国a级景区数据,shp+csv数据均有

大家好~这周将和大家分享关于文化旅游和城乡建设相关的数据&#xff0c;希望大家喜欢~ 今天分享的是2021年全国a级景区数据&#xff0c;数据格式有shpcsv&#xff0c;几何类型为点&#xff0c;已经经过清洗加工&#xff0c;可直接使用&#xff0c;以下为部分字段列表&#xff…

无人机遥控器方案定制_MTK平台无人设备手持遥控终端PCB板开发

随着科技的不断发展和无人机技术的逐步成熟&#xff0c;无人机越来越受到人们的关注。作为一种高新技术&#xff0c;无人机的应用范围不断拓展&#xff0c;包括农业、环境监测、城市规划、运输物流等领域。同时&#xff0c;无人机的飞行控制技术也得到了不断的优化和提升。 早…

前端管理制度

数据运营中心的管理形式&#xff1a; 数据运营中心的管理形式 竖向是各小组 横向是项目管理 负责人的定位&#xff1a; 只是工作的内容不同&#xff0c;没有上下级之分 帮助组员找到适合的位置&#xff0c;帮助大家解决问题&#xff0c;给大家提供资源 前端组的工作形式&am…

Doris-Routine Load(二十七)

例行导入&#xff08;Routine Load&#xff09;功能为用户提供了一种自动从指定数据源进行数据导入的功能。 适用场景 当前仅支持从 Kafka 系统进行例行导入&#xff0c;使用限制&#xff1a; &#xff08;1&#xff09;支持无认证的 Kafka 访问&#xff0c;以及通过 SSL 方…

二维码智慧门牌管理系统:实现高效信息管理

文章目录 前言一、 功能升级优势 前言 随着科技的飞速发展和人们生活节奏的加快&#xff0c;传统的门牌管理系统已经不再适应现代社会的需求。为了解决这一问题&#xff0c;全新的二维码智慧门牌管理系统升级解决方案应运而生&#xff0c;为用户带来前所未有的便捷与高效。 一…

1m照片手机怎么拍?一分钟解决!

我们都知道现在的手机像素特别好&#xff0c;随便拍一张照片都是2-3MB&#xff0c;有时候上课或者会议要拍很多照片&#xff0c;这些照片其实又不需要如此清晰&#xff0c;就会特别占内存&#xff0c;下面就向大家介绍三种好用的办法。 方法一&#xff1a;拍完照后手机截图进行…

【开源】基于JAVA的海南旅游景点推荐系统

项目编号&#xff1a; S 023 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S023&#xff0c;文末获取源码。} 项目编号&#xff1a;S023&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四…

训练 CNN 对 CIFAR-10 数据中的图像进行分类

1. 加载 CIFAR-10 数据库 import keras from keras.datasets import cifar10# 加载预先处理的训练数据和测试数据 (x_train, y_train), (x_test, y_test) cifar10.load_data() 2. 可视化前 24 个训练图像 import numpy as np import matplotlib.pyplot as plt %matplotlib …

【Java开发基础】intellij IDEA快速配置JDBC驱动连接MySQL数据库并查询数据,其实真的很简单,我5分钟就学会了!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

多功能音乐沙漏的设计与实现

【摘要】随着当今社会快节奏生活的发展&#xff0c;当代大学生越来忽视时间管理的重要性&#xff0c;在原本计划只看几个视频只玩几个游戏的碎片化娱乐中耗费了大量的时光&#xff0c;对于自己原本的学习生活产生了巨大的影响。为更加有效的反映时间的流逝&#xff0c;特设计该…

canvas基础:绘制线段,绘制多边形

canvas实例应用100 专栏提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。 canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重要的帮助。 文章目录 使用…

TDA4开发环境Docker化

文章目录 背景1. TDA4X Linux SDK编译环境镜像构建1.1 安装SDK1.2 验证制卡1.2.1 出现的问题:1.3 验证编译1.3.1 出现的问题2. TDA4X Linux-RT SDK编译环境镜像构建2.1 安装SDK2.2 出现的问题参考背景 开始阅读本篇前,假设你已经对docker有了一定了解,且有过docker换件搭建…

优思学院|5S不只是清洁,但却离不开清洁!

很多说5S不止是清洁和搞卫生那么简单&#xff0c;相信有正规地学习过5S的人都应该深切了解。 不过&#xff0c;5S之中的确包括了清理、清洁的步骤&#xff0c;5S&#xff0c;也被称为“五常法则”或“五常法”&#xff0c;它包含了&#xff1a; 整理&#xff08;SEIRI&#x…

8.统一异常处理 + 统一记录日志

目录 1.统一异常处理 2.统一记录日志 1.统一异常处理 在 HomeController 类中添加请求方法&#xff08;服务器发生异常之后需要统一处理异常&#xff0c;记录日志&#xff0c;然后转到 500 页面&#xff0c;需要人工处理重定向到 500 页面&#xff0c;提前把 500 页面请求访问…

Containerd Container管理功能解析

Containerd Container管理功能解析 container是containerd的一个核心功能&#xff0c;用于创建和管理容器的基本信息。 本篇containerd版本为v1.7.9。 更多文章访问 https://www.cyisme.top 本文从ctr c create命令出发&#xff0c;分析containerd的容器及镜像管理相关功能。 …

01 项目架构

关于我 曾经就职于蚂蚁金服&#xff0c;多年的后端开发经验&#xff0c;对微服务、架构这块研究颇深&#xff0c;同时也是一名热衷于技术分享、拥抱开源技术的博主。 个人技术公众号&#xff1a;码猿技术专栏个人博客&#xff1a;www.java-family.cn 前期一直在更新《Spring…

什么是美颜sdk?视频直播美颜sdk技术深度剖析

美颜sdk可以通过实时处理图像&#xff0c;提升主播或用户在视频直播中的外观。通过美颜sdk接口调用可以轻松实现美颜效果。美颜sdk的核心目标是在保持图像真实性的同时&#xff0c;为用户创造出最理想的美化效果。 一、美颜sdk的技术实现 1.面部识别技术&#xff1a;美颜sdk…