测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)

简介: 这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。

一、任务描述

通过给定的算法接口,对算法的输出(置信度、检测框、告警、类别等)进行数据处理,结合原标签完成TP、FP、FN、TN、准确率、召回率的指标测试。

二、指标分析

2.1 TP/FP/FN/TN

TP(True Positives,真正例):表示模型正确预测为正类的样本数量,也就是将正例正确分类为正例的数量。

FP(False Positives,假正例):表示模型错误预测为正类的样本数量,也就是将负例错误分类为正例的数量。

FN(False Negatives,假负例):表示模型错误预测为负类的样本数量,也就是将正例错误分类为负例的数量。

TN(True Negatives,真负例):表示模型正确预测为负类的样本数量,也就是将负例正确分类为负例的数量。

2.2 精准率

精准率是指模型在所有被预测为正例的样本中,真正为正例的比例。它的计算公式是:Precision = TP / (TP + FP)。精准率衡量了模型的预测中有多少是真正的正例,是一个关于假正例的指标。

2.3 召回率

召回率是指模型在所有实际正例中,成功预测为正例的比例。它的计算公式是:Recall = TP / (TP + FN)。召回率衡量了模型对于所有正例的识别能力,是一个关于假负例的指标。

三、接口处理

import os, base64, json, time, requests

def get_all_file(path):
    result_list = []
    for root, dirs, files in os.walk(path):
        for file in files:
            if os.path.basename(file).__contains__(".jpg"):
                result_list.append(os.path.join(root, file))
    return result_list

def pic2base64(img_path):
    if os.path.exists(img_path):
        encoded_base64 = base64.b64encode(open(img_path, 'rb').read()).decode()
        return encoded_base64
    else:
        os.error("图片不存在,请检查图片路径:{}".format(img_path))

def write_content_to_json(content, json_file_path):
    with open(json_file_path, 'w+', encoding='utf-8') as f:
        f.write(json.dumps(content, indent=4, ensure_ascii=False))

if __name__ == "__main__":
    result = {}
    fish_pic_path = r"D:\datasets\test_mission\fishing_test_data"
    url_fish = "http://***.***.***.*:端口号/能力接口"
    pic_list = get_all_file(fish_pic_path)
    for pic in pic_list:
        image_base64 = pic2base64(pic)
        payload = {
            "seqid": "test1",
            "timestamp": int(time.time()),
            "image": image_base64
            # "image": rf';base64,{image_base64}\"alt=\"\">'
        }
        res = requests.post(url_fish, json=payload)
        json_res = res.json()
        print(json_res)
        if 'code' in json_res and json_res['code'] == 6000:
            result[os.path.basename(pic)] = json_res['data']
    write_content_to_json(result, 'result/fish_result.json')

将所有的结果保存为JSON文档,如下:
在这里插入图片描述

四、数据集处理

数据集统一处理成:
在这里插入图片描述

数据集如果是JSON格式,通过下面的代码转换为TXT格式

import os
import numpy as np
import json
from glob import glob
import cv2
from sklearn.model_selection import train_test_split
from shutil import copyfile
import argparse

obj_classes = []

# Labelme坐标到YOLO V5坐标的转换
def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)

def create(yolo_labels_dir):
    if not os.path.exists(yolo_labels_dir):
        os.makedirs(yolo_labels_dir)

