当前位置: 首页 > article >正文

自然语言处理:词频-逆文档频率

介绍

大家好,博主又来给大家分享知识了。本来博主计划完成稠密向量表示的内容分享后,就开启自然语言处理中文本表示的讲解。可在整理分享资料的时候,博主发现还有个知识点,必须得单独拎出来好好说道说道。

这就是TF-IDF,也就是词频-逆文档频率。它在自然语言处理里堪称“幕后功臣”,在文本表示、文本分类、信息检索等诸多关键任务中,发挥着超乎想象的作用。那么,我们直接进入正题。

TF-IDF

自然语言处理(NLP)领域,理解文本数据的含义并从中提取有价值的信息是核心任务。TF-IDF(Term Frequency-Inverse Document Frequency)作为一种重要的统计方法,在文本表示、文本分类、信息检索、关键词提取等众多任务中发挥着关键作用。

基础概念

词频

Term Frequency, TF。词频衡量的是一个词在一篇文档中出现的频率。直观地说,一个词在文档中出现的次数越多,它对该文档的重要性可能越高。例如,在文档“我喜欢苹果,苹果很美味”中,“苹果”这个词出现了两次,相对其他词出现的频率较高,可能在该文档中具有一定重要性。

其计算公式为:TF_{t,d} = \frac{n_{t,d}}{\sum_{k} n_{k,d}}

其中,TF_{t,d}表示词t在文档d中的词频,n_{t,d}是词t在文档d中出现的次数,\sum_{k} n_{k,d}是文档d中所有词的出现次数总和。

逆文档频率

Inverse Document Frequency, IDF。逆文档频率反映了一个词在整个文档集合中的普遍重要性。如果一个词在大量文档中都出现,那么它对于区分不同文档的作用就较小。相反,一个只在少数文档中出现的词,对于识别这些特定文档更为关键。

例如,“的”,“是”等常用词在几乎所有文档中都会频繁出现,它们的区分能力较弱。而专业术语如“量子纠缠”,只在特定领域的文档中出现,其区分能力较强。

其计算公式为:IDF_{t} = \log \frac{N}{n_{t}}

其中,IDF_{t}表示词t的逆文档频率,N是文档集合中的文档总数,n_{t}是包含词t的文档数量。

TF-IDF加权

TF-IDF加权综合了词频和逆文档频率,通过将两者相乘得到每个词在文档中的TF-IDF值。

公式为:TF-IDF_{t,d} = TF_{t,d} \times IDF_{t}

TF-IDF值越高,说明该词对当前文档越重要,同时在整个文档集中相对不常见,具有较强的区分性。

代码实现

计算词频(TF)

完整代码
# 从collections模块导入Counter类,用于统计元素出现的次数
from collections import Counter# 定义一个名为NLPTextRepresentation的类,用于处理文本表示相关任务
class NLPTextRepresentation:# 类的初始化方法,此处不做任何初始化操作def __init__(self):# pass 语句占位,不进行实际操作pass# 定义一个方法,用于计算文档中每个单词的词频(TF)def compute_tf(self, document):# 将输入的文档按空格分割成单词列表words = document.split()# 使用Counter统计每个单词在文档中出现的次数word_count = Counter(words)# 计算文档中单词的总数total_words = len(words)# 初始化一个空字典,用于存储每个单词的词频tf_dict = {}# 遍历统计结果中的每个单词及其出现次数for word, count in word_count.items():# 计算该单词的词频并存储到字典中tf_dict[word] = count / total_words# 返回存储词频的字典return tf_dict# 当脚本作为主程序运行时执行以下代码
if __name__ == "__main__":# 创建NLPTextRepresentation类的一个实例nlp_text_representation = NLPTextRepresentation()# 定义一个示例文档document = "我喜欢苹果 苹果很美味"# 调用compute_tf方法计算文档中单词的词频tf_result = nlp_text_representation.compute_tf(document)# 打印计算得到的词频结果print(tf_result)
运行结果
{'我喜欢苹果': 0.5, '苹果很美味': 0.5}进程已结束,退出代码为 0

在这段代码中,首先使用split()方法将输入的文档字符串分割成单词列表。然后,利用Counter类统计每个单词在文档中出现的次数。

