Python调用讯飞星火大模型v3.5接口

在国外,ChatGPT已经成为AI模型行业的大佬,但是国内如果需要使用,会有各种限制,本文介绍如何使用国内的模型。

在国内,讯飞星火大模型是一个非常优秀的中文预训练模型。本文将介绍如何使用Python调用讯飞星火大模型接口,实现文本生成等功能。

讯飞星火官网:讯飞星火认知大模型-AI大语言模型-星火大模型-科大讯飞

1、获取api接口的ID和key

可以获取星火免费赠送的200万个token使用和测试,个人学习使用完全够了

1.1 创建应用

       点击购买首次应该会让创建一个应用, 如下图,按要求内容随意填写,然后提交

1.2  购买token

        创建完成应用,回去购买,我这里选择个人的(这些都是在完成认证及设置了支付密码的基础),我们选择免费的包

1.3 获取 ID和key

        在工单中心这个大模型3.5,页面就是,appid这三个我们会用到

1.4 接口文档的选择

官方提供很多版本的SDK开发包及文档,这里需要我们选择web,官方有介绍

1.5 获取python API接口文档

点击上图的WebAPI链接跳转到如下链接:

星火认知大模型Web API文档 | 讯飞开放平台文档中心

下拉文档到最后,下面会有一些不同语言的调用接口示例,我们选择python的:

点击后会自动下载示例程序包:

解压后如下:

打开查看如下内容所示:

# coding: utf-8
import _thread as thread
import os
import time
import base64import base64
import datetime
import hashlib
import hmac
import json
from urllib.parse import urlparse
import ssl
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_timeimport websocket
import openpyxl
from concurrent.futures import ThreadPoolExecutor, as_completed
import osclass Ws_Param(object):# 初始化def __init__(self, APPID, APIKey, APISecret, gpt_url):self.APPID = APPIDself.APIKey = APIKeyself.APISecret = APISecretself.host = urlparse(gpt_url).netlocself.path = urlparse(gpt_url).pathself.gpt_url = gpt_url# 生成urldef create_url(self):# 生成RFC1123格式的时间戳now = datetime.now()date = format_date_time(mktime(now.timetuple()))# 拼接字符串signature_origin = "host: " + self.host + "\n"signature_origin += "date: " + date + "\n"signature_origin += "GET " + self.path + " HTTP/1.1"# 进行hmac-sha256进行加密signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),digestmod=hashlib.sha256).digest()signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')# 将请求的鉴权参数组合为字典v = {"authorization": authorization,"date": date,"host": self.host}# 拼接鉴权参数,生成urlurl = self.gpt_url + '?' + urlencode(v)# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致return url# 收到websocket错误的处理
def on_error(ws, error):print("### error:", error)# 收到websocket关闭的处理
def on_close(ws):print("### closed ###")# 收到websocket连接建立的处理
def on_open(ws):thread.start_new_thread(run, (ws,))def run(ws, *args):data = json.dumps(gen_params(appid=ws.appid, query=ws.query, domain=ws.domain))ws.send(data)# 收到websocket消息的处理
def on_message(ws, message):# print(message)data = json.loads(message)code = data['header']['code']if code != 0:print(f'请求错误: {code}, {data}')ws.close()else:choices = data["payload"]["choices"]status = choices["status"]content = choices["text"][0]["content"]print(content,end='')if status == 2:print("#### 关闭会话")ws.close()def gen_params(appid, query, domain):"""通过appid和用户的提问来生成请参数"""data = {"header": {"app_id": appid,"uid": "1234",           # "patch_id": []    #接入微调模型,对应服务发布后的resourceid          },"parameter": {"chat": {"domain": domain,"temperature": 0.5,"max_tokens": 4096,"auditing": "default",}},"payload": {"message": {"text": [{"role": "user", "content": query}]}}}return datadef main(appid, api_secret, api_key, gpt_url, domain, query):wsParam = Ws_Param(appid, api_key, api_secret, gpt_url)websocket.enableTrace(False)wsUrl = wsParam.create_url()ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)ws.appid = appidws.query = queryws.domain = domainws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})if __name__ == "__main__":main(appid="",api_secret="",api_key="",#appid、api_secret、api_key三个服务认证信息请前往开放平台控制台查看(https://console.xfyun.cn/services/bm35)gpt_url="wss://spark-api.xf-yun.com/v3.5/chat",# Spark_url = "ws://spark-api.xf-yun.com/v3.1/chat"  # v3.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat"  # v2.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v1.1/chat"  # v1.5环境的地址domain="generalv3.5",# domain = "generalv3"    # v3.0版本# domain = "generalv2"    # v2.0版本# domain = "general"    # v2.0版本query="给我写一篇100字的作文")
代码解释