# 样本转换
def convertToYolo5(fileList, output_dir, labelImg_path, unify_path):
    # 创建指定样本的父目录
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # 创建指定样本的images和labels子目录
    yolo_images_dir = '{}/images/'.format(output_dir)
    yolo_labels_dir = '{}/labels/'.format(output_dir)

    create(yolo_images_dir)
    create(yolo_labels_dir)
    create(unify_path)

    # 一个样本图片一个样本图片地转换
    for num,json_file_ in enumerate(fileList):
        # print('fileList',fileList)
        # 1. 生成YOLO样本图片
        # 构建json图片文件的全路径名
        imagePath = labelImg_path + '/' + json_file_ + ".jpg"
        print('name',imagePath, json_file_)
        # print('labelme_path', labelme_path)
        # 构建Yolo图片文件的全路径名
        yolo_image_file_path = yolo_images_dir + "{}.jpg".format(json_file_)
        print('yolo_image_file_path', yolo_image_file_path)

        # copy样本图片
        copyfile(imagePath, yolo_image_file_path)

        # 2. 生成YOLO样本标签
        # 构建json标签文件的全路径名

        labelme_path_ = labelImg_path.split('image')[0]

        json_filename = labelme_path_ + 'json'+'\\' + json_file_ + ".json"

        # 构建Yolo标签文件的全路径名
        yolo_label_file_path = yolo_labels_dir + "{}.txt".format(json_file_)
        txt_label_file_path = unify_path + "/{}.txt".format(json_file_)

        # 创建新的Yolo标签文件
        yolo_label_file = open(yolo_label_file_path, 'w')
        txt_label_file = open(txt_label_file_path, 'w')

        # 获取当前图片的Json标签文件
        json_obj = json.load(open(json_filename, "r", encoding="utf-8"))

        # 获取当前图片的长度、宽度信息
        height = json_obj['imageHeight']
        width = json_obj['imageWidth']

        # 依次读取json文件中所有目标的shapes信息
        for shape in json_obj["shapes"]:
            # 获取shape中的物体分类信息
            label = shape["label"]
            if label not in ['car_red','car_orange','car_green','car_blue','car_black','car_white','car_purple','car_grey','car_silvery','car grey','car orange','car black','car','car blue','car purple','car white','car silvery','car green','car_yellow','car red']:
                if label == 'Fengtain' or label == 'FengTain' or label == 'FengtTian' or label == 'Fengtian':
                    label = 'FengTian'
                if (label not in obj_classes):
                    obj_classes.append(label)

                # 获取shape中的物体坐标信息
                if (shape["shape_type"] == 'rectangle'):
                    points = np.array(shape["points"])
                    xmin = min(points[:, 0]) if min(points[:, 0]) > 0 else 0
                    xmax = max(points[:, 0]) if max(points[:, 0]) > 0 else 0
                    ymin = min(points[:, 1]) if min(points[:, 1]) > 0 else 0
                    ymax = max(points[:, 1]) if max(points[:, 1]) > 0 else 0

                    # 对坐标信息进行合法性检查
                    if xmax <= xmin:
                        pass
                    elif ymax <= ymin:
                        pass
                    else:
                        # Labelme坐标转换成YOLO V5坐标
                        bbox_labelme_float = (float(xmin), float(xmax), float(ymin), float(ymax))
                        bbox_yolo_normalized = convert((width, height), bbox_labelme_float)

                        # 把分类标签转换成分类id
                        class_id = obj_classes.index(label)

                        # 生成YOLO V5的标签文件
                        yolo_label_file.write(str(class_id) + " " + " ".join([str(a) for a in bbox_yolo_normalized]) + '\n')

                        # 保存为统一的位置
                        txt_label_file.write(str(class_id) + " " + " ".join([str(a) for a in bbox_yolo_normalized]) + '\n')

        yolo_label_file.close()
        txt_label_file.close()

def check_output_directory(output=""):
    # 创建保存输出图片的目录
    save_path = output + '/'
    is_exists = os.path.exists(save_path)

    if is_exists:
        print('Warning: path of %s already exist, please remove it firstly by manual' % save_path)
        # shutil.rmtree(save_path)  # 避免误删除已有的文件
        return ""

    # print('create output path %s' % save_path)
    os.makedirs(save_path)

    return save_path