接着,计算文档的总词数,通过遍历每个单词及其出现次数,将每个单词的出现次数除以总词数,得到该单词在文档中的词频,并存储在字典tf_dict中。

最后返回这个字典,其中键为单词,值为对应的词频。

计算逆文档频率(IDF)

完整代码
# 导入math模块,用于使用数学函数,这里主要是为了计算对数
import math# 定义一个名为NLPTextRepresentation的类,用于处理自然语言处理中的文本表示相关任务
class NLPTextRepresentation:# 类的初始化方法,目前不做任何初始化操作def __init__(self):# 占位语句,不执行任何实际逻辑pass# 定义一个方法,用于计算语料库中每个单词的逆文档频率(IDF)def compute_idf(self, corpus):# 计算语料库中文档的总数total_docs = len(corpus)# 初始化一个空字典,用于存储每个单词在多少个文档中出现过word_in_doc_count = {}# 遍历语料库中的每一个文档for doc in corpus:# 将当前文档按空格分割成单词,并使用 set 去重words = set(doc.split())# 遍历当前文档中出现的每个唯一单词for word in words:# 如果该单词还未在word_in_doc_count字典中if word not in word_in_doc_count:# 则将该单词添加到字典中,并将其出现文档数初始化为 1word_in_doc_count[word] = 1else:# 否则,将该单词出现的文档数加 1word_in_doc_count[word] += 1# 初始化一个空字典,用于存储每个单词的逆文档频率idf_dict = {}# 遍历word_in_doc_count字典中的每个单词及其出现文档数for word, count in word_in_doc_count.items():# 计算该单词的逆文档频率(使用自然对数),并存储到idf_dict中idf_dict[word] = math.log(total_docs / count)# 返回存储逆文档频率的字典return idf_dict# 当脚本作为主程序运行时执行以下代码
if __name__ == "__main__":# 创建NLPTextRepresentation类的一个实例nlp_text_representation = NLPTextRepresentation()# 定义一个语料库,包含多个文档corpus = ["我喜欢苹果 苹果很美味", "我喜欢香蕉 香蕉很甜", "苹果和香蕉都是水果"]# 调用compute_idf方法计算语料库中每个单词的逆文档频率idf_result = nlp_text_representation.compute_idf(corpus)# 打印计算得到的逆文档频率结果print(idf_result)
运行结果
{'我喜欢苹果': 1.0986122886681098, '苹果很美味': 1.0986122886681098, '我喜欢香蕉': 1.0986122886681098, '香蕉很甜': 1.0986122886681098, '苹果和香蕉都是水果': 1.0986122886681098}进程已结束,退出代码为 0

在这段代码中,首先计算语料库中总的文档数量。然后,遍历语料库中的每一篇文档,将文档中的单词通过set()方法去重,以确保每个单词只被统计一次。

对于每个单词,如果它不在word_in_doc_count字典中,则将其初始值设为 1;如果已经存在,则将其对应的值加 1,这样word_in_doc_count字典记录了每个单词在多少篇文档中出现过。

接下来,通过遍历word_in_doc_count字典,根据逆文档频率的计算公式,计算每个单词的逆文档频率,并存储在idf_dict字典中返回。

计算词频-逆文档频率(TF-IDF)

