通过k-means对相似度较高的语句进行分类
本文介绍了如何使用K-Means算法对相似度较高的语句进行分类,并附上java案例代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化语句数据集List<String> texts = new ArrayList<>();texts.add("如果他不是老师,他就是学生");texts.add("他可能是老师也可能是学生");texts.add("他经常在学校学习");texts.add("他在学校的学习成绩很好");texts.add("老师和学生在上课");texts.add("学校是学习的地方");texts.add("老师收到定金");texts.add("学校塑料袋管理科");texts.add("开心数量肯定两个都是");texts.add("开心的两个孩子");// 设置K值(簇的数量)int K = 3;// 执行K-Means算法List<List<String>> clusters = kMeans(texts, K);// 打印聚类结果for (int i = 0; i < clusters.size(); i++) {System.out.println("Cluster " + (i + 1) + ":");for (String text : clusters.get(i)) {System.out.println(text);}System.out.println();}}public static List<List<String>> kMeans(List<String> texts, int K) {// 随机选择K个语句作为初始簇中心Random random = new Random();List<String> centroids = new ArrayList<>();for (int i = 0; i < K; i++) {centroids.add(texts.get(random.nextInt(texts.size())));}boolean isChanged;List<List<String>> clusters = new ArrayList<>();do {// 创建K个空簇clusters.clear();for (int i = 0; i < K; i++) {clusters.add(new ArrayList<>());}// 分配数据点到最近的簇中心for (String text : texts) {int closestCentroidIndex = 0;double minDistance = Double.MAX_VALUE;for (int i = 0; i < K; i++) {double similarity = 1 - calcTextSim(text, centroids.get(i)); // 使用相似度的补数作为距离if (similarity < minDistance) {minDistance = similarity;closestCentroidIndex = i;}}clusters.get(closestCentroidIndex).add(text);}// 更新簇中心isChanged = false;for (int i = 0; i < K; i++) {String newCentroid = findCentroid(clusters.get(i), centroids.get(i));if (!newCentroid.equals(centroids.get(i))) {isChanged = true;centroids.set(i, newCentroid);}}} while (isChanged);return clusters;}// 计算两个语句的相似度public static double calcTextSim(String text, String targetText) {return ChineseTextRecommender.calcTextSim(text, targetText); // 返回相似度值}// 计算簇的中心点(这里简化为返回簇中第一个元素)public static String findCentroid(List<String> cluster, String currentCentroid) {if (cluster.isEmpty()) return currentCentroid;// 存储每个语句的平均相似度double[] averageSimilarities = new double[cluster.size()];// 计算每个语句与其他语句的平均相似度for (int i = 0; i < cluster.size(); i++) {double totalSimilarity = 0.0;for (int j = 0; j < cluster.size(); j++) {if (i != j) {totalSimilarity += calcTextSim(cluster.get(i), cluster.get(j));}}averageSimilarities[i] = totalSimilarity / (cluster.size() - 1);}// 找到平均相似度最高的语句作为簇中心点int centroidIndex = 0;double maxAverageSimilarity = averageSimilarities[0];for (int i = 1; i < averageSimilarities.length; i++) {if (averageSimilarities[i] > maxAverageSimilarity) {maxAverageSimilarity = averageSimilarities[i];centroidIndex = i;}}return cluster.get(centroidIndex);}
}
相似度工具:
import com.hankcs.hanlp.tokenizer.StandardTokenizer;import java.util.*;
import java.util.stream.Collectors;public class ChineseTextRecommender {public static double calcTextSim(String text, String targetText) {Map<String, Integer> targetVector = buildTermVector(targetText);Map<String, Integer> textVector = buildTermVector(text);double similarity = cosineSimilarity(targetVector, textVector);return similarity;}public static Map<String, Integer> buildTermVector(String text) {List<String> words = StandardTokenizer.segment(text).stream().map(term -> term.word).collect(Collectors.toList());Map<String, Integer> termVector = new HashMap<>();for (String word : words) {termVector.put(word, termVector.getOrDefault(word, 0) + 1);}return termVector;}// 计算余弦相似度public static double cosineSimilarity(Map<String, Integer> vectorA, Map<String, Integer> vectorB) {double dotProduct = 0.0;double normA = 0.0;double normB = 0.0;for (String key : vectorA.keySet()) {dotProduct += vectorA.get(key) * (vectorB.getOrDefault(key, 0));normA += Math.pow(vectorA.get(key), 2);}for (String key : vectorB.keySet()) {normB += Math.pow(vectorB.get(key), 2);}if (normA == 0 || normB == 0) {return 0.0;}return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));}
}
pom依赖
<!-- 分词工具 --><dependency><groupId>com.hankcs</groupId><artifactId>hanlp</artifactId><version>portable-1.8.4</version></dependency>
打印结果:
Cluster 1:
他经常在学校学习
他在学校的学习成绩很好
学校是学习的地方
学校塑料袋管理科Cluster 2:
开心数量肯定两个都是
开心的两个孩子Cluster 3:
如果他不是老师,他就是学生
他可能是老师也可能是学生
老师和学生在上课
老师收到定金
相关文章:
通过k-means对相似度较高的语句进行分类
本文介绍了如何使用K-Means算法对相似度较高的语句进行分类,并附上java案例代码 import java.util.ArrayList; import java.util.List; import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化语句数据集…...
国信华源科技赋能长江蓄滞洪区水闸管护项目验收成果报道
“碧水悠悠绕古城,闸启长江万象新。”近日,由北京国信华源科技有限公司倾力打造的万里长江蓄滞洪区水闸管护项目,圆满通过验收,为这片鱼米之乡的防洪安全注入了新的科技活力。 长江之畔,水闸挺立,犹如干堤上…...
HTML:表格重点
用表格就用table caption为该表上部信息,用来说明表的作用 thead为表头主要信息,效果加粗 tbody为表格中的主体内容 tr是 table row 表格的行 td是table data th是table heading表格标题 ,一般表格第一行的数据都是table heading...
wine的使用方法
wine版本 所有分支,新的主要版本: wine-x.0 All branches, release candidates:各分支、候选版本: wine-x.0-rcn Stable branch updates: 稳定分支更新: wine-x.0.z Development branch updates: wine-x.y wine *.exe “更改目…...
Linux服务器离线安装unzip包
Linux服务器离线安装unzip包 1. 安装unzip包的目的 解压Docker部署包和服务部署包。 2. 查看当前环境是否已经安装unzip rpm -qa | grep --color unzip3. 下载对应的离线包 地址:http://www.rpmfind.net/linux/rpm2html/search.php?query&submitSearch 例…...
Excel拆分脚本
Excel拆分 工作表按行拆分为工作薄 工作表按行拆分为工作薄 打开要拆分的Excel文件,使用快捷键(AltF11)打开脚本界面,选择要拆分的sheet,打开Module,在Module中输入脚本代码,然后运行脚本 Su…...
Mybatis---事务
目录 引入 一、事务存在的意义 1.事务是什么? 2.Mybatis关于事务的管理 程序员自己控制处理的提交和回滚 引入 一、事务存在的意义 1.事务是什么? 多个操作同时进行,那么同时成功,那么同时失败。这就是事务。 事务有四个特性…...
企业直播间媒体分发新闻转播拉流推广名单(金融财经科技类)
【本篇由 言同数字媒体直播分发 原创】随着直播与短视频成为各大企业营销的重要手段,如何选择合适的视频平台进行内容分发与拉流成为了企业关注的焦点。对于财经和科技类企业而言,选择具有专业受众群体和广泛传播能力的平台尤为重要。下面是一些可以帮助…...
华为FreeBuds Pro 4丢了如何找回?(附查找功能使用方法)
华为FreeBuds Pro 4查找到底怎么用?华为FreeBuds Pro 4有星闪精确查找和离线查找,离线查找功能涵盖播放铃声、导航定位、星闪精确查找、上线通知、丢失模式、遗落提醒等。星闪精确查找是离线查找的子功能,当前仅华为FreeBuds Pro 4充电盒支持…...
若依微服务登录密码加密传输解决方案
文章目录 一、需求提出二、应用场景三、解决思路四、注意事项五、完整代码第一步:前端对密码进行加密第二步:后端工具类实现 RSA 加解密功能第三步:登录接口中添加解密逻辑 六、运行结果总结 一、需求提出 在默认情况下,RuoYi 微…...
NVR小程序接入平台/设备EasyNVR深度解析H.265与H.264编码视频接入的区别
随着科技的飞速发展和社会的不断进步,视频压缩编码技术已经成为视频传输和存储中不可或缺的一部分。在众多编码标准中,H.265和H.264是最为重要的两种。今天我们来将深入分析H.265与H.264编码的区别。 一、H.265与H.264编码的区别 1、比特率与分辨率 H.…...
Redisson常用方法
Redisson 参考: 原文链接 定义:Redisson 是一个用于与 Redis 进行交互的 Java 客户端库 优点:很多 1. 入门 1.1 安装 <!--redission--> <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifa…...
html自带的input年月日(date) /时间(datetime-local)/星期(week)/月份(month)/时间(time)控件
年月日期控件 type"date" <input type"date" id"StartDate" valueDateTime.Now.ToString("yyyy-MM-dd") /> //设置值 $("#StartDate").val("2024-12-12"); //获取值 var StartDate$("#StartDate&quo…...
CSS系列(12)-- 响应式设计详解
前端技术探索系列:CSS 响应式设计详解 📱 致读者:掌握响应式设计的艺术 👋 前端开发者们, 今天我们将深入探讨 CSS 响应式设计,学习如何创建适应各种设备的网页布局。 响应式基础 🚀 视口设…...
filecoin boost GraphQL API 查询
查询示例 查询失败交易 curl -X POST \ -H "Content-Type: application/json" \ -d {"query":"query { deals(limit: 10, query: \"failed to get size of imported\") { deals { ID CreatedAt Message } } }"} \ http://localhost:…...
SAS - Subtractive Port
在SAS(串行连接SCSI,Serial Attached SCSI)协议中,subtractive port 是一种特殊类型的端口,主要用于设备间的路由功能。它的作用是在路径选择过程中充当默认路径,以处理未明确指定路径的请求。以下是它的定…...
TCP客户端模拟链接websocket服务端
因一些特殊原因研究了下TCP模拟链接websocket。原理上可以连接但具体怎么连接怎么操作就不知道了,需要研究下,以下是个人研究的方案。 用线上和本地地址来做例子: 线上wss地址:wss://server.cs.com/cs/vido/1 本地地址ws://127…...
TypeScript 的崛起:全面解析与深度洞察
一、背景与起源 (一)JavaScript 的局限性 类型系统缺失 难以在编码阶段发现类型相关错误,导致运行时错误频发。例如,将字符串误当作数字进行数学运算,可能在运行时才暴露问题。函数参数类型不明确,容易传入…...
c#笔记2024
Ctrl r e自动添加get和set CompositeCurve3d 复合曲线 List<Entity> entS listline.Cast<Entity>().ToList();//list类型强转 前面拼上\u0003,就可以实现,不管有没有命令都能打断当前命令的效果 取消其他命令:Z.doc.SendStri…...
Hadoop一课一得
Hadoop作为大数据时代的奠基技术之一,自问世以来就深刻改变了海量数据存储与处理的方式。本文将带您深入了解Hadoop,从其起源、核心架构、关键组件,到典型应用场景,并结合代码示例和图示,帮助您更好地掌握Hadoop的实战…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
