【Python机器学习】NLP信息提取——提取人物/事物关系
目录
词性标注
实体名称标准化
实体关系标准化和提取
单词模式
文本分割
断句
断句的方式
使用正则表达式进行断句
词性标注
词性(POS)标注可以使用语言模型来完成,这个语言模型包含词及其所有可能词性组成的字典。然后,该模型可以使用已经正确标注好词性的句子进行训练,从而识别由该字典中其他词组成的新句子中所有词的词性。NLTK和spaCy都具备词性标注功能。这里使用spaCy,因为它更快,更精确:
import spacyen_model=spacy.load('en_core_web_md')
sentence=("In 1541 Desoto wrote in his journal that the Pascagoula people ranged as far north as the confluence of the Leaf and Chickasawhay rivers at 30.4,-88.5.")
parsed_sent=en_model(sentence)
print(parsed_sent.ents)print(' '.join(['{}_{}'.format(tok,tok.tag_)for tok in parsed_sent]))
这里spaCy一开始没有识别出经纬度对中的经度,后来使用了“OntoNotes 5”词性标注标签体系。
要构建知识图谱,需要确定哪些对象(名词短语)应该配对。我们想把日期“1554年3月15日”与命名实体Desoto配对。然后可以解析这两个字符串(名词短语)以指向我们知识库中的对象。这里可以将1554年3月15日转换为规范化的datetime.date对象
spaCy解析的句子还包含嵌套字典表示的依存树。同时,spacy.displacy可以生成可缩放的矢量图形SVG字符串(或完整的HTML页面),然后在浏览器中以图像的方式查看。上述可视化方式可以帮助我们找到通过依存树创建用于关系提取的标签模式的方法:
from spacy.displacy import render
sentence="In 1541 Desoto wrote in his journal that the Pascagoula."
parsed_sent=en_model(sentence)
with open('pascagoula.html','w') as f:f.write(render(docs=parsed_sent,page=True,options=dict(compact=True)))
上述短句的依存树表明,名称短语“the Pascagoula”是主语“Desoto”的“met”关系的宾语。这两个名词都被标注为专有名词:
要为spacy.matcher.Matcher创建词性和词属性的模式,以表格形式列出所有的词条标签会很有帮助,下面是一些辅助函数,会使上述过程更容易:
import pandas as pd
from collections import OrderedDict
def token_dict(token):return OrderedDict(ORTH=token.orth_,LEMMA=token.lemma_,POS=token.pos_,TAG=token.tag_,DEP=token.dep_)
def doc_dataframe(doc):return pd.DataFrame([token_dict(tok) for tok in doc])
print(doc_dataframe(en_model("In his journal that the Pascagoula.")))
从上例中,可以看到POS或TAG特征值组成的序列构成了一个正确的模式。如果我们查找人与组织的“has-met”关系,我们可能希望引入诸如“PROPN met PROPN”、“PROPN met the PROPN”、“PROPN met with the PROPN”等模式。我们可以单独指定每个模式,或者在专有名词之间尝试使用“任何词”加上*会?操作符的模式来捕获它们:
'PROPN ANYWORD? met ANYWORD?ANYWORD? PROPN'
spaCy中的模式比上述伪代码更强大更灵活,因此必须更加详细的阐述我们想要匹配的词的特征。在spaCy的模式规范中,我们使用字典为每个词或词条去捕获想要匹配的所有标签:
pattern=[{'TAG':'NNP','OP':'+'},{'IS_ALPHA':True,'OP':'*'},{'LEMMA':'meet'},{'IS_ALPHA':True,'OP':'*'},{'TAG':'NNP','OP':'+'}]
然后,可以从解析的句子中提取想要的带标签的词条:
from spacy.matcher import Matcher
doc=en_model("In 1541 Desoto met the Pascagoula.")
matcher=Matcher(en_model.vocab)
matcher.add('met',patterns=[pattern])
m=matcher(doc)
print(m)
通过上述模式就可以从原始句子中提取一个匹配项。下面看对于类似句子的效果:
doc=en_model("October 24: Lewis and Clark met their first Mandan Chief, Big White.")
m=matcher(doc)[0]
print(m)
print(doc[m[1]:m[2]])
我们需要再添加一个模式,,允许动词在主语和宾语名词之后出现:
doc=en_model("On 11 October 1986, Gorbachev and Reagan met at a house.")
pattern=[{'TAG':'NNP','OP':'+'},{'LEMMA':'and'},{'TAG':'NNP','OP':'+'},{'IS_ALPHA':True,'OP':'*'},{'LEMMA':'meet'}]
matcher.add('met',[pattern])
m=matcher(doc)
print(m)
print(doc[m[-1][1]:m[-1][2]])
现在得到了实体和关系。我们甚至可以构建一个对中间动词(“met”)的限制更少、对两侧的人祸组织的名称限制更严格的模式。这样做可能帮助我们识别出更多类似的动词,这些动词也表示一个人或组织和另一个人或组织相遇,例如动词“knows”,甚至包括被动短语,然后我们可以基于这些新的动词给两侧新的专有名词添加关系。
对于如何偏离初始关系模式的原本含义,这被称为语义漂移。幸运的是,spaCy在对被解析文档中的词打标签时,不仅包含词性和依存树信息,还提供了Word2vec词向量。我们可以利用该向量来避免动词和任何一侧的专有名词的连接关系偏离初始模式的原本含义太远。
实体名称标准化
实体的标准化表示通常是一个字符串,即使对于日期之类的数字信息也是如此。日期的标准化ISO格式为“1541-01-01”。实体的标准化表示使我们的知识库能够将图谱中在同一天世界上发生的所有不同事情连接到同一节点(实体)。
我们对其他类型的命名实体也采用标准化,更正单词的拼写,并尝试处理物体、动物、人物、地点等名称的歧义。特别是对于代词或依赖上下文的其他“名称”,标准化命名实体和解决歧义问题通常也被成为共指消解或指代消解。命名实体的标准化确保拼写和命名实体不会产生混淆的、有冗余的名称,从而污染命名实体表。
例如,“Desoto”可能至少以5种不同的方式在特定文档中出现:
- “de Soto”;
- “Hernando de Soto”;
- “Hernando de Soto(约1496/1497-1542),相西班牙征服者”;
- https://.../.../Hernando de Soto(一个URL);
- 著名历史人物数据库的数字ID。
类似的,标准化算法可以选择上述任何一种形式。知识图谱应该以相同的方式对每种实体进行标准化,以防止同一类型的多个不同实体使用了相同的名称。我们不希望多个人的名字都指向同一个人。更重要的是,标准化应该一以贯之的使用——无论是在向知识库写入新的事实,还是在读取或者查询知识库时都应如此。
如果打算在填充知识库之后更改标准化的方法,那么应该“迁移”或更新知识库中已有实体的数据,以符合新的标准化模式。用于存储知识图谱或知识库的无模式数据库(键值存储),也会受到关系数据库迁移的影响。毕竟,无模式数据库实际上就是关系数据库的接口封装器。
实体标准化之后,还需要“is-a”关系将它们连接到实体类别,这些实体类别定义了实体的类别或类型。因为每个实体可以具有多个“is-a”关系,所以这些“is-a”关系可以被认为是标签。类似于人名或词性标签,如果想要在知识库中使用日期和其他离散数字对象,也需要对其进行标准化。
实体关系标准化和提取
现在需要一种标准化实体关系的方法,从而确定实体之间的关系类型。通过标准化,我们可以找到日期和人之间的所有生日关系,或历史事件发生的日期,类似与“Hernando de Soto”和“Pascagoula people”相遇的时间。我们需要编写算法来选择上述关系中的正确标签。
此外,这些关系可以采用层次化的命名方式,例如“发生于/近似地”和“发生于/精确地”,从而让我们采用特定的关系或者关系类别。还可以使用一个数字属性来标记这些关系的“置信度”、概率、权重或者标准化频率(类似于词项/单词的TF-IDF)。每次从新文本中提取的事实证实了知识库中存在的事实或该事实矛盾时,都可以调整这些置信度的值。
现在需要一种方法来匹配可以找到这些关系的模式。
单词模式
单词模式就像正则表达式一样,但它用于单词而不是字符。我们使用单词类,而不使用字符类。例如,我们不是通过匹配小写字符,而是通过单词模式判定方法来匹配所有的单数名词(词性标注为“NN”)。这往往通过机器学习来实现。一些种子句利用从句子中提取的正确关系(事实)来进行标注,然后可以通过词性标注模式查找类似的句子,即使句子中的主语词和宾语词甚至关系有所变化。
无论先要匹配多少个模式,都可以使用spaCy包以两种不同的方式在O(1)(常数时间)时间内匹配这些模式:
- 用于任何单词/标签序列模式的PhraseMatcher;
- 用于词性标签序列模式的Matcher。
为了确保在新句子中找到的新关系真正类似于原始的种子(例子)关系,我们通常需要新句子中的主语词、关系词和宾语词的含义与种子句子中的类似。实现上述目标的最好方法是使用词义的向量表示。词向量有助于尽可能减少语义漂移的发生。
使用单词和短语的语义向量表示使自动信息提取精确到能够自动构建大型知识库。不过仍然需要人工监督和管理来处理自然语言文本中的大量歧义。
文本分割
文档“组块”有助于创建关于文档的半结构化数据,从而让文档在信息检索场景中更加容易搜索、过滤和排序。对于信息提取,如果从中提取关系以创建知识库(如NELL或Freebase),则需要将文档拆分成可能包含一到两个事实的多个部分。我们把自然语言文本划分为有意义的各部分的过程,称为文本分割。得到的分割结果可以是短语、句子、引文、段落甚至是长文档的整个章节。
对于大多数信息提取问题,句子是最常见的块。句子之间通常使用一些符号(.、?、\、!或换行符)作为标点。语法正确的英文句子必须包含一个主语(名词)和一个动词,这意味着它们之间通常至少有一个关系或事实值得提取。句子的意义通常是自包含的,不会过多依赖前面的文本来传达句子的大部分信息。
幸运的是,包含英语在内的大多数语言都有句子的概念,即一个单独的语句,包含一个主语和一个表达了某些内容的动词。对于NLP知识提取流水线,句子正是所需要的文本块。对于聊天机器人流水线,我们的目标是将文档划分成句子和语句。
除了便于信息提取,我们还可以将其中一些语句和句子进行标记,然后作为对话的一部分或者对话中的适当回复。通过短句,可以在较长的文本上训练聊天机器人。相比于单纯在聊天记录上训练,选择合适的数据可以使聊天机器人具有更文艺、智慧的风格。这些书籍使聊天机器人可以使用范围更广的训练文档,从而获得关于世界的常识性知识。
断句
断句通常是信息提取流水线的第一步,它有助于将事实彼此隔离,以便于可以在“The Babel fish cost $42.42 cents for the stamp”这个字符串中,将正确的价格与正确的事物相关联。上述字符串是表明断句很难的一个很好的例子——中间的句号可以被解释为小数点或句号结束符。
我们从文档中提取的最简单的“信息”是包含逻辑性连贯语句的词序列。在自然语言文档中,重要性排在词之后的是句子。句子包含了关于世界的逻辑连贯语句。这些语句包含我们要从文本中提取的信息。句子描述事实的时候,常常描述事物之间的关系以及世界运行的原理,因此我们可以基于句子进行知识提取。句子通常用来解释过去的某个时间、地点,事情是怎么发生的,一般会怎么发展,或者将来怎么发展。因此,还应该能够用句子作为知道,提取有关时间、地点、人、甚至事件或任务序列的事实。而且,最重要的是,所有自然语言都有句子或某种逻辑连贯的文本部分,并且所有语言都有一个广泛认同的步骤来生成它们(一套语法规则或习惯)。
但是断句即识别句子边界,是很复杂的。例如在英语中没有哪个标点符号或字符序列可以始终标记句子的结尾。
断句的方式
即使是人也可能无法在每个句子中找到合适的句子边界。对于一些疑难例子,错误率可能都接近100%。
即使文档特别难以断句,因为对工程师、科学家和数学家来说,句子和感叹号除了可以用来表示句子结尾外,还会被用来表示很多其他内容,对于这些情况,需要一些更复杂的NLP方法,而不仅仅是split('.!?)。这些方法分别是:
- 手动编程算法(正则表达式和模式匹配);
- 统计模型(基于数据的模型或机器学习)。
使用正则表达式进行断句
正则表达式知识描述“if...then”规则树(正则语法规则)的简写方法,用于查找字符串中的字符模式。正则表达式(正则语法)是指定有限状态机规则的一种特别简明的方法,使用正则表达式或有限状态机只有一个目的:识别句子边界。
有一些搜索断句工具,它们通过组合和增强提供快速、通用的断句表达式。以下正则表达式适用于一些“正常”句子:
import reprint(re.split(r'[!.?]+[ $]',"Hello World.... Are you there?!?! I'm going to Mars!"))
但是上面的re.split方法消耗了句子的分隔符,只有该分隔符是文档或者字符串的最后一个字符时才会被保留。但该方法确实正确地忽略了双层嵌套引号中句号的问题:
print(re.split(r'[!.?] ',"The author wrote \"'I don't think it's conscious.'Turing said."))
但是该方法也忽略了引号中真实句子的分隔符。这可能是好事也是坏事,取决于断句之后的信息提取步骤:
print(re.split(r'[!.?] ',"The author wrote \"'I don't think it's conscious.'Turing said.\" But I stopped readin."))
缩写文本的效果呢?有时人们着急会把句子写到一起,句号周围没有留空。以下正则表达式职能处理在任何一侧都有字母的短消息中的句号,并且它可以安全地跳过数值:
print(re.split(r'(?<!\d)\.|\.(?!\d)',"I went to GT.You?"))
即使合并上面两个正则表达式,也无法在nlpia.data的疑难测试用例中获得较好的效果:
from nlpia.data.loaders import get_data
regex=re.compile(r'(?<!\d)\.|\.(?!\d)|([!.?]+)[ $]+')
examples=get_data('sentence_tm_town')
wrong=[]
for i,(challenge,text,sents) in enumerate(examples):if tuple(regex.split(text))!=tuple(sents):print('wrong{}:{}{}'.format(i,text[:50],'...'if len(text)>50 else ''))wrong=wrong+[i]
print(len(wrong),len(examples))
必须添加“前向环视”和“后向环视”来提高正则表达式断句工具的精确性。更好的断句方法是使用在标记好的句子集合上训练的机器学习算法(通常是单层神经网络或对率回归)。有些软件包含这样的模型,大家可以使用它来改进断句工具:
- DetectorMorse;
- spaCy;
- SyntaxNet;
- NLTK;
- StandfordCoreNLP。
对于大多数关键任务的应用程序,可以使用spaCy断句工具(内置于解析器中)。spaCy依赖少,并且在精确率和速度方面与其他工具相当。纯Python实现中,Kyle Gorman的DetectorMorse也是一个不错的选择。
相关文章:

【Python机器学习】NLP信息提取——提取人物/事物关系
目录 词性标注 实体名称标准化 实体关系标准化和提取 单词模式 文本分割 断句 断句的方式 使用正则表达式进行断句 词性标注 词性(POS)标注可以使用语言模型来完成,这个语言模型包含词及其所有可能词性组成的字典。然后,该…...

vector类
一、STL库 vector 1.1 vector的介绍 vector英文意思为向量:向量是表示大小可以改变的数组的序列容器。 指向其元素的常规指针上的偏移量来访问其元素,并且与数组中的效率一样高。但与数组不同,它们的大小可以动态变化,其存储由容…...

python常见的魔术方法
什么是魔术方法 Python类的内置方法,各自有各自的特殊功能,被称之为魔术方法 常见的魔术方法有以下: __init__:构造方法 __str__:字符串方法 __lt__:小于、大于符号比较 __le__:小于等于、大于等于符合比较 __eq__:等于符合比较__init__ c…...

自动化测试常用函数:弹窗、等待、导航、上传与参数设置
目录 一、弹窗 1. 警告弹窗确认弹窗 2. 提示弹窗 二、等待 1. 强制等待 2. 隐式等待 3. 显示等待 三、浏览器导航 1. 打开网站 2. 浏览器的前进、后退、刷新 四、文件上传 五、浏览器参数设置 1. 设置无头模式 2. 页面加载策略 一、弹窗 弹窗是在页面是找不到任何…...

【必看】2024国赛选题分布情况分析及数模国赛答辩指南~答辩不走弯路
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 紧张刺激的数模国赛已经过去一段时间,各赛区的成绩发布也在陆续进…...

微服务注册中⼼1
1. 微服务的注册中⼼ 注册中⼼可以说是微服务架构中的”通讯录“ ,它记录了服务和服务地址的映射关系。在分布式架构中, 服务会注册到这⾥,当服务需要调⽤其它服务时,就这⾥找到服务的地址,进⾏调⽤。 1.1 注册中⼼的…...

我设置了路由器自动切换ip,这会让我的账号登录地址经常改变吗
是的,路由器设置自动切换IP可能会导致你的账号登录地址经常改变。 这是因为当路由器切换IP时,外部网络所看到的你的设备IP地址也会随之改变。对于很多跨境电商、社交媒体或者银行账户等需要较高安全性的系统来说,经常变动的IP地址可能会被视…...

Nginx 限流实战教程和技巧
Nginx限流是一种重要的技术手段,用于保护服务器资源,防止因过度请求而导致的服务不可用。以下是一个详细的Nginx限流教程,包括限流原理、常用模块和配置示例。 一、Nginx限流原理 Nginx限流主要基于两种算法:漏桶算法和令牌桶算…...

AlphaFold3 | 详解 AlphaFold3 的模型结构及其在不同类型的预测实验中的表现
Jumper 本文将介绍 24 年 5 月发布的 Alaphafold3,其以“使用 AlphaFold 3 进行生物分子相互作用的精确结构预测”为标题发表在《nature》上,通讯作者为 Jumper。 Jumper 具有物理、化学、生物和计算方面的丰富背景。Jumper 本科学的是物理和数学&#…...

公交IC卡收单管理系统 多处 SQL注入致RCE漏洞复现
0x01 产品简介 公交IC卡收单管理系统是城市公共交通领域中不可或缺的一部分,它通过集成先进的集成电路技术(IC卡)实现了乘客便捷的支付方式,并有效提高了公共交通运营效率。系统集成了发卡、充值、消费、数据采集、查询和注销等多个功能模块,为公交公司和乘客提供了全面、…...

淘客系统开发之卷轴模式系统源码功能分析
随着互联网技术的快速发展,电商行业不断创新,探索更加高效、有趣的用户参与机制。其中,卷轴模式作为一种新兴的商业模式,以其独特的积分兑换和任务系统,在淘客系统开发中得到了广泛应用。本文将从技术角度,…...

MoCo中的字典
在 MoCo(Momentum Contrast)中,字典(dictionary)是一个核心组件,用于存储负样本(negative samples)的特征表示(key)。这个字典的设计使得 MoCo 可以高效地利用…...

Xcode16 iOS18 编译问题适配
问题1:ADClient编译报错问题 报错信息 Undefined symbols for architecture arm64:"_OBJC_CLASS_$_ADClient", referenced from:in ViewController.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit co…...

加密解密的艺术:探索Java中的DES算法
目录 1. 引言 2. DES算法简介 3. Java中的DES实现 4. 代码解析 5. 安全性考量 1. 引言 在数字化时代,数据安全变得至关重要。无论是个人隐私还是企业机密,都需要强有力的保护措施。今天,我们将探讨一种经典的数据加密技术——DES&#…...

jQuery——层次选择器
1、层次选择器:查找子元素,后代元素,兄弟元素的选择器。 ancestor descendant:在给定的祖先元素下匹配所有的后代元素 parent > child:在给定的父元素下匹配所有的子元素 prev next:匹配所有紧接在…...

MySQL常见面试总结
MySQL基础 什么是关系型数据库? 顾名思义,关系型数据库(RDB,Relational Database)就是一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系(一对一、一对多、多对多&…...

记录一次学习--委派攻击学习
目录 为什么要使用委派 什么账号可以使用委派 非约束性委派 这里有一张图 利用 流程 约束性委派 这里有一张图 如何利用 条件 具体流程 为什么要使用委派 这个是因为可能A服务需要B服务的支持,但是A服务的权限不可以使用B服务。然后这时就可以让域用户将…...

前端列表数据太多导致页面卡顿就这么处理
前端列表数据太多页面卡顿就这么处理 实际场景什么是虚拟列表虚拟列表实现原理实战中虚拟列表的问题及相应解决方案 实际场景 首先看以下两个实际场景: 场景一:有一个数据列表,数据量非常大且每一个数据项都有几十列甚至更多,且后…...

机器学习_神经网络_深度学习
【神经网络——最易懂最清晰的一篇文章 - CSDN App】https://blog.csdn.net/illikang/article/details/82019945?type=blog&rId=82019945&refer=APP&source=weixin_45387165 参考以上资料,可对神经网络有初步了解。接下来可参考书籍等投身实际项目中使用。 书…...

MT6765/MT6762(R/D/M)/MT6761(MT8766)安卓核心板参数比较_MTK联发科4G智能模块
联发科Helio P35 MT6765安卓核心板 MediaTek Helio P35 MT6765是智能手机的主流ARM SoC,于2018年末推出。它在两个集群中集成了8个ARM Cortex-A53内核(big.LITTLE)。四个性能内核的频率高达2.3GHz。集成显卡为PowerVR GE8320,频率…...

TikTok五分钟开户快速步骤流程!
1、注册您的账户 首先,访问TikTok广告管理器的注册页面(https://ads.tiktok.com/i18n/signup/)以创建账户。您可以选择使用电子邮件或手机号码进行注册。输入您的电子邮件和密码后,您需要同意TikTok的广告条款,然后点击…...

BFS 解决拓扑排序 , 课程表 , 课程表 II , 火星词典
文章目录 拓扑排序简介1.有向无环图(DAG图)2.AOV网:顶点活动图3.拓扑排序4.实现拓扑排序 207. 课程表210. 课程表 IILCR 114. 火星词典 拓扑排序简介 1.有向无环图(DAG图) 像这样只能从一个点到另一个点有方向的图&a…...

web安全攻防渗透测试实战指南_web安全攻防渗透测试实战指南,零基础入门到精通,收藏这一篇就够了
1. Nmap的基本 Nmap ip 6 ip Nmap -A 开启操作系统识别和版本识别功能 – T(0-6档) 设置扫描的速度 一般设置T4 过快容易被发现 -v 显示信息的级别,-vv显示更详细的信息 192.168.1.1/24 扫描C段 192.168.11 -254 上 nmap -A -T4 -v -i…...

大模型如何赋能智慧城市新发展?
国家数据局近期发布的《数字中国发展报告(2023)》显示,我国数据要素市场化改革步伐进一步加快,数字经济规模持续壮大,数字技术应用场景不断拓展。这一成就的背后是数字技术广泛应用,数字技术不仅影响着老百…...

随记——机器学习
前言 本来有个500块钱的单子,用机器学习做一个不知道什么鸟的识别,正好有数据集,跑个小项目,过一下机器学习图像识别的流程,用很短的时间记录下来..... 一、数据预处理 将数据集分为训练集和测试集,直接…...

【在Linux世界中追寻伟大的One Piece】进程间通信
目录 1 -> 进程间通信介绍 1.1 -> 进程间通信目的 1.2 -> 进程间通信发展 1.3 -> 进程间通信分类 1.3.1 -> 管道 1.3.2 -> System V IPC 1.3.3 -> POSIX IPC 2 -> 管道 2.1 -> 什么是管道 2.2 -> 匿名管道 2.3 -> 实例代码 2.4 -…...

多路复用IO
一。进程处理多路IO请求 在没有多路复用IO之前,对于多路IO请求,一般只有阻塞与非阻塞IO两种方式 1.1 阻塞IO 需要结合多进程/多线程,每个进程/线程处理一路IO 缺点:客户端越多,需要创建的进程/线程越多,…...

C++ prime plus-7-編程練習
1, #include <iostream>// 函数声明 double harmonicMean(double x, double y);int main() {double x, y, result;while (true) {std::cout << "请输入两个数(其中一个为0时结束): ";std::cin >> x >> y;…...

计算1 / 1 - 1 / 2 + 1 / 3 - 1 / 4 + 1 / 5 …… + 1 / 99 - 1 / 100 的值,打印出结果
我们写这道题的时候需要俩变量接受,一个总数一个分母,我们发现分母变化是有规律的从1~100循环。 #include<stdio.h> int main() {int i 0;int tag 1;double sum 0.0;for (i 1; i < 101; i){if (i % 2 0){sum sum - 1.0 / i;}else{sum s…...

Linux本地服务器搭建开源监控服务Uptime Kuma与远程监控实战教程
文章目录 前言**主要功能**一、前期准备本教程环境为:Centos7,可以跑Docker的系统都可以使用本教程安装。本教程使用Docker部署服务,如何安装Docker详见: 二、Docker部署Uptime Kuma三、实现公网查看网站监控四、使用固定公网地址…...