大连鼎信网站建设公司地址,网站建设做得好的公司,网站设计 站,关于营销策划的方案[TOC](【AI量化投研】- Modeling(四, 意外之喜))
背景
训练一直没有实际的效果,一方面准备好重来,要站在巨人的肩膀上做事,不再像无头苍蝇那样乱撞. 另一方面,原来的研究也不是毫无用处.发现,虽然损失函数长得很猥琐, 也不怎么收敛,但出现一些很神奇的结果:
精确度49.57%,召回…[TOC](【AI量化投研】- Modeling(四, 意外之喜))背景训练一直没有实际的效果,一方面准备好重来,要站在巨人的肩膀上做事,不再像无头苍蝇那样乱撞. 另一方面,原来的研究也不是毫无用处.发现,虽然损失函数长得很猥琐, 也不怎么收敛,但出现一些很神奇的结果:精确度49.57%,召回率63.42%,精确度58.92%,召回率43.01%,精确度66.86%,召回率36.73%,精确度70.77%,召回率21.66%,相当炸列了! 生财有道了! 说明:误打误撞拿到了一个有潜力的模型训练模式(虽然输入特征缺陷很大);F1 分值 与 我们要的方向已经比较接近了, (除了尚未融入盈亏比信息, 但其实融入盈亏比信息并无必要,因损失可通过策略止损获得缩小,只要胜率高已是胜利!);目前训练的一个要点是: 在样本分布不均衡的条件下, 正负样本权重差异设置, 是一个走钢丝的精细平衡过程,找到一个特别的点很重要;损失函数的猥琐, 尚不能代表模型训练的失败, 不过,它的不稳定,可能会导致样本外的表现动荡,尚需实证;不过:6. 模型没保存好;7. 损失寻优的方向与需要的方向不对头(但这次来看, 貌似如果以 F1 为方向搜索寻优能得到好结果,如何将F1 融入损失函数?);8. 数据本身只有32000,总样本量实际上是10W左右,因此,目前的结果仍然只处于测试阶段.尝试 损失函数 融入盈亏比计算盈亏比并融入损失函数不同类样本权重中.staticmethod def create_adaptive_loss(dataset, loss_typefocal_weighted): if isinstance(dataset, Subset): labels [dataset.dataset.binary_labels[i] for i in dataset.indices] returns [dataset.dataset.returns[i] for i in dataset.indices] else: labels dataset.binary_labels returns dataset.returns pos_count sum(1 for label in labels if label 1) neg_count sum(1 for label in labels if label 0) total len(labels) print(f 类别分布统计:) print(f 正样本: {pos_count} ({pos_count / total * 100:.1f}%)) print(f 负样本: {neg_count} ({neg_count / total * 100:.1f}%)) # 计算平均盈亏比 pos_returns [r for r, label in zip(returns, labels) if label 1 and r ! 0] neg_returns [abs(r) for r, label in zip(returns, labels) if label 0 and r ! 0] # 亏损取绝对值 avg_win np.mean(pos_returns) if pos_returns else 0.0 avg_loss np.mean(neg_returns) if neg_returns else 1.0 profit_loss_ratio avg_win / avg_loss if avg_loss ! 0 else 1.0 print(f 平均盈利: {avg_win:.4f}, 平均亏损: {avg_loss:.4f}, 盈亏比: {profit_loss_ratio:.4f}) if loss_type focal_weighted: class_weights torch.tensor([1.0, profit_loss_ratio], dtypetorch.float32).to(device) print(f Focal Loss 类别权重: 负样本1.00, 正样本{profit_loss_ratio:.2f}) return FocalLoss(alphaclass_weights, gamma2.0) else: print( 使用标准交叉熵损失) return nn.CrossEntropyLoss()尝试 损失函数 融入F1 Score直接让损失函数优化F1分数是一个很有价值的方向尤其是在正负样本不平衡的分类任务中。传统的交叉熵损失并不直接优化F1分数这会导致模型训练目标与最终评估指标不一致。以下是几种将F1分数融入损失函数的主流方法。 直接近似法软化F1的计算核心思路是让不可微的F1分数变得可微从而能够进行梯度下降。Dice Loss其思路是将F1分数Dice系数中的“整数计数”如TP, FP替换为模型预测的概率值即软化形成一个连续可微的近似版本。公式如下DL 1 - (2 * sum(y_true * y_pred) smooth) / (sum(y_true²) sum(y_pred²) smooth)其中 y_true是真实标签y_pred是预测概率。这个损失函数直接优化的是F1的软近似因此在F1指标上通常有良好表现。F1 Score Loss另一种直接的软化方式其目标是直接最大化F1分数# TensorFlow/Keras 示例 def f1_loss(y_true, y_pred): tp K.sum(y_true * y_pred, axis0) fp K.sum((1 - y_true) * y_pred, axis0) fn K.sum(y_true * (1 - y_pred), axis0) precision tp / (tp fp K.epsilon()) recall tp / (tp fn K.epsilon()) f1 2 * precision * recall / (precision recall K.epsilon()) return 1 - K.mean(f1) # 最小化 1 - F1 间接优化法改进交叉熵这类方法不直接计算F1而是通过调整交叉熵损失使其优化方向与提升F1一致。Focal Loss通过降低模型已能很好分类的样本通常是大量的简单负样本对损失的贡献让模型更专注于难以分类的样本这有助于提升召回率进而可能优化F1。其核心是一个调制因子 (1 - p_t)^gamma。# PyTorch 示例 class FocalLoss(nn.Module): def __init__(self, gamma2.0): super().__init__() self.gamma gamma def forward(self, logits, targets): ce_loss F.cross_entropy(logits, targets, reductionnone) p_t torch.exp(-ce_loss) focal_loss ((1 - p_t) ** self.gamma) * ce_loss return focal_loss.mean()加权交叉熵Weighted Cross-Entropy为少数类样本的损失分配更高的权重缓解类别不平衡问题这也是提升F1的常见策略。权重可以固定也可以根据每个批次的样本分布动态计算自适应权重。 : 软化F1 加权交叉熵 相结合将软化F1分数与加权交叉熵结合结合了两种方法的优势能更直接地引导模型优化关心的F1指标同时保持训练过程的稳定。结合一 - 复合损失下面是一个具体的方案。创建一个复合损失函数Composite Loss让软化F1分数和加权交叉熵协同工作。import torch import torch.nn as nn import torch.nn.functional as F class CompositeF1CrossEntropyLoss(nn.Module): 结合软化F1损失与加权交叉熵的复合损失函数 目标同时优化分类准确性和F1分数特别适用于不平衡数据 def __init__(self, alpha0.5, beta0.5, class_weightsNone, epsilon1e-7): Args: alpha: 软化F1损失的权重 beta: 加权交叉熵损失的权重 (alpha beta 通常为1) class_weights: 各类别的权重张量用于处理类别不平衡 epsilon: 平滑项防止除零 super().__init__() self.alpha alpha self.beta beta self.epsilon epsilon self.class_weights class_weights # 初始化加权交叉熵损失 if class_weights is not None: self.cross_entropy nn.CrossEntropyLoss( weightclass_weights, reductionmean ) else: self.cross_entropy nn.CrossEntropyLoss(reductionmean) def soft_f1_loss(self, y_pred, y_true): 计算软化F1损失基于Dice Loss思想 使用概率值而非硬标签使得损失函数可微 # 将真实标签转换为one-hot编码 y_true_oh F.one_hot(y_true, num_classesy_pred.size(1)).float() # 对预测值应用softmax y_pred_softmax F.softmax(y_pred, dim1) # 计算真正例、假正例、假负例的软化版本 tp (y_true_oh * y_pred_softmax).sum(dim0) fp ((1 - y_true_oh) * y_pred_softmax).sum(dim0) fn (y_true_oh * (1 - y_pred_softmax)).sum(dim0) # 计算软化精确率和召回率 precision tp / (tp fp self.epsilon) recall tp / (tp fn self.epsilon) # 计算软化F1分数 soft_f1 2 * (precision * recall) / (precision recall self.epsilon) # 返回平均F1损失最小化1-F1 return 1 - soft_f1.mean() def forward(self, y_pred, y_true): # 计算软化F1损失 f1_loss self.soft_f1_loss(y_pred, y_true) # 计算加权交叉熵损失 ce_loss self.cross_entropy(y_pred, y_true) # 组合损失 composite_loss self.alpha * f1_loss self.beta * ce_loss return composite_loss, f1_loss, ce_loss为了使复合损失函数达到最佳效果建议采用以下训练策略渐进式训练def get_training_schedule(total_epochs100): 制定渐进式训练计划 前期侧重交叉熵稳定收敛 后期侧重F1损失优化目标指标 schedule { phase1: {epochs: int(0.3 * total_epochs), alpha: 0.3, beta: 0.7}, phase2: {epochs: int(0.5 * total_epochs), alpha: 0.5, beta: 0.5}, phase3: {epochs: int(0.2 * total_epochs), alpha: 0.7, beta: 0.3} } return schedule关键参数初始化# 根据类别不平衡程度设置权重 def calculate_class_weights(labels): 计算类别权重处理不平衡数据 class_counts torch.bincount(labels) total_samples len(labels) class_weights total_samples / (len(class_counts) * class_counts.float()) return class_weights # 初始化损失函数 class_weights calculate_class_weights(training_labels) loss_fn CompositeF1CrossEntropyLoss( alpha0.5, beta0.5, class_weightsclass_weights )结合二 - 动态权重调整策略固定权重可能不是最优的。可以参考基于奖惩机制的动态权重方法让模型在训练过程中自动调整两个损失的比重.class AdaptiveCompositeLoss(nn.Module): 自适应权重的复合损失函数 根据训练阶段动态调整F1损失和交叉熵损失的权重 def __init__(self, total_epochs, initial_alpha0.3): super().__init__() self.total_epochs total_epochs self.initial_alpha initial_alpha def forward(self, y_pred, y_true, current_epoch): # 动态调整权重前期侧重CE稳定训练后期侧重F1优化 # 随着训练进行逐渐增加F1损失的权重 alpha self.initial_alpha (1 - self.initial_alpha) * (current_epoch / self.total_epochs) beta 1 - alpha # 计算各项损失 base_loss_fn CompositeF1CrossEntropyLoss() total_loss, f1_loss, ce_loss base_loss_fn(y_pred, y_true) # 应用动态权重 adaptive_loss alpha * f1_loss beta * ce_loss return adaptive_loss, f1_loss, ce_loss, alpha, beta结合小结优势目标一致性训练稳定性不平衡适应性灵活可调说明软化F1损失确保模型直接优化你关心的F1指标交叉熵损失提供良好的梯度信号防止训练震荡加权机制和F1优化共同应对类别不平衡问题动态权重机制让模型在不同训练阶段有不同侧重预期效果相比单一损失函数这种组合通常能在验证集上获得更高的F1分数同时保持较好的准确率。特别是在数据不平衡的场景下对少数类的识别能力会有明显提升。这种复合损失函数的设计思路本质上是让交叉熵负责夯实基础而软化F1负责冲刺高分两者协同工作共同推动模型向既准确又均衡的方向发展。