def create_yolo_dataset_cfg(output_dir='', label_class=[]):
    # 创建文件
    data_cfg_file = open(output_dir + '/data.yaml', 'w')

    # 创建文件内容
    data_cfg_file.write('train:  ../train/images\n')
    data_cfg_file.write("val:    ../valid/images\n")
    data_cfg_file.write("test:   ../test/images\n")
    data_cfg_file.write("\n")
    data_cfg_file.write("# Classes\n")
    data_cfg_file.write("nc: %s\n" % len(label_class))
    data_cfg_file.write('names: ')
    i = 0
    for label in label_class:
        if (i == 0):
            data_cfg_file.write("[")
        else:
            data_cfg_file.write(", ")
            if (i % 10 == 0):
                data_cfg_file.write("\n        ")
        i += 1
        data_cfg_file.write("'" + label + "'")
    data_cfg_file.write(']  # class names')
    data_cfg_file.close()
    # 关闭文件

def labelImg2yolo(input='', output='', unify_path=""):
    outputdir_root = output + '/'
    labelImg_path = input
    print(labelImg_path)
    labelImg_path_imagepath = labelImg_path + '\\' + 'image'
    print(labelImg_path_imagepath)
    json_path = labelImg_path+'\\'+'json'
    print(json_path)

    print("*"*100)

    # 1.获取input目录中所有的json标签文件全路径名
    files = glob(json_path + "/*.json")
    print(files)

    # 2.获取所有标签文件的短文件名称
    files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files]
    print(files)

    # 3. 按比例随机切分数据集,获取训练集样本
    train_files, valid_test_files = train_test_split(files, test_size=0.2, random_state=55)

    # 4. 按比例随机切分数据集,获取验证集和测试集样本
    valid_files, test_files = train_test_split(valid_test_files, test_size=0.1, random_state=55)

    # 5. 构建YOLO数据集目录
    train_path = outputdir_root + '/train'
    valid_path = outputdir_root + '/valid'
    test_path = outputdir_root + '/test'

    # 6. 生成YOLO 训练、验证、测试数据集:图片+标签
    convertToYolo5(train_files, train_path, labelImg_path_imagepath, unify_path)
    convertToYolo5(valid_files, valid_path, labelImg_path_imagepath, unify_path)
    convertToYolo5(test_files, test_path, labelImg_path_imagepath, unify_path)
    print("*"*100)
    # 7. 创建YOLO数据集配置文件
    create_yolo_dataset_cfg(output, obj_classes)
    labelme_path = input

    print("Classes:", obj_classes)
    print('Finished, output path =', outputdir_root)

    return 0

def parse_opt():
    # define argparse object
    parser = argparse.ArgumentParser()

    # input 包含两个文件夹, image和json,分别存放了对应的文件
    parser.add_argument('--input', type=str, default=r'F:\python\mission\fish_power_test\data\test',help='The input LabelImg directory')
    # output 存放保存的yolov5的训练数据,分为train、val、test三个文件,里面分别存放了对应的images和labels,在train目录下还存放了yolov5加载数据集的yaml文件(见data.yaml)
    parser.add_argument('--output', type=str,default=r'F:\python\mission\fish_power_test\data\test/yolo_txt', help='The output YOLO V5 directory')
    # 统一存放
    parser.add_argument('--unify_path', type=str,default=r'F:\python\mission\fish_power_test\data\test/txt', help='The output txt directory')

    # parse arges from command line
    opt = parser.parse_args()
    print("input  =", opt.input)
    print("output =", opt.output)
    print("unify_path =", opt.unify_path)
    # return opt
    return opt

def main(opt):
    labelImg2yolo(**vars(opt))

if __name__ == '__main__':
    opt = parse_opt()
    main(opt)

然后通过下面的代码将源标签的txt文档进行总结

# 将txt标签对应的原始的label和boxs写入到txt文档中
import cv2
import os

# 读取txt文件信息
def read_list(txt_path):
    pos = []
    with open(txt_path, 'r') as file_to_read:
        while True:
            lines = file_to_read.readline()  # 整行读取数据
            if not lines:
                break
            # 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。
            p_tmp = [float(i) for i in lines.split(' ')]
            pos.append(p_tmp)  # 添加新读取的数据
            pass
    return pos