完整代码
# 从collections模块导入Counter类,用于统计元素出现的次数
from collections import Counter
# 导入math模块,用于使用数学函数,这里主要是为了计算对数
import math# 定义一个名为NLPTextRepresentation的类,用于处理自然语言处理中的文本表示相关任务
class NLPTextRepresentation:# 类的初始化方法,目前不做任何初始化操作def __init__(self):# 占位语句,不执行任何实际逻辑pass# 定义一个方法,用于计算文档中每个单词的词频(TF)def compute_tf(self, document):# 将输入的文档按空格分割成单词列表words = document.split()# 使用Counter统计每个单词在文档中出现的次数word_count = Counter(words)# 计算文档中单词的总数total_words = len(words)# 初始化一个空字典,用于存储每个单词的词频tf_dict = {}# 遍历统计结果中的每个单词及其出现次数for word, count in word_count.items():# 计算该单词的词频并存储到字典中tf_dict[word] = count / total_words# 返回存储词频的字典return tf_dict# 定义一个方法,用于计算语料库中每个单词的逆文档频率(IDF)def compute_idf(self, corpus):# 计算语料库中文档的总数total_docs = len(corpus)# 初始化一个空字典,用于存储每个单词在多少个文档中出现过word_in_doc_count = {}# 遍历语料库中的每一个文档for doc in corpus:# 将当前文档按空格分割成单词,并使用set去重words = set(doc.split())# 遍历当前文档中出现的每个唯一单词for word in words:# 如果该单词还未在word_in_doc_count字典中if word not in word_in_doc_count:# 则将该单词添加到字典中,并将其出现文档数初始化为1word_in_doc_count[word] = 1else:# 否则,将该单词出现的文档数加1word_in_doc_count[word] += 1# 初始化一个空字典,用于存储每个单词的逆文档频率idf_dict = {}# 遍历word_in_doc_count字典中的每个单词及其出现文档数for word, count in word_in_doc_count.items():# 计算该单词的逆文档频率(使用自然对数),并存储到idf_dict中idf_dict[word] = math.log(total_docs / count)# 返回存储逆文档频率的字典return idf_dict# 定义一个方法,用于计算语料库中每个文档里单词的TF-IDF值def compute_tfidf(self, corpus):# 初始化一个空列表,用于存储每个文档的TF-IDF结果tfidf_corpus = []# 调用compute_idf方法计算语料库中所有单词的逆文档频率idf = self.compute_idf(corpus)# 遍历语料库中的每一个文档for doc in corpus:# 调用compute_tf方法计算当前文档中每个单词的词频tf = self.compute_tf(doc)# 初始化一个空字典,用于存储当前文档中每个单词的TF-IDF值tfidf_doc = {}# 遍历当前文档词频字典中的每个单词for word in tf:# 计算该单词的TF-IDF值并存储到字典中tfidf_doc[word] = tf[word] * idf[word]# 将当前文档的TF-IDF结果添加到tfidf_corpus列表中tfidf_corpus.append(tfidf_doc)# 返回存储所有文档TF-IDF结果的列表return tfidf_corpus# 当脚本作为主程序运行时执行以下代码
if __name__ == "__main__":# 创建NLPTextRepresentation类的一个实例nlp_text_representation = NLPTextRepresentation()# 定义一个包含多个文档的语料库corpus = ["我喜欢苹果 苹果很美味", "我喜欢香蕉 香蕉很甜", "苹果和香蕉都是水果"]# 调用compute_tfidf方法计算语料库中每个文档里单词的TF-IDF值tfidf_result = nlp_text_representation.compute_tfidf(corpus)# 遍历计算得到的TF-IDF结果列表for i, doc in enumerate(tfidf_result):# 打印每个文档的TF-IDF计算结果print(f"文档{i + 1}的TF-IDF结果: {doc}")
运行结果
文档1的TF-IDF结果: {'我喜欢苹果': 0.5493061443340549, '苹果很美味': 0.5493061443340549}
文档2的TF-IDF结果: {'我喜欢香蕉': 0.5493061443340549, '香蕉很甜': 0.5493061443340549}
文档3的TF-IDF结果: {'苹果和香蕉都是水果': 1.0986122886681098}进程已结束,退出代码为 0

这段代码首先调用前面定义的compute_idf函数计算整个语料库的逆文档频率。然后,遍历语料库中的每一篇文档,对每篇文档调用compute_tf函数计算词频。

接着,对于每个词,将其在当前文档中的词频乘以其在整个语料库中的逆文档频率,得到该词在当前文档中的TF-IDF值,并存储在tfidf_doc字典中。

最后,将每篇文档的TF-IDF字典结果添加到tfidf_corpus列表中并返回。这段代码的目的是将前面计算得到的词频和逆文档频率进行综合计算,得到每篇文档中每个词的TF-IDF值,从而完成TF-IDF加权的计算过程。 

TF-IDF的优点

  • 简单有效:TF-IDF的计算原理直观易懂,实现相对简单,不需要复杂的模型训练过程,却能在很多实际应用中取得较好的效果,如文本分类、信息检索等。
  • 突出关键信息:通过加权计算,能够突出那些在特定文档中频繁出现且在整个文档集中相对不常见的词,这些词往往与文档的主题紧密相关,有助于快速定位文档的核心内容。
  • 可扩展性好:无论是小规模还是大规模的文档集合,TF-IDF都能适用,并且计算资源消耗相对可控。在处理大规模文本数据时,可以通过分布式计算等方式进一步优化计算效率。

