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

优化多分类数据集下KDE交集面积计算的Python函数问题

搞定多分类下KDE交集面积的鲁棒计算问题

我来帮你把代码优化成支持任意类别数的版本,先拆解下问题,再一步步解决:

先修正你代码里的小bug

你原来的类别提取和参数引用有两处错误:

  • data.target_variable_name.unique() 是错的,因为target_variable_name是函数传入的字符串参数,得用索引方式data[target_variable_name].unique()
  • 后面的target_name是笔误,要和参数名target_variable_name统一

核心逻辑:多分类要算所有类别对的交集

对于多分类任务,我们需要计算每两个不同类别之间的KDE交集(避免重复计算,比如只算(0,1)不算(1,0)),可以用itertools.combinations生成所有不重复的类别对。

完整优化后的代码

import numpy as np
import pandas as pd
from scipy.stats import gaussian_kde
from itertools import combinations

def intersection_area(data, bandwidth, margin, target_variable_name):
    # 预处理:删除缺失值,分离自变量和目标变量
    data = data.dropna()
    feature_names = data.drop(columns=[target_variable_name], axis=1).columns.tolist()
    
    # 获取所有唯一类别,转成列表
    classes = data[target_variable_name].unique().tolist()
    # 生成所有不重复的类别对(比如(0,1)、(0,2),不会重复生成(1,0))
    class_pairs = list(combinations(classes, 2))
    
    # 存储结果的列表,方便后续转成DataFrame
    results = []
    
    # 遍历每个特征
    for feature in feature_names:
        # 遍历每个类别对
        for class_a, class_b in class_pairs:
            # 提取当前类别对对应的特征数据(这就是你卡住的部分,现在搞定了)
            x_a = data.loc[data[target_variable_name] == class_a, feature]
            x_b = data.loc[data[target_variable_name] == class_b, feature]
            
            # 计算两个类别的KDE
            kde_a = gaussian_kde(x_a, bw_method=bandwidth)
            kde_b = gaussian_kde(x_b, bw_method=bandwidth)
            
            # 确定x轴范围:覆盖两个类别的数据范围,再加上margin扩展(修正了你原来的min错误)
            x_min = min(x_a.min(), x_b.min())
            x_max = max(x_a.max(), x_b.max())
            dx = margin * (x_max - x_min)
            x_range = np.linspace(x_min - dx, x_max + dx, 500)
            
            # 计算KDE在x轴上的取值
            kde_a_vals = kde_a(x_range)
            kde_b_vals = kde_b(x_range)
            
            # 计算交集区域的面积
            intersection_vals = np.minimum(kde_a_vals, kde_b_vals)
            area = np.trapz(intersection_vals, x_range)
            
            # 把结果存入列表
            results.append({
                'feature': feature,
                'class_pair': f"({class_a}, {class_b})",
                'intersection_area': round(area, 4)
            })
    
    # 返回结构化的结果DataFrame,方便查看和后续分析
    return pd.DataFrame(results)

用你的模拟数据集测试

from sklearn.datasets import make_classification

# 生成4分类模拟数据集
X, y = make_classification(
    n_samples=50000, n_features=6, n_informative=6, n_redundant=0, n_repeated=0,
    n_classes=4, n_clusters_per_class=3, class_sep=0.95, flip_y=0.2,
    weights=[0.7, 0.2, 0.1], shuffle=True, random_state=93
)
dataset_x = pd.DataFrame({
    'var1': X[:, 0], 'var2': X[:, 1], 'var3': X[:, 2],
    'var4': X[:, 3], 'var5': X[:, 4], 'var6': X[:, 5]
})
dataset_y = pd.DataFrame({'target': y})
sample_dataset = pd.concat([dataset_x, dataset_y], axis=1)

# 调用函数计算交集面积
result_df = intersection_area(sample_dataset, bandwidth=0.5, margin=0.1, target_variable_name='target')
print(result_df.head(10))

几个关键细节说明

  • 用itertools.combinations生成类别对,避免重复计算,节省资源
  • 修正了你原来x轴范围的错误:把x_max = min(...)改成了max(...),不然会截断KDE的尾部,导致面积计算不准
  • 返回的是DataFrame格式结果,比单纯打印更方便后续分析、排序或可视化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:08:13