def draw_box_in_single_image(image_path, txt_path, image_name):
    # 读取图像
    image = cv2.imread(image_path)
    pos = read_list(txt_path)
    reses = []
    reses.append(image_name)
    for i in range(len(pos)):
        label = classes[int(str(int(pos[i][0])))]
        print('label is '+label)

        # 将中心坐标、宽度和高度转换为 xywh 格式
        x_center = int(pos[i][1] * image.shape[1])
        y_center = int(pos[i][2] * image.shape[0])
        width = int(pos[i][3] * image.shape[1])
        height = int(pos[i][4] * image.shape[0])

        x_min = x_center - width // 2
        y_min = y_center - height // 2

        # 绘制矩形框
        cv2.rectangle(image, (x_min, y_min), (x_min + width, y_min + height), colores[int(str(int(pos[i][0])))], 2)
        cv2.putText(image, label, (x_min, y_min - 2), 0, 1, colores[int(str(int(pos[i][0])))], thickness=2, lineType=cv2.LINE_AA)

        res = [label, x_min, y_min, width, height]

        reses.append(res)
    # cv2.imshow("images", image)
    # cv2.waitKey(0)
    return reses

if __name__ == '__main__':
    f =  open('result/ori_data.txt', 'w+')
    img_folder = "data/test/image"
    img_list = [f for f in os.listdir(img_folder) if f.endswith('.jpg')]
    img_list.sort()

    label_folder =  "data/test/txt"
    label_list = [f for f in os.listdir(label_folder) if f.endswith('.txt')]
    label_list.sort()

    classes = {0: "fishing", 1: "no_fishing"}
    colores = [(0, 0, 255), (255, 0, 255)]

    for i in range(len(img_list)):
        image_path = os.path.join(img_folder, img_list[i])
        txt_path = os.path.join(label_folder, label_list[i])
        reses = draw_box_in_single_image(image_path, txt_path, img_list[i])
        print(reses)
        f.write(str(reses))
        f.write("\n")
    f.close()

五、开始计算指标

处理之后就可以得到检测后的fish_result.json和ori_data.txt。然后根据这两个文件来计算即可。

部分重要代码放在这里面:链接
在这里插入图片描述

五、实用工具

5.1 移动文件

import os
import shutil

# 源文件夹和目标文件夹的路径
source_folder = 'fishing_test_data'
destination_folder = 'test/image'

# 确保目标文件夹存在,如果不存在就创建它
if not os.path.exists(destination_folder):
    os.makedirs(destination_folder)

# 遍历源文件夹中的文件
for filename in os.listdir(source_folder):
    # 检查文件扩展名是否为图片格式,可以根据需要添加其他格式
    if filename.endswith(('.jpg', '.png', '.jpeg')):
        # 构建源文件的完整路径和目标文件的完整路径
        source_file_path = os.path.join(source_folder, filename)
        destination_file_path = os.path.join(destination_folder, filename)

        # 移动文件
        shutil.move(source_file_path, destination_file_path)
        print(f'Moved: {filename} to {destination_folder}')

5.2 可视化JSON标签

# -*- coding: utf-8 -*-
import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Path
from glob import glob

id2cls = {0: 'fishing', 1: "no_fishing"}
cls2id = {'fishing': 0,  "no_fishing": 1}
id2color = {"fishing": (0, 255, 0), "no_fishing": (0, 255, 255)}

# 支持中文路径
def cv_imread(filePath):
    cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), flags=cv2.IMREAD_COLOR)
    return cv_img

def get_labelme_info(label_file):
    anno = json.load(open(label_file, "r", encoding="utf-8"))
    shapes = anno['shapes']
    image_path = os.path.basename(anno['imagePath'])
    labels = []
    for s in shapes:
        pts = s['points']
        x1, y1 = pts[0]
        x2, y2 = pts[1]
        color = id2color[s["label"]]
        labels.append([color, x1, y1, x2, y2])
    return labels, image_path