TF-IDF的缺点

  • 忽略语义信息:TF-IDF只考虑了词的出现频率和文档分布,完全没有涉及词与词之间的语义关系。例如,“汽车”“轿车”在语义上相近,但TF-IDF无法体现这种关系,可能会导致在一些需要语义理解的任务中效果不佳。
  • 依赖文档集合:逆文档频率的计算依赖于整个文档集合,当文档集合发生变化时,需要重新计算IDF值,这在实时性要求较高的应用场景中可能会带来不便。
  • 无法处理多义词:对于具有多种含义的词,TF-IDF不能区分其在不同上下文中的语义差异,会将其视为同一个词进行计算,可能影响对文本的准确理解。

结论赋能

TF-IDF作为自然语言处理中的经典方法,在文本分析的众多领域有着广泛应用。通过对词频和逆文档频率的巧妙结合,能够有效地提取文本中的关键信息,为后续的文本处理任务提供有力支持。

然而,其固有的局限性也为研究人员提供了改进和创新的方向。在实际应用中,需要根据具体任务的需求和数据特点,合理选择是否使用TF-IDF,并结合其他技术(如词向量模型等)来弥补其不足,以更好地实现自然语言处理的目标。

结束

好了,以上就是本次分享的全部内容了。不知道大家是否对TF-IDF有了更深入的理解,以及对其在实际应用中的潜力有了新的认识呢?希望本次分享能为大家在自然语言处理的学习和实践中带来启发和帮助。

随着自然语言处理技术的不断发展,我们期待看到更多能够克服TF-IDF局限性的创新方法涌现。无论是在文本分类、信息检索,还是在文本摘要等领域,TF-IDF都已经奠定了坚实的基础,激励着研究者们不断探索更高效、更精准的文本处理策略。

那么本次分享就到这里了。最后,博主还是那句话:请大家多去大胆的尝试和使用,成功总是在不断的失败中试验出来的,敢于尝试就已经成功了一半。如果大家对博主分享的内容感兴趣或有帮助,请点赞和关注。大家的点赞和关注是博主持续分享的动力🤭,博主也希望让更多的人学习到新的知识。

相关文章:

自然语言处理:词频-逆文档频率

介绍 大家好,博主又来给大家分享知识了。本来博主计划完成稠密向量表示的内容分享后,就开启自然语言处理中文本表示的讲解。可在整理分享资料的时候,博主发现还有个知识点,必须得单独拎出来好好说道说道。 这就是TF-IDF&#xf…...

快速在本地运行SpringBoot项目的流程介绍

目录 前言 一、环境配置 1.1Java环境 1.2Maven环境 1.3IntelliJ IDEA安装 1.4MySql安装 二、项目导入与启动的过程 2.1Maven镜像和本地仓库 2.1.2镜像配置 2.1.3配置本地仓库 2.2导入项目与启动 2.2.1加载Maven设置 2.2.2配置jdk与java版本 2.2.3创建数据库 2.2…...

【后端开发面试题】每日 3 题(三)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:https://blog.csdn.net/newin2020/category_12903849.html 📚专栏简介:在这个专栏中,我将会分享后端开发面试中常见的面试题给大家~ ❤️如果有收获的话&#x…...

Java容器异常分析与恢复实战指南

引言 在云原生时代,Java应用的容器化部署已成为主流。然而,容器环境下的异常处理相比传统部署模式更为复杂,特别是在处理内存溢出(OOM)、资源限制和服务恢复等方面面临新的挑战。本文将结合实战经验,系统讲解Java容器异常的分析方法、恢复策略与最佳实践。 一、容器化Java异常…...

SpringBoot 端口配置

在Spring Boot中,配置应用程序的监听端口有多种方式。以下是常见的几种方法: 1. 通过 application.properties 或 application.yml 文件配置 application.properties server.port8081application.yml server:port: 8081如果没有显式配置 server.port…...

Python 数据结构 4.单向链表

惟愿春日不迟,相逢终有时 —— 25.3.2 一、单向链表的基本概念 1.单向链表的概念 对于顺序存储的结构,最大的缺点就是:插入 和 删除 的时候需要移动大量的元素,所以基于前人的智慧,他们发明了链表。 链表是由一个个结…...