这段代码定义了一个名为Ws_Param的类,用于处理WebSocket请求。以下是代码中各个方法的解释:

  1. __init__(self, APPID, APIKey, APISecret, gpt_url):初始化方法,用于设置类的实例变量。其中,APPID、APIKey、APISecret分别表示讯飞开放平台的应用ID、API Key和API Secret;gpt_url表示讯飞语音合成服务的URL。
  2. create_url(self):生成请求的URL。根据当前时间生成RFC1123格式的时间戳;然后,拼接签名字符串,包括host、date和GET请求行;接着,使用hmac-sha256算法对签名字符串进行加密;将加密后的签名字符串进行Base64编码,并将其添加到鉴权参数中,生成完整的URL。
  3. on_error(ws, error):收到WebSocket错误的处理方法。当WebSocket连接发生错误时,会调用此方法。
  4. on_close(ws):收到WebSocket关闭的处理方法。当WebSocket连接关闭时,会调用此方法。
  5. on_open(ws):收到WebSocket连接建立的处理方法。当WebSocket连接建立时,会调用此方法。在此处,会启动一个新的线程来运行run函数。
  6. run(ws, *args):运行函数,用于向讯飞语音合成服务发送请求。根据WebSocket实例的appid和question属性生成请求参数;然后,将请求参数转换为JSON字符串并通过WebSocket发送。
  7. on_message(ws, message):收到WebSocket消息的处理方法。当从讯飞语音合成服务接收到消息时,会调用此方法。解析接收到的消息;然后,根据消息中的code判断请求是否成功;如果成功,则将返回的内容累加到全局变量result中,并打印出来;如果code不为0,表示请求失败,此时关闭WebSocket连接。

官方的代码有个坑,就是answer = ""是个全局变量,这个会将所有的提问拼接在一起,不过这个影响不大,就是打印answer的结果不好看,只要我们输入时text列表清除历史输入,token还是不带历史。

2、代码调试

直接运行发现报错

发现是on_close()方法少传两个参数,实际在传参时是有三个参数,这里我们给它随便补两个参数,然后调试发现不报错了

运行结果:

3、代码调整

虽然上面的代码可以直接运行了,但是没有交互,只能运行一次,并且不能获取用户输入,如果想实现这样的功能,需要调整代码:

参考官方请求参数:

这里我需要给原来的代码添加一个text的列表,将我们要问的问题全部写入到text列表中,然后传递给query参数

封装函数,添加如下代码:

text = []# length = 0def getText(role, content):jsoncon = {}history_put = """['工程','货物',]\n请从上面选项中选择一个属于下面文本的分类\n左侧边坡宣传标语,结果只输出1,2 ,如果都不属于输出0"""text.append({'role': 'user', 'content': history_put})text.append({'role': 'assistant', 'content': '0'})# # 设置对话背景或者模型角色# text.append({"role": "system", "content": "你现在扮演李白,你豪情万丈,狂放不羁;接下来请用李白的口吻和用户对话。"})jsoncon["role"] = rolejsoncon["content"] = contenttext.append(jsoncon)return text