def vis_labelme(labelme_label_dir, save_dir='res/'):
    labelme_label_dir = str(Path(labelme_label_dir)) + '/'
    save_dir = str(Path(save_dir)) + '/'
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    json_files = glob(labelme_label_dir + '*.json')
    for ijf, jf in enumerate(json_files):
        print(ijf + 1, '/', len(json_files), jf)
        filename = os.path.basename(jf).rsplit('.', 1)[0]
        labels, image_path = get_labelme_info(jf)
        image = cv_imread(labelme_label_dir + image_path)
        for label in labels:
            color = label[0]
            x1, y1, x2, y2 = label[1:]
            x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
            cv2.rectangle(image, (x1, y1), (x2, y2), color, 3)
        # 显示图片
        # cv2.imshow(filename, image)
        # cv2.waitKey(0)
        # 支持中文路径,保存图片
        cv2.imencode(os.path.splitext(image_path)[-1], image)[1].tofile(save_dir + image_path)
    print('Completed!')

if __name__ == '__main__':
    root_dir = r'D:\Python\money\data\test'
    save_dir = r'D:\Python\money\data\test/t'
    vis_labelme(root_dir, save_dir)

5.3 可视化TXT标签

import cv2
import os

# 读取txt文件信息
def read_list(txt_path):
    pos = []
    with open(txt_path, 'r') as file_to_read:
        while True:
            lines = file_to_read.readline()  # 整行读取数据
            if not lines:
                break
            # 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。
            p_tmp = [float(i) for i in lines.split(' ')]
            pos.append(p_tmp)  # 添加新读取的数据
            # Efield.append(E_tmp)
            pass
    return pos

# txt转换为box
def convert(size, box):
    xmin = (box[1] - box[3] / 2.) * size[1]
    xmax = (box[1] + box[3] / 2.) * size[1]
    ymin = (box[2] - box[4] / 2.) * size[0]
    ymax = (box[2] + box[4] / 2.) * size[0]
    box = (int(xmin), int(ymin), int(xmax), int(ymax))
    return box

def draw_box_in_single_image(image_path, txt_path):
    # 读取图像
    image = cv2.imread(image_path)
    pos = read_list(txt_path)

    for i in range(len(pos)):
        label = classes[int(str(int(pos[i][0])))]
        print('label is '+label)
        box = convert(image.shape, pos[i])
        image = cv2.rectangle(image,(box[0], box[1]),(box[2],box[3]),colores[int(str(int(pos[i][0])))],2)
        cv2.putText(image, label,(box[0],box[1]-2), 0, 1, colores[int(str(int(pos[i][0])))], thickness=2, lineType=cv2.LINE_AA)

    cv2.imshow("images", image)
    cv2.waitKey(0)

if __name__ == '__main__':

    img_folder = r"F:\python\mission\fish_power_test\data\test\yolo_txt\train\images"
    img_list = os.listdir(img_folder)
    img_list.sort()

    label_folder = r"F:\python\mission\fish_power_test\data\test\yolo_txt\train/labels"
    label_list = os.listdir(label_folder)
    label_list.sort()

    classes = {0: "fishing", 1: "no_fishing"}
    colores = [(0,0,255),(255,0,255)]

    for i in range(len(img_list)):
        image_path = img_folder + "\\" + img_list[i]
        txt_path = label_folder + "\\" + label_list[i]
        draw_box_in_single_image(image_path, txt_path)