LeeCode题库第四十题

40.组合总和II 项目场景: 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 示…...

AI日报 - 2025年3月2日 - 推特版

AI日报 - 2025年3月2日 - 推特版 🌟 今日概览(60秒速览) ▎🤖 AGI突破 | Anthropic预测AGI将于2027年实现 🔬 Sholto Douglas加入团队,开源社区推动AGI竞赛加速 ▎💼 商业动向 | 腾讯发布Hunyua…...

Kotlin语言特性(一):空安全、扩展函数与协程

Kotlin语言特性(一):空安全、扩展函数与协程 一、引言 Kotlin作为Android官方推荐的开发语言,相比Java具有诸多现代化特性。本文将重点介绍Kotlin三个最具特色的语言特性:空安全、扩展函数和协程,并结合A…...

玩转大模型——deepseek本地部署与ollama 非C盘安装之ChatBox配置

文章目录 ollama安装ollama是什么DeepSeek是什么下载地址非C盘安装配置大模型目录大模型下载安装deepseek-r1:1.5b安装deepseek-r1:7b ChatBox安装参考资料 ollama安装 ollama是什么 Ollama 是一个专注于本地运行大型语言模型的工具。它允许用户在本地环境中部署和运行各种开…...

面试题:说一下你对DDD的了解?

面试题:说一下你对DDD的了解? 在面试中,关于 DDD(领域驱动设计,Domain-Driven Design) 的问题是一个常见的技术考察点。DDD 是一种软件设计方法论,旨在通过深入理解业务领域来构建复杂的软件系统。以下是一个清晰、详细的回答模板,帮助你在面试中脱颖而出: DDD 的定义…...

【构建企业级Spring Boot应用:从基础到高级的全面指南】

摘要 本文旨在为开发者提供一份详尽的指南,帮助大家深入理解并掌握如何使用Spring Boot框架来快速开发企业级应用程序。通过实际案例分析、代码示例以及架构设计思路分享,读者不仅能够学习到理论知识,还能获得宝贵的实践经验。本文将涵盖从环…...

DAV_postgresql_3-schema

schem介绍: 什么是schema? 用户对象的集合叫做模式 不同模式下的对象可以同名 可以把用户下对象根据业务分类,不同的对象放在不同的模式 一个用户可以创与拥有多个模式 一个模式只能属于一个用户 普通用户创建模式需要授权指定数据库下的创建权限…...

Hive-04之存储格式、SerDe、企业级调优

一、主题 hive表的数据压缩和文件存储格式hive的自定义UDF函数hive的JDBC代码操作hive的SerDe介绍和使用hive的优化 二、要点 1. hive表的文件存储格式 Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC&…...

信号和槽

connect(信号发送者,发送的信号,信号接收者,信号的处理); 信号函数和槽函数的参数必须是一样的,但信号的参数可以多余槽函数的参数(前面的参数类型必须一致) 是控件和控件间的信号传递,这两个…...

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(八) 聊天框用户列表

简单画了个聊天框 就是咱们的HomePage.jsx 1.后端接口开发 在server/src/index.js 新增 messagesRoutes 先引入 import messageRoutes from ./routes/message.route.js // 消息接口 app.use(/api/messages, messageRoutes) 在routes文件夹下新建message.route.js 有3个路…...

关于后端使用Boolean或boolean时前端收到的参数的区别

当后端使用的是Boolean时,调用的方法是setIsLoginUser,前端收到的参数的参数名是isLoginUser 而当后端使用的是boolean时,调用的方法是setLoginUser,前端收到的参数的参数名是loginUser 封装类和基本数据类型在使用时需要注意这…...

智能称重搬物寻迹小车(论文+源码)

1 系统设计方案确定 本次设计的总系统有以下几个模块分别是避障模块,循迹模块,二维码扫描电路,称重电路,LCD显示电路和电机驱动模块,而且这几个模块都是由单片机stm32控制的,整个系统的框图如下图所示。其…...

使用 ASP.NET Core 创建和下载 zip 文件

对于最近的一个功能,我必须从用 ASP.NET Core 编写的内部网站下载一批文件。在下载文件之前对其进行压缩,结果证明这是一种轻松实现多文件下载的好方法。.NET 提供了所有需要的功能,在本文中,我将向您展示如何实现它。 首先&#…...

