Python连接Oracle运行KNN出现Input contains NaN等float64类型错误
报错原因及解决方案
核心触发原因
- KNN是基于数值距离计算的模型,无法直接处理字符串类型特征,你传入的
Province_name是VARCHAR2字符串类型,模型尝试将字符串转为数值时会生成非法值,触发报错 KNeighborsClassifier.fit()的入参格式错误,标准入参格式为fit(训练特征集X, 训练标签集y),你把特征集同时传入了两个参数,不符合接口要求- 即使表中无空值,Oracle的NUMBER(38,0)最大值可达1e38,远大于float64类型能承载的整数精度上限(2^53≈9e15),如果你的
cnt字段值超过这个范围,会触发溢出转为无穷大inf,也会触发该报错
解决步骤
- 处理字符串类型特征:将
Province_name转换为数值格式,可选择标签编码、独热编码两种方案,若暂时不需要省份字段参与计算,也可先仅保留cnt字段测试 - 修正模型入参格式:明确分类任务的特征列和标签列,按
fit(特征集, 标签集)的格式传参 - 校验数值范围:检查
cnt字段的最大值,若超出float64精度范围,做数值缩放或归一化处理
可运行参考代码
import pandas as pd import numpy as np from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder # 读取数据 无需重复查询两次同表 df = pd.read_sql_query('''select Province_name, cnt from Provincepartnercnt''' , conn) # 先校验是否存在异常值 print("空值统计:", df.isna().sum()) print("无穷大统计:", np.isinf(df['cnt']).sum()) print("cnt最大值、float64安全上限:", df['cnt'].max(), 2**53) # 转换字符串类型的省份为数值标签(如果省份是预测目标) le = LabelEncoder() df['Province_label'] = le.fit_transform(df['Province_name']) # 拆分特征、标签:示例以cnt为特征,预测对应的省份 X = df[['cnt']] y = df['Province_label'] # 模型训练 myKNN = KNeighborsClassifier(n_neighbors = 1) myKNN.fit(X, y)
如果需要将省份作为特征参与计算,可使用独热编码转换:
# 独热编码转换省份列,和cnt合并为特征集 province_onehot = pd.get_dummies(df['Province_name'], drop_first=True) X = pd.concat([df[['cnt']], province_onehot], axis=1)
内容的提问来源于stack exchange,提问作者Sara Moradi
相关产品推荐
相关产品推荐

