You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用ADASYN遇NaN/无穷值错误的排查与解决(Python)

解决ADASYN的NaN/inf错误及高特征数问题

嘿,我来帮你搞定这个问题!你遇到的ValueError说明哪怕做了NaN和inf的替换与填充,数据里还是藏着这些问题,再加上2300+的特征量,确实会给处理增加难度。下面分两部分给你具体的解决方案:

1. 排查并定位问题数据

  • 先确认填充后的数据是否真的干净:
    • 检查是否还有残留的NaN:执行print(df_imputed.isna().any().any()),如果输出True,说明还有未填充的NaN;再用print(df_imputed.columns[df_imputed.isna().any()])定位具体出问题的列。
    • 检查是否有隐藏的inf:执行print(np.isinf(df_imputed).any().any()),定位列用print(df_imputed.columns[np.isinf(df_imputed).any()])
  • 为什么会出现这种情况?最常见的原因是某些列全是NaN:因为df.mean()对全NaN的列返回的还是NaN,所以fillna(df.mean())根本没填充这些列。你可以用df_imputed.isna().sum()[df_imputed.isna().sum() > 0]查看每列的NaN数量,确认是不是全NaN的列。
  • 另外检查特征列的类型:执行print(X.dtypes),如果有object类型的列,说明存在非数值型数据(比如字符串),这类列无法计算均值,填充后还是NaN,必然会导致ADASYN报错。
  • 最后排查极端值:有没有超出float64范围的数值?可以用print((df_imputed > np.finfo(np.float64).max).any().any())检查,不过这种情况比较少见,但也不能忽略。

2. 处理2300+特征的解决方案

第一步:先清理有问题的特征

  • 删掉全NaN的列:这类列完全没有有效信息,留着只会添乱,执行:
    df_clean = df_imputed.drop(df_imputed.columns[df_imputed.isna().all()], axis=1)
    
  • 处理非数值型列:如果是分类特征,用独热编码(pd.get_dummies())或者标签编码转换为数值;如果是无关的文本列,直接删除即可。
  • 换用更鲁棒的填充方式:对于有部分NaN的列,用中位数(df.fillna(df.median()))代替均值,避免极端值干扰;或者用sklearn.impute.KNNImputer基于邻近样本填充,比简单的统计量更准确。

第二步:特征筛选/降维减少特征数量

2300+特征里肯定有大量冗余或无关特征,先过滤掉一部分能大幅降低后续处理难度:

  • 方差过滤:去掉方差接近0的列(这类列几乎没有波动,对模型没用):
    from sklearn.feature_selection import VarianceThreshold
    selector = VarianceThreshold(threshold=1e-5)
    X_filtered = selector.fit_transform(df_clean.drop(['target'], axis=1))
    # 转换回DataFrame方便后续处理
    X_filtered_df = pd.DataFrame(X_filtered, columns=df_clean.drop(['target'], axis=1).columns[selector.get_support()])
    
  • 基于树模型的特征重要性筛选:用随机森林计算特征重要性,保留top N个或重要性超过阈值的特征:
    from sklearn.ensemble import RandomForestClassifier
    # 先拆分训练集测试集(注意要在特征筛选前拆分,避免数据泄露)
    X_train, X_test, y_train, y_test = train_test_split(df_clean.drop(['target'], axis=1), df_clean.target, test_size=0.3, random_state=0)
    
    rf = RandomForestClassifier(random_state=0)
    rf.fit(X_train, y_train)
    # 获取特征重要性并排序
    importances = pd.Series(rf.feature_importances_, index=X_train.columns).sort_values(ascending=False)
    # 保留重要性大于1e-4的特征(阈值可以根据实际情况调整)
    top_features = importances[importances > 1e-4].index
    X_selected_train = X_train[top_features]
    X_selected_test = X_test[top_features]
    
  • PCA降维:如果特征冗余度很高,可以用PCA将特征压缩到更低维度(比如200维),不过降维后特征的解释性会变差:
    from sklearn.decomposition import PCA
    pca = PCA(n_components=200, random_state=0)
    X_pca_train = pca.fit_transform(X_train)
    X_pca_test = pca.transform(X_test)
    

最后一步:验证数据

处理完数据后,一定要再次执行以下代码确认数据干净:

print(X_processed.isna().any().any())  # 应该输出False
print(np.isinf(X_processed).any().any())  # 应该输出False

确认没问题后再用ADASYN进行过采样就不会报错啦!

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

火山引擎 最新活动