Gaussian Mixture绘图报错及基于GMM的离群点提取问题咨询
报错解决方案
你遇到的ValueError: min value must be less than or equal to max value报错,本质是CPH1920型号对应的数据分布和其他型号差异大,硬设的绘图参数不匹配该型号的数据范围:
- 你代码中
levels=np.logspace(0, 3, 10)固定了等高线阈值范围是1~1000,同时LogNorm(vmax=500)固定了归一化的最大值为500,如果CPH1920对应的-Z数组最大值小于1,就会出现阈值下限高于数据最大值的矛盾,触发报错。 - 修复方法:
- 先打印
-Z的数值范围确认:print(-Z.min(), -Z.max()) - 动态适配数据生成阈值:
levels = np.logspace(np.log10(max(1e-3, -Z.min())), np.log10(-Z.max()), 10) - 移除固定的vmax参数,让归一化逻辑自动适配数据:
norm=LogNorm()
- 先打印
等高线外侧点的离群判定
紫色一般是等高线的最外层,对应最低的分布概率密度阈值,紫色圆圈外的点属于拟合高斯混合分布的概率极低的样本,常规场景下可以直接判定为离群点。
离群点提取与阈值筛选方法
完全可以通过概率阈值筛选可用数据,核心逻辑和操作步骤如下:
- 逻辑纠正:GMM做离群检测的规则是「样本属于拟合分布的概率越低,越可能是离群点」,你提到的「概率大于0.5判定为离群点」逻辑反过来了,正确规则是低于设定阈值的样本判定为离群点。
- 操作步骤:
- 对每个型号单独拟合GMM后,调用
score_samples方法得到每个样本的对数概率密度:log_probs = gmm.score_samples(model_df[['r_max', 'b_max']].values) - 两种常用阈值设置方式:
- 固定分位筛选:比如保留概率最高的95%样本,取对数概率的5分位数作为阈值:
threshold = np.percentile(log_probs, 5),小于该值的为离群点 - 匹配等高线筛选:取最外层紫色等高线的level值作为阈值:
threshold = -CS.levels[0],小于该值的就是圆圈外的离群点
- 固定分位筛选:比如保留概率最高的95%样本,取对数概率的5分位数作为阈值:
- 筛选代码示例:
# 单型号数据筛选示例 model_df = df[df['model'] == 'CPH1920'].copy() # 拟合GMM(n_components按你实际使用的数量设置即可) gmm = GaussianMixture(n_components=2, random_state=42) gmm.fit(model_df[['r_max', 'b_max']]) # 计算所有样本的对数概率密度 log_probs = gmm.score_samples(model_df[['r_max', 'b_max']]) # 设定阈值,这里以保留95%非离群点为例 threshold = np.percentile(log_probs, 5) # 筛选得到可用于后续EDA的干净数据 clean_df = model_df[log_probs >= threshold].copy() # 提取识别到的离群点 outlier_df = model_df[log_probs < threshold].copy() - 对每个型号单独拟合GMM后,调用
- 补充说明:
score_samples返回的是对数概率密度,不需要特意转换为0-1区间的概率,直接用对数概率的相对大小做筛选即可,不会影响结果准确性。
内容的提问来源于stack exchange,提问作者user16285826
相关产品推荐
相关产品推荐

