解决|RuntimeWarning: invalid value encountered in double_scalars W = numer / denom

报错:RuntimeWarning: invalid value encountered in double_scalars W = numer / denom
先自查数据里有没有NaN,然后,我发现我代码里的levene和t检验部分会涉及多步除法。一旦分母为0或NaN就会出现上述报错
在chatgpt帮我过了一遍两个检验计算时所有可能的分母时,发现一共三种情况:
1-样本数异常(为0或为1——自由度为0),我的数据中没有这种情况;
2-计算t统计量时,分母包含合并方差,一旦为0,会报错
3-计算Levene统计量时,分母包含组内方差,一旦为0,会报错
然后我去翻了一下我的特征矩阵的csv文件,发现:
(1)确实有几列提取特征出来所有样本(group_0和group_1)的值均为一样,这种特征一方面会导致合并方差为0然后t检验时报错,另一方面这根本无法区分两组,显然不是我们需要的特征。
(2)也有的组内值一样的情况,这种特征其实未必不能区分,但是不剔除掉会报错,仁者见仁智者见智了。。。(但其实我自己的数据上,我剔除和不剔除都试了,结果一样的,,,剔除了的话,不报错看着舒心些罢了)
因此在进行levene和ttest前,我选择,直接将合并方差为0的特征以及组内方差为0的特征忽略掉即可解决报错

相关代码修改如下:

def t_test_feature_selection(X, y):
    y = y.squeeze()  # 将 y 转换为 Series
    n_samples, n_features = X.shape  # 获取X的样本数量n_samples和特征数量n_features
    selected_features = []  # 用于存储通过t检验的特征索引

    for feature_index in range(n_features):
        # 遍历每个特征
        feature_data = X[:, feature_index]  # 每列特征存储至feature_data
        group_0 = feature_data[y == 0]  # 根据目标变量y的值,每列特征分为2个group
        group_1 = feature_data[y == 1]

        # 检查合并方差是否为0
        combined_data = np.concatenate([group_0, group_1])
        if np.var(combined_data, ddof=1) == 0:
            continue  # 合并方差为0,跳过该特征

        # 检查每组的方差是否为0,导致Levene计算异常
        if np.var(group_0, ddof=1) == 0 or np.var(group_1, ddof=1) == 0:
            continue  # 某组方差为0,跳过该特征

        # 进行Levene检验和t检验
        if levene(group_0, group_1)[1] > 0.05:  # Levene检验方差齐性,p>0.05代表方差齐
            if ttest_ind(group_0, group_1)[1] < 0.05:  # 独立t检验p<0.05,说明2个group间显著差异
                selected_features.append(feature_index)
        else:
            if ttest_ind(group_0, group_1, equal_var=False)[1] < 0.05:  # 方差不齐时,独立t检验要设置equal_var=False
                selected_features.append(feature_index)

    return selected_features
posted @ 2024-08-05 13:41  xjl_ultrasound  阅读(209)  评论(0)    收藏  举报