求基于IoU匹配的时间序列分段任务Python评估指标实现
时间序列分段评估(带IoU容错)的Python实现
核心逻辑
你需要的是基于区间IoU匹配的分段级评估方案:先通过设定的IoU阈值(70%)找到真实分段与预测分段的有效匹配对,再基于匹配结果计算精确率、召回率、F1等核心指标。以下是针对你已算出IoU值的场景的具体实现:
基于已计算IoU的实现代码
1. 分段匹配(贪心策略)
该函数会从IoU矩阵中筛选出满足阈值的最优匹配对,避免一对多/多对一的重复匹配:
import numpy as np def match_segments(iou_matrix, threshold=0.7): matches = {} iou_copy = iou_matrix.copy() num_true, num_pred = iou_copy.shape # 每次选取当前IoU最大的有效对进行匹配 while np.max(iou_copy) >= threshold: true_idx, pred_idx = np.unravel_index(np.argmax(iou_copy), iou_copy.shape) matches[true_idx] = pred_idx # 标记已匹配的分段,不再参与后续匹配 iou_copy[true_idx, :] = -1 iou_copy[:, pred_idx] = -1 return matches
2. 计算分段级评估指标
基于匹配结果,计算召回率(真实分段的匹配覆盖率)、精确率(预测分段的有效率)和F1分数:
def calculate_segment_metrics(matches, total_true_segments, total_pred_segments): matched_count = len(matches) recall = matched_count / total_true_segments if total_true_segments > 0 else 0.0 precision = matched_count / total_pred_segments if total_pred_segments > 0 else 0.0 f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0.0 return { "recall": round(recall, 4), "precision": round(precision, 4), "f1": round(f1, 4), "matched_pairs": matched_count }
3. 完整使用示例
# 示例:真实分段与预测分段的IoU矩阵(3个真实分段 × 4个预测分段) iou_matrix = np.array([ [0.75, 0.0, 0.0, 0.0], # 真实分段0与预测0的IoU=75%(符合阈值) [0.0, 0.8, 0.0, 0.0], # 真实分段1与预测1的IoU=80%(符合阈值) [0.0, 0.0, 0.72, 0.0] # 真实分段2与预测2的IoU=72%(符合阈值) ]) # 执行匹配 matches = match_segments(iou_matrix, threshold=0.7) # 计算指标 metrics = calculate_segment_metrics(matches, total_true_segments=3, total_pred_segments=4) print("匹配结果(真实分段索引→预测分段索引):", matches) print("评估指标:", metrics)
输出示例:
匹配结果(真实分段索引→预测分段索引): {0: 0, 1: 1, 2: 2} 评估指标: {'recall': 1.0, 'precision': 0.75, 'f1': 0.8571, 'matched_pairs': 3}
进阶优化选项
- 标签一致性校验:如果需要仅匹配同标签的分段,可以在计算IoU前先过滤掉不同标签的分段对,将它们的IoU值设为-1。
- 全局最优匹配:若要替代贪心策略,可用匈牙利算法实现全局最优匹配,避免局部最优问题:
from scipy.optimize import linear_sum_assignment def match_segments_hungarian(iou_matrix, threshold=0.7): cost_matrix = 1 - iou_matrix # 将IoU低于阈值的对设为极大值,排除出匹配范围 cost_matrix[iou_matrix < threshold] = np.inf true_indices, pred_indices = linear_sum_assignment(cost_matrix) matches = {} for t_idx, p_idx in zip(true_indices, pred_indices): if cost_matrix[t_idx][p_idx] != np.inf: matches[t_idx] = p_idx return matches
内容的提问来源于stack exchange,提问作者riridev
相关产品推荐
相关产品推荐

