混合数据类型下特征选择及随机森林字符串转浮点数报错咨询
核心结论与修复方案
1. 字符串转数值是否为必须操作
是必须操作。Scikit-learn框架下的所有算法(包括随机森林)仅支持数值型矩阵输入,无法直接处理标称/分类型字符串特征,这是你触发ValueError: could not convert string to float报错的直接原因。
另外需要注意你当前代码的逻辑问题:如果Prime列是类似示例中300的连续数值,你选择的RandomForestClassifier是分类模型,并不适配回归任务,需要替换为RandomForestRegressor,仅当Prime是离散分类标签时才保留分类器配置。同时类似40,000带逗号的数值列需要先做格式清洗转成纯数值,否则也会被识别为字符串触发报错。
2. 具体修复方案
方案1:编码转换后用Scikit-learn随机森林
对分类特征做编码处理,结合流水线避免数据泄露,示例代码如下:
import pandas as pd from sklearn.ensemble import RandomForestRegressor from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.pipeline import Pipeline # 数据读取与格式清洗 df = pd.read_csv(data, delimiter=";") # 清洗带逗号的数值列,示例如下,按需替换列名 df['Car_price'] = df['Car_price'].str.replace(',', '').astype(float) # 按特征类型分类,替换为你实际的列名 cat_cols = ['Brand', 'Model'] # 所有字符串类型的分类特征列 num_cols = ['Car_price'] # 所有原生数值类型列 feature_cols = cat_cols + num_cols X = df[feature_cols] Y = df['Prime'] # 构建预处理+模型流水线 preprocessor = ColumnTransformer( transformers=[ # 低基数分类特征用独热编码,高基数特征可替换为目标编码 ('cat', OneHotEncoder(sparse_output=False, drop='first'), cat_cols), ('num', 'passthrough', num_cols) ]) pipe = Pipeline(steps=[ ('preprocessor', preprocessor), # 分类任务替换为RandomForestClassifier ('model', RandomForestRegressor(n_jobs=-1, max_depth=5, random_state=42)) ]) pipe.fit(X, Y) # 提取特征重要性 ohe_feature_names = pipe.named_steps['preprocessor'].named_transformers_['cat'].get_feature_names_out(cat_cols) all_feature_names = list(ohe_feature_names) + num_cols importances = pipe.named_steps['model'].feature_importances_ # 生成按重要性排序的特征表 feature_importance_df = pd.DataFrame({ 'feature': all_feature_names, 'importance': importances }).sort_values(by='importance', ascending=False) print(feature_importance_df)
方案2:用原生支持分类特征的模型
如果不想手动做编码转换,可以选择LightGBM、CatBoost等支持直接传入分类特征的树模型,无需额外编码即可输出特征重要性,以CatBoost为例:
import pandas as pd from catboost import CatBoostRegressor, Pool df = pd.read_csv(data, delimiter=";") df['Car_price'] = df['Car_price'].str.replace(',', '').astype(float) cat_cols = ['Brand', 'Model'] num_cols = ['Car_price'] feature_cols = cat_cols + num_cols X = df[feature_cols] Y = df['Prime'] train_pool = Pool(data=X, label=Y, cat_features=cat_cols) # 分类任务替换为CatBoostClassifier model = CatBoostRegressor(max_depth=5, verbose=0, random_state=42) model.fit(train_pool) # 提取特征重要性 feature_importance_df = pd.DataFrame({ 'feature': feature_cols, 'importance': model.get_feature_importance() }).sort_values(by='importance', ascending=False) print(feature_importance_df)
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