发现接口调用示例对text长度有要求:

注意:text里面的所有content内容加一起的tokens需要控制在8192以内,开发者如有较长对话需求,需要适当裁剪历史信息

需要添加对text长度的检测和判断代码:

#获取长度
def getlength(text):length = 0for content in text:temp = content["content"]leng = len(temp)length += lengreturn length#检测长度
def checklen(text):while getlength(text) > 8000:del text[0]return text

接下来对主函数main进行修改,实现交互式及循环请求:

if __name__ == "__main__":text.clear()while 1:Input = input("\n" + "我:")query = checklen(getText("user", Input))answer = ""print("星火:", end="")main(appid="xxxx",  # 填写控制台中获取的 APPID 信息api_secret="xxxxx",  # 填写控制台中获取的 APISecret 信息api_key="xxxxxx",  # 填写控制台中获取的 APIKey 信息# appid、api_secret、api_key三个服务认证信息请前往开放平台控制台查看(https://console.xfyun.cn/services/bm35)gpt_url="wss://spark-api.xf-yun.com/v3.5/chat",# Spark_url = "ws://spark-api.xf-yun.com/v3.1/chat"  # v3.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat"  # v2.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v1.1/chat"  # v1.5环境的地址domain="generalv3.5",# domain = "generalv3"    # v3.0版本# domain = "generalv2"    # v2.0版本# domain = "general"    # v2.0版本query=query)# 这里是获取星火AI模型助手的回答getText("assistant", answer)

在使用接口函数调用是加上text.clear(),清除历史对话,否则在一个长的连接调用时历史的token会加越来越长,十分消耗token,不需要历史的建议clear

请求参数这里需要调整,将之前的"text": [{"role": "user", "content": query}]改为如下,否则会报

json: cannot unmarshal array into Go struct field message.payload.message.text.content of type string'

调整后的代码如下:

def gen_params(appid, query, domain):"""通过appid和用户的提问来生成请参数"""data = {"header": {"app_id": appid,"uid": "1234",# "patch_id": []    #接入微调模型,对应服务发布后的resourceid          },"parameter": {"chat": {"domain": domain,"temperature": 0.5,"max_tokens": 4096,"auditing": "default",}},"payload": {"message": {"text": query}}}return data

4、代码测试

5、最终代码(亲测可用)

# coding: utf-8
import _thread as thread
import base64
import datetime
import hashlib
import hmac
import json
from urllib.parse import urlparse
import ssl
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_timeimport websockettext = []# length = 0class Ws_Param(object):# 初始化def __init__(self, APPID, APIKey, APISecret, gpt_url):self.APPID = APPIDself.APIKey = APIKeyself.APISecret = APISecretself.host = urlparse(gpt_url).netlocself.path = urlparse(gpt_url).pathself.gpt_url = gpt_url# 生成urldef create_url(self):# 生成RFC1123格式的时间戳now = datetime.now()date = format_date_time(mktime(now.timetuple()))# 拼接字符串signature_origin = "host: " + self.host + "\n"signature_origin += "date: " + date + "\n"signature_origin += "GET " + self.path + " HTTP/1.1"# 进行hmac-sha256进行加密signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),digestmod=hashlib.sha256).digest()signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')# 将请求的鉴权参数组合为字典v = {"authorization": authorization,"date": date,"host": self.host}# 拼接鉴权参数,生成urlurl = self.gpt_url + '?' + urlencode(v)# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致return url# 收到websocket错误的处理
def on_error(ws, error):print("### error:", error)# 收到websocket关闭的处理
def on_close(ws, one, two):print("### closed ###")# 收到websocket连接建立的处理
def on_open(ws):thread.start_new_thread(run, (ws,))def run(ws, *args):data = json.dumps(gen_params(appid=ws.appid, query=ws.query, domain=ws.domain))ws.send(data)# 收到websocket消息的处理
def on_message(ws, message):# print(message)data = json.loads(message)code = data['header']['code']if code != 0:print(f'请求错误: {code}, {data}')ws.close()else:choices = data["payload"]["choices"]status = choices["status"]content = choices["text"][0]["content"]print(content, end='')global answeranswer += contentif status == 2:print()print("#### 关闭会话")ws.close()def gen_params(appid, query, domain):"""通过appid和用户的提问来生成请参数"""data = {"header": {"app_id": appid,"uid": "1234",# "patch_id": []    #接入微调模型,对应服务发布后的resourceid          },"parameter": {"chat": {"domain": domain,"temperature": 0.5,"max_tokens": 4096,"auditing": "default",}},"payload": {"message": {"text": query}}}return datadef getText(role, content):jsoncon = {"role": role, "content": content}# history_put = """['工程','货物',]\n请从上面选项中选择一个属于下面文本的分类\n左侧边坡宣传标语#         ,结果只输出1,2 ,如果都不属于输出0#     """# text.append({'role': 'user', 'content': history_put})# text.append({'role': 'assistant', 'content': '0'})# # 设置对话背景或者模型角色# text.append({"role": "system", "content": "你现在扮演李白,你豪情万丈,狂放不羁;接下来请用李白的口吻和用户对话。"})text.append(jsoncon)return textdef getlength(text):length = 0for content in text:temp = content["content"]leng = len(temp)length += lengreturn lengthdef checklen(text):while getlength(text) > 8000:del text[0]return textdef main(appid, api_secret, api_key, gpt_url, domain, query):wsParam = Ws_Param(appid, api_key, api_secret, gpt_url)websocket.enableTrace(False)wsUrl = wsParam.create_url()ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)ws.appid = appidws.query = queryws.domain = domainws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})if __name__ == "__main__":text.clear()while 1:Input = input("\n" + "我:")query = checklen(getText("user", Input))answer = ""print("星火:", end="")main(appid="",  # 填写控制台中获取的 APPID 信息api_secret="",  # 填写控制台中获取的 APISecret 信息api_key="",  # 填写控制台中获取的 APIKey 信息# appid、api_secret、api_key三个服务认证信息请前往开放平台控制台查看(https://console.xfyun.cn/services/bm35)gpt_url="wss://spark-api.xf-yun.com/v3.5/chat",# Spark_url = "ws://spark-api.xf-yun.com/v3.1/chat"  # v3.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat"  # v2.0环境的地址# Spark_url = "ws://spark-api.xf-yun.com/v1.1/chat"  # v1.5环境的地址domain="generalv3.5",# domain = "generalv3"    # v3.0版本# domain = "generalv2"    # v2.0版本# domain = "general"    # v2.0版本query=query)# 这里是获取星火AI模型助手的回答getText("assistant", answer)

6、其他功能参数

system:设置对话背景或者模型角色

使用方法--> 旧版本传入请求数据时列表中只有usr和assistant这两个字典数据,现在要是使用system,只需要在usr前加入提示语字典如下图。

 也就是在上文应用分享中 getText函数,text.append(                   {"role":"system","content":"你现在扮演李白,你豪情万丈,狂放不羁;接下来请用李白的口吻和用户对话。"} )后面每次调用接口都是自带system

# 参数构造示例如下
{"header": {"app_id": "12345","uid": "12345"},"parameter": {"chat": {"domain": "generalv3.5","temperature": 0.5,"max_tokens": 1024, }},"payload": {"message": {# 如果想获取结合上下文的回答,需要开发者每次将历史问答信息一起传给服务端,如下示例# 注意:text里面的所有content内容加一起的tokens需要控制在8192以内,开发者如有较长对话需求,需要适当裁剪历史信息"text": [{"role":"system","content":"你现在扮演李白,你豪情万丈,狂放不羁;接下来请用李白的口吻和用户对话。"} #设置对话背景或者模型角色{"role": "user", "content": "你是谁"} # 用户的历史问题{"role": "assistant", "content": "....."}  # AI的历史回答结果# ....... 省略的历史对话{"role": "user", "content": "你会做什么"}  # 最新的一条问题,如无需上下文,可只传最新一条问题]}}
}

测试如下:

一股子诗人的味道,哈哈!

7、问题解决

问题现象

在websocket同服务器进行连接时,出现没有enableTrace属性:

module 'websocket' has no attribute 'enableTrace'

image-20231118234948161

问题原因

检查一下当前安装的websocket:

pip show websocket

检查这个库的相关发布信息:已经很久没维护了,早已被弃用:

pip_search websocket

解决方法

后续Python中websocket库改为使用websocket-client,需要重新安装:

卸载websocket,这个已弃用,websockets中没有enableTrace模块

 推荐安装如下库

 pip install websocket-client -i https://pypi.tuna.tsinghua.edu.cn/simple/

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

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

相关文章

优思学院|六西格玛中的普氏矩阵(Pugh Matrix)是什么?

决策矩阵(Pugh Matrix),也可称作普氏矩阵,它是由设计工程师斯图尔特普发展并得名。这是一个基于标准的矩阵,用于帮助团队从几个备选方案中定量确定给定问题的“最佳”解决方案。普矩阵通常用于产品设计,但实…

java spring 09 Bean的销毁过程 上 在docreatebean中登记要销毁的bean

1.Bean销毁是发送在Spring容器关闭过程中的 AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) context.getBean("userService");userService.test();// 容器关闭cont…

使用STM32CubeMX进行STM32F4的定时器配置

目录 1. Pin脚2. 配置2.1 时钟配置2.2 RCC配置2.3 Timer配置2.4 输出文件 3. 代码3.1 使能定时器3.2 回调函数 1. Pin脚 2. 配置 2.1 时钟配置 timer3时钟挂载在APB1上: 时钟配置如下: 外部使用8MHz晶振 开启内部16MHz晶振 使用锁相环 开启最高100MHz。…

React18+TS+NestJS+GraphQL 全栈开发在线教育平台

高质量平台级应用流行全栈技术实用职场技巧通用面试策略React18TSNestJSGraphQL 全栈开发在线教育平台(完结) 黑石老师,大厂技术专家,深耕前后端十多年。发现很多的前端同学都面临如下的职业困扰:没有能拿的出手的面试…

HTML批量文件上传2——进度条显示

作者:私语茶馆 非常多的云应用中需要上传文本,包括图片,文件等等,这些批量文件上传,往往涉及到进度条显示,多文件上传等,这里分享一个非常好的案例,来自BootStrapfriendly.com&#…

『MySQL 实战 45 讲』20 - 幻读是什么,幻读有什么问题?

幻读是什么,幻读有什么问题? 需求:创建一个小表 CREATE TABLE t (id int(11) NOT NULL,c int(11) DEFAULT NULL,d int(11) DEFAULT NULL,PRIMARY KEY (id),KEY c (c) ) ENGINEInnoDB;insert into t values(0,0,0),(5,5,5), (10,10,10),(15,…

开放原子龙蜥社区 2 大学习赛首批获奖者名单公布

近日,开放原子开源基金会联合龙蜥社区推出「人人都可以参与开源」和「基于 ECS Intel 实例部署 GPT-2 大语言模型」两大学习赛,此赛题长期有效,且有开放原子开源基金会和龙蜥社区共同提供的丰厚双重奖励机制。赛题一经发布,吸引了…

电脑内存不足怎么清理?教你3招轻松解决

电脑内存不足是影响电脑性能的常见问题之一,它会导致电脑运行缓慢、应用程序响应迟钝等情况。为了解决这个问题,需要对电脑内存进行清理和优化。本文将介绍电脑内存不足怎么清理的三种方法,帮助您提高电脑性能。 方法1:清理临时文…

高压开关柜局部放电监测装置APD

安科瑞薛瑶瑶18701709087/17343930412 APD系列高压柜局部放电监测装置通过检测伴随局部放电而产生的电磁波辐射,实时监测的开关柜内局部放电的放电次数和放电频次等数据,对电气设备绝缘状况进行评估,发现设备潜伏性故障,最终实现…

RUST 编程语言使构建更安全的软件变得更加容易。RUST ALL THE THINGS 需要什么?

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

Java初识继承

继承 文章目录 继承为什么需要继承继承中变量的访问特点继承中方法的访问特点继承的优缺点 概念:在Java中,继承是面向对象编程的一个基本特性。它允许我们定义一个新类,它从另一个已经存在的类继承其属性和方法。被继承的类称为父类或超类,新…

List的两种实现

前置知识: 数组 baseAddress:数组的首地址 dataTypeSize:数组中元素类型的大小,如int为4字节 为什么数组索引从0开始,假如从1开始不行吗? 在根据数组索引获取元素的时候,会用索引和寻址公式来计…

JAVA随记——集合篇

注意:作者之前的Java基础没有打牢,有一些知识点没有记住,所以在学习中出现了许多零散的问题。现在特地写一篇笔记总结一下,所以有些知识点不是很齐全。 集合中各类名词的关系 Collection集合为单列集合。 集合存储数据类型的特点…

森林消防—高扬程水泵,高效、稳定、可靠!/恒峰智慧科技

森林,作为地球的“绿色肺叶”,不仅为我们提供了丰富的自然资源,更是维持生态平衡的重要一环。然而,随着全球气候的变化和人为活动的增加,森林火灾频发,给生态环境和人民生命财产安全带来了巨大威胁。在森林…

与时代同行,Build with AI 2024 线下活动五月再次开放报名

技术开发日新月异,软硬件迭代和应用场景多样化对开发者提出了更多挑战。面对科技发展潮流,GDG (谷歌开发者社区) 一直秉承开放共创的精神,以热忱之心与开发者们一同探索 AI 的广阔发展前景。 在过去的四月里,我们在北京、上海、深…

php使用服务器端和客户端加密狗环境部署及使用记录(服务器端windows环境下部署、linux环境宝塔面板部署、客户端部署加密狗)

php使用服务器端和客户端加密狗环境部署及使用记录 ViKey加密狗环境部署1.windows环境下部署开发文档验证代码提示Fatal error: Class COM not found in 2.linux环境下部署(宝塔面板)开发文档验证代码提示Fatal error: Uncaught Error: Call to undefine…

加速乐 js解混淆 __jsl_clearance_s生成

提示!本文章仅供学习交流,严禁用于任何商业和非法用途,未经许可禁止转载,禁止任何修改后二次传播,如有侵权,可联系本文作者删除! 目标网站 aHR0cHM6Ly9jcmVkaXQuaGVmZWkuZ292LmNuL2NyZWRpdC13…

聚观早报 | 比亚迪首款新能源皮卡;苹果M4芯片有望登场

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 5月8日消息 比亚迪首款新能源皮卡 苹果M4芯片有望登场 红旗首款手机外观揭晓 一加13设计细节曝光 长城汽车4月销…

matlab 基于拉依达检验法(3σ准则) 实现多类别多参数的批量异常样本检验 V2.0

简介 拉依达检验法(3σ准则)是一种统计学方法,用于检测数据中的异常值。这种方法基于正态分布的特性来确定数据点是否可能是异常值。以下是关于拉依达检验法(3σ准则)的详细介绍: 基本原理: 拉…

Electron项目中将CommonJS改成使用ES 模块(ESM)语法preload.js加载报错

问题 将Electron项目原CommonJS语法改成使用ES 模块(ESM)语法,preload.js一直加载不到,报错如下: VM111 renderer_init:2 Unable to load preload script: D:\Vue\wnpm\electron\preload.js VM111 renderer_init:2 E…