“深入浅出”系列之音视频开发:(12)使用FFmpeg实现倍速播放:技术细节与优化思路

一、前言 在音视频处理领域,倍速播放是一个常见的需求,尤其是在视频播放器、在线教育平台等场景中,用户常常需要以不同的速度播放视频内容。然而,实现一个高质量的倍速播放功能并不容易,尤其是在处理音频时&#xff0…...

dify绑定飞书多维表格

dify 绑定飞书和绑定 notion 有差不多的过程,都需要套一层应用的壳子,而没有直接可以访问飞书文档的 API。本文记录如何在dify工具中使用新增多条记录工具。 创建飞书应用 在飞书开放平台创建一个应用,个人用户创建企业自建应用。 自定义应…...

SQL server配置ODBC数据源(本地和服务器)

本地配置 1. 控制面板中找到系统ODBC数据源(打开控制面板直接搜) 2. 选择“系统DSN”,点击“添加” 3. 选择“SQL server” 4. 名称和描述自己填,服务器选择本机设备名称 5. 选择ID和密码验证,并填写本地SQL server登…...

LogiSim教程

一、LogiSim是什么 Logisim是一种设计数字电路的工具。 二、安装LogiSim 下载地址 https://sourceforge.net/projects/circuit/ 此软件需要java运行环境。 三、使用LogiSim (一)界面 Logisim界面分为菜单栏、工具栏、资源管理器,属性表…...

RAP: Efficient Text-Video Retrieval with Sparse-and-Correlated Adapter

​​标题:RAP:基于稀疏相关适配器的高效文本视频检索 原文链接:RAP: Efficient Text-Video Retrieval with Sparse-and-Correlated Adapter - ACL Anthology 发表:ACL-2024(NLP领域CCF A类) 摘要 文本-视频检索(TVR&#xff0…...

I2C驱动(十一) -- gpio模拟的i2c总线驱动i2c-gpio.c分析

相关文章 I2C驱动(一) – I2C协议 I2C驱动(二) – SMBus协议 I2C驱动(三) – 驱动中的几个重要结构 I2C驱动(四) – I2C-Tools介绍 I2C驱动(五) – 通用驱动i2c-dev.c分析 I2C驱动(六) – I2C驱动程序模型 I2C驱动(七) – 编写I2C设备驱动之i2c_driver I2C驱动(八) – 编写I2C…...

不要升级,Flutter Debug 在 iOS 18.4 beta 无法运行,提示 mprotect failed: Permission denied

近期如果有开发者的 iOS 真机升级到 18.4 beta,大概率会发现在 debug 运行时会有 Permission denied 的相关错误提示,其实从 log 可以很直观看出来,就是 Dart VM 在初始化时,对内核文件「解释运行(JIT)」时…...

zjbdt

嵌入式软件工程师可以通过考取相关职业证书来提升专业能力和职业竞争力。以下是几种含金量较高且广受认可的证书: 1. NIEH 嵌入式技术工程师证书 颁发机构:教育部考试中心级别:初级、中级、高级内容:涵盖嵌入式系统的基础理论、开…...

【3天快速入门WPF】11-附加属性

目录 1. 步骤1:定义附加属性2. 示例代码3. 步骤2:在XAML中使用附加属性3.1. 示例代码4. 步骤3:扩展使用场景4.1. 示例代码5. 总结上一篇讲到了依赖属性,本篇主要想说一下附加属性。 在WPF中,附加属性(Attached Property)是一种特殊的依赖属性,允许你在不属于某个类的控…...

私有化部署大模型推理性能分析

从用户感知角度分析私有化部署的大模型推理性能,这里的用户感知包括响应速度、生成速度、系统可用性以及系统稳定性。大模型首先获取输入内容的字符串,将这部分内容转换为模型token,过模型推理,到最后输出第一个token的时间是ttft,从这以后&a…...

版图自动化连接算法开发 00001 ------ 直接连接两个给定的坐标点

版图自动化连接算法开发 00001 ------ 直接连接两个给定的坐标点 引言正文定义坐标点的类绘图显示代码直接连接两个坐标点引言 由于人工智能的加速普及,每次手动绘制版图都会觉得特别繁琐,作者本人在想可否搞一个自动化连接器件端口的算法,后期可以根据一些设定的限制进行避…...