通过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的实战…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...