目录
相关文章
|
4月前
|
存储 人工智能 测试技术
HarmonyOS Next~HarmonyOS应用测试全流程解析:从一级类目上架到二级类目专项测试
本文深入解析HarmonyOS应用测试全流程,涵盖从一级类目通用测试到二级类目专项测试的技术方案。针对兼容性、性能、安全测试及分布式能力验证等关键环节,提供详细实践指导与代码示例。同时,结合典型案例分析常见问题及优化策略,帮助开发者满足华为严苛的质量标准,顺利上架应用。文章强调测试在开发中的核心地位,助力打造高品质HarmonyOS应用。
205 2
|
4月前
|
算法 JavaScript 数据安全/隐私保护
基于GA遗传优化的最优阈值计算认知异构网络(CHN)能量检测算法matlab仿真
本内容介绍了一种基于GA遗传优化的阈值计算方法在认知异构网络(CHN)中的应用。通过Matlab2022a实现算法,完整代码含中文注释与操作视频。能量检测算法用于感知主用户信号,其性能依赖检测阈值。传统固定阈值方法易受噪声影响,而GA算法通过模拟生物进化,在复杂环境中自动优化阈值,提高频谱感知准确性,增强CHN的通信效率与资源利用率。预览效果无水印,核心程序部分展示,适合研究频谱感知与优化算法的学者参考。
|
6月前
|
算法 数据安全/隐私保护
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。
126 14
|
7月前
|
算法 安全 大数据
【算法合规新时代】企业如何把握“清朗·网络平台算法典型问题治理”专项行动?
在数字化时代,算法推动社会发展,但也带来了信息茧房、大数据杀熟等问题。中央网信办发布《关于开展“清朗·网络平台算法典型问题治理”专项行动的通知》,针对六大算法问题进行整治,明确企业需落实算法安全主体责任,建立健全审核与管理制度,并对算法进行全面审查和备案。企业应积极自查自纠,确保算法合规透明,防范风险,迎接新机遇。
|
7月前
|
算法
MATLAB在风险管理中的应用:从VaR计算到压力测试
本文介绍如何使用MATLAB进行风险管理,涵盖风险度量(如VaR)、压力测试和风险分解。通过历史模拟法、参数法和蒙特卡洛模拟法计算VaR,评估投资组合在极端市场条件下的表现,并通过边际VaR和成分VaR识别风险来源。结合具体案例和代码实现,帮助读者掌握MATLAB在风险管理中的应用,确保投资组合的稳健性。
|
10月前
|
存储 缓存 监控
性能测试中关注的指标
性能测试关注多个层面的指标,包括系统层(CPU、内存、磁盘、网络)、中间件层(网关、数据库、缓存、MQ、分布式存储)、应用层(响应时间、吞吐量、应用资源、GC、错误信息)及业务层和发压机指标。这些指标帮助评估系统性能,识别潜在瓶颈,确保软件质量和用户体验。
683 5
|
11月前
|
监控 算法 数据安全/隐私保护
基于三帧差算法的运动目标检测系统FPGA实现,包含testbench和MATLAB辅助验证程序
本项目展示了基于FPGA与MATLAB实现的三帧差算法运动目标检测。使用Vivado 2019.2和MATLAB 2022a开发环境,通过对比连续三帧图像的像素值变化,有效识别运动区域。项目包括完整无水印的运行效果预览、详细中文注释的代码及操作步骤视频,适合学习和研究。
|
14天前
|
机器学习/深度学习 算法 新能源
【优化调度】基于matlab粒子群算法求解水火电经济调度优化问题研究(Matlab代码实现)
【优化调度】基于matlab粒子群算法求解水火电经济调度优化问题研究(Matlab代码实现)
|
16天前
|
算法 机器人 定位技术
基于机器视觉和Dijkstra算法的平面建筑群地图路线规划matlab仿真
本程序基于机器视觉与Dijkstra算法,实现平面建筑群地图的路径规划。通过MATLAB 2022A读取地图图像,识别障碍物并进行路径搜索,支持鼠标选择起点与终点,最终显示最优路径及长度,适用于智能导航与机器人路径规划场景。
|
17天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化的XGBoost时间序列预测算法matlab仿真
本程序基于Matlab 2024b实现,结合粒子群优化(PSO)与XGBoost算法,用于时间序列预测。通过PSO优化XGBoost超参数,提升预测精度。程序包含完整注释与操作视频,运行后生成预测效果图及性能评估指标RMSE。

热门文章

最新文章