You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现马氏距离异常检测预测模型及分类逻辑修正

马氏距离单类分类器(适配LDA特征)修正实现方案

核心问题排查

  • 分类器未遵循sklearn估计器接口规范,训练阶段从C0类计算得到的分布参数没有作为实例属性持久化,预测阶段无法调用训练好的分布信息
  • 预测流程缺失核心的马氏距离计算环节,predict_proba直接返回输入数据,判定逻辑完全失效,导致准确率虚高为100%
  • 标签映射规则不清晰,没有按照单类异常检测的逻辑划分正常/异常边界,无法正确识别假阴性样本

各方法正确实现逻辑

fit方法(训练阶段)

仅使用正常类C0的LDA特征作为训练输入,执行以下操作:

  • 校验输入特征格式为二维矩阵,记录特征维度
  • 计算C0类样本的特征均值向量,存储为实例属性self.mean_
  • 计算C0类样本的协方差矩阵,做正定校验后求逆,分别存储为self.cov_、self.inv_cov_(可添加极小单位矩阵扰动避免协方差矩阵奇异)
  • 基于训练集马氏距离的分布确定异常阈值:可选择卡方分布对应置信度的分位点,或训练集样本马氏距离的经验分位点,存储为self.threshold_
  • 方法末尾返回self,符合sklearn接口要求

内部马氏距离计算方法

实现私有方法_calc_mahalanobis供预测阶段调用:

  • 校验输入样本的特征维度和训练阶段一致
  • 批量计算每个输入样本到C0类分布的马氏距离,返回一维距离数组

predict方法(预测阶段)

  • 调用内部距离计算方法,得到所有输入样本的马氏距离
  • 判定规则:马氏距离 ≤ 阈值的样本判定为正常类C0(标签设为0),马氏距离 > 阈值的样本判定为异常类(标签设为1,对应C1-C4)
  • 返回和输入样本长度一致的标签数组

predict_proba方法(概率输出)

禁止直接返回输入数据,按以下逻辑实现:

  • 基于样本的马氏距离转换为类别概率:距离越近,属于正常类C0的概率越高;距离越远,属于异常类的概率越高
  • 返回形状为(n_samples, 2)的数组,第一列为异常类概率,第二列为正常类概率,匹配sklearn接口规范

可直接复用的实现代码

import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
from scipy.stats import chi2

class MahalanobisOneclassClassifier(BaseEstimator, ClassifierMixin):
    def __init__(self, confidence=0.95):
        self.confidence = confidence

    def fit(self, X, y=None):
        # 存储C0类分布参数
        n_samples, n_features = X.shape
        self.mean_ = np.mean(X, axis=0)
        # 加1e-6单位矩阵扰动保证协方差正定
        self.cov_ = np.cov(X, rowvar=False) + 1e-6 * np.eye(n_features)
        self.inv_cov_ = np.linalg.inv(self.cov_)
        # 卡方分布计算阈值:自由度等于特征数
        self.threshold_ = np.sqrt(chi2.ppf(self.confidence, df=n_features))
        return self

    def _calc_mahalanobis(self, X):
        # 批量计算马氏距离
        diff = X - self.mean_
        left_term = np.dot(diff, self.inv_cov_)
        dist_sq = np.sum(left_term * diff, axis=1)
        return np.sqrt(dist_sq)

    def predict(self, X):
        dist = self._calc_mahalanobis(X)
        # 大于阈值判为异常(1),否则为正常(0)
        return (dist > self.threshold_).astype(int)

    def predict_proba(self, X):
        dist = self._calc_mahalanobis(X)
        # 距离转换为正常类概率,用sigmoid形式保证概率在0-1区间
        prob_normal = 1 / (1 + np.exp(dist - self.threshold_))
        prob_abnormal = 1 - prob_normal
        return np.column_stack([prob_abnormal, prob_normal])

评估注意事项

  • 标签映射统一:评估前将测试集的C0类样本标记为0(正类,正常),所有C1-C4类样本标记为1(负类,异常)
  • 假阴性样本无需手动标记:真实标签为1(C1-C4类)但预测标签为0(距离低于阈值被误判为正常)的样本,会自动被sklearn的confusion_matrix、classification_report识别统计
  • 禁止数据泄露:预测阶段不得重新计算协方差、均值等分布参数,必须全程使用fit阶段在C0训练集上得到的参数
  • 结果校验:训练完成后在C0训练集上做预测,异常样本占比应接近设置的显著性水平(如confidence=0.95时异常占比约5%),不会出现100%准确率的异常结果

内容的提问来源于stack exchange,提问作者WDpad159

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.14 16:15:48