将泰坦尼克号数据集列转为Int8后,Sklearn SVC报错原因咨询
问题:转换列类型后SVM训练报错的原因分析
背景
在Kaggle泰坦尼克号数据集上运行SVM分类脚本,原本代码可正常执行,但将部分列转为Int8类型后,模型训练阶段抛出错误。
原正常运行代码
import pandas as pd from sklearn.svm import SVC from sklearn.model_selection import train_test_split X = df.drop(['Survived'], axis=1) y = df['Survived'] X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.33, random_state=10) clf = SVC() clf.fit(X_train,y_train) clf.predict(X_test) clf.score(X_test,y_test)
导致报错的类型转换代码
df = df.astype( {'Survived':'Int8', 'Pclass':'Int8', 'SibSp': 'Int8', 'Parch': 'Int8'})
报错信息(翻译后)
ValueError: 输入包含NaN、无穷大或超出float64 dtype范围的值。
原因分析
核心问题是pandas可空整数类型与scikit-learn的兼容性冲突:
- 你使用的
Int8是pandas的可空整数扩展类型,允许列中存在NaN值; - 但scikit-learn模型依赖numpy数组做底层计算,而numpy原生
int8类型不支持NaN。当scikit-learn尝试将pandas的Int8列转为numpy数组时,会因NaN的存在自动转为float64类型,若数据中确实有NaN,就会触发输入非法值的错误。
解决办法
方法1:先填充缺失值,再转原生整数类型
如果列中存在NaN,先根据数据特性填充缺失值(比如中位数、众数或固定值),再转为numpy原生的小写int8类型:
# 示例:填充各列缺失值后转换类型 df['Survived'] = df['Survived'].fillna(0).astype('int8') df['Pclass'] = df['Pclass'].fillna(df['Pclass'].median()).astype('int8') df['SibSp'] = df['SibSp'].fillna(0).astype('int8') df['Parch'] = df['Parch'].fillna(0).astype('int8')
方法2:直接用numpy原生整数类型(无NaN时适用)
如果列中没有缺失值,直接用小写的int8(numpy原生类型)代替pandas的Int8,规避可空类型的兼容性问题:
df = df.astype( {'Survived':'int8', 'Pclass':'int8', 'SibSp': 'int8', 'Parch': 'int8'})
内容的提问来源于stack exchange,提问作者Michele Assirelli
相关产品推荐
相关产品推荐

