如何在sklearn KNN的.fit()方法中同时使用字符串与浮点型数据
解决KNN训练时"could not convert string to float"错误
问题原因
KNN是基于距离计算的模型,仅支持数值型输入特征。你的inputs数据中包含Sex、ChestPainType、RestingECG、ExerciseAngina、ST_Slope等字符串类型的分类特征,scikit-learn无法自动将这类特征转换为浮点型,因此训练时抛出ValueError。
解决方案
针对字符串分类特征,有两种常用的数值化处理方式,根据特征类型选择:
方案1:标签编码(Label Encoding)
适用于有序分类特征(例如ST_Slope的Up/Flat/Down存在明确顺序关系),将每个唯一字符串映射为一个整数。
修改后的代码:
import pandas as pd from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 定义输入输出特征 inputs = data.drop(['HeartDisease'], axis='columns') output = data['HeartDisease'] # 直接提取目标列更简洁 # 遍历所有列,对字符串类型列做标签编码 label_encoder = LabelEncoder() for col in inputs.columns: if inputs[col].dtype == 'object': inputs[col] = label_encoder.fit_transform(inputs[col]) # 拆分训练集和测试集 x_train, x_test, y_train, y_test = train_test_split(inputs, output, train_size=0.8) # 训练KNN模型 model = KNeighborsClassifier(n_neighbors=31) model.fit(x_train, y_train)
方案2:独热编码(One-Hot Encoding)
适用于无序分类特征(例如ChestPainType的不同类型无顺序关联),将每个类别转化为独立的二进制列,避免模型误判类别间存在大小关系。
修改后的代码:
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 定义输入输出特征 inputs = data.drop(['HeartDisease'], axis='columns') output = data['HeartDisease'] # 对字符串类型列做独热编码,drop_first避免多重共线性 inputs = pd.get_dummies(inputs, drop_first=True) # 拆分训练集和测试集 x_train, x_test, y_train, y_test = train_test_split(inputs, output, train_size=0.8) # 训练KNN模型 model = KNeighborsClassifier(n_neighbors=31) model.fit(x_train, y_train)
注意事项
- 若先拆分数据集再编码,需保证训练集和测试集使用同一套编码规则:标签编码时仅在训练集调用
fit_transform,测试集调用transform;独热编码时可使用ColumnTransformer统一处理。 - 优先根据特征的实际含义选择编码方式,无序特征用独热编码更合理,避免引入错误的顺序假设。
内容的提问来源于stack exchange,提问作者Akshay Basutkar
相关产品推荐
相关产品推荐

