Sklearn分类器处理含日期/分类特征的司机驾驶预测问题
司机驾驶行为预测模型训练问题解答
问题背景
预测注册司机是否会实际开始驾驶,使用Sklearn基础分类器开展训练。
数据集情况
包含分类特征(如city_name、signup_os、signup_channel)和日期特征(如signup_date、bgc_date),示例数据如下:
city_name signup_os signup_channel signup_date bgc_date first_completed_date did_drive Strark ios web Paid 1/2/16 NaN NaN no Strark windows Paid 1/21/16 NaN NaN no
尝试的模型及代码
使用Logistic Regression、LinearSVC、DecisionTreeClassifier等多种Sklearn分类器,代码如下:
from sklearn.model_selection import train_test_split X = refined_df[['city_name','signup_os','signup_channel','signup_date','bgc_date']] y = refined_df['did_drive'] X_train, X_test, y_train, y_test = train_test_split(X, y , test_size=0.25, random_state=0) models = {} # Logistic Regression from sklearn.linear_model import LogisticRegression models['Logistic Regression'] = LogisticRegression() # Support Vector Machines from sklearn.svm import LinearSVC models['Support Vector Machines'] = LinearSVC() # Decision Trees from sklearn.tree import DecisionTreeClassifier models['Decision Trees'] = DecisionTreeClassifier() # Random Forest from sklearn.ensemble import RandomForestClassifier models['Random Forest'] = RandomForestClassifier() # Naive Bayes from sklearn.naive_bayes import GaussianNB models['Naive Bayes'] = GaussianNB() # K-Nearest Neighbors from sklearn.neighbors import KNeighborsClassifier models['K-Nearest Neighbor'] = KNeighborsClassifier() from sklearn.metrics import accuracy_score, precision_score, recall_score accuracy, precision, recall = {}, {}, {} for key in models.keys(): # Fit the classifier models[key].fit(X_train, y_train) # Make predictions predictions = models[key].predict(X_test) # Calculate metrics accuracy[key] = accuracy_score(predictions, y_test) precision[key] = precision_score(predictions, y_test) recall[key] = recall_score(predictions, y_test)
遇到的问题
运行代码时出现错误 ValueError: could not convert string to float: 'Berton',无法将分类字符串转换为浮点数,且日期值也导致模型运行失败。
疑问
- 如何处理该类型转换问题?
- 是否存在无需额外转换即可接受日期值的决策树分类器?
解答
1. 类型转换问题的解决方法
Sklearn所有分类器都要求输入特征为数值型,必须对分类特征和日期特征做预处理:
分类特征处理
- 独热编码(One-Hot Encoding):适合无顺序关系的分类特征(如
city_name、signup_os),可处理未知类别,推荐用ColumnTransformer结合OneHotEncoder实现:from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.impute import SimpleImputer cat_features = ['city_name', 'signup_os', 'signup_channel'] # 构建预处理管道,先填充缺失值再独热编码 cat_preprocessor = ColumnTransformer( transformers=[ ('cat', OneHotEncoder(handle_unknown='ignore'), cat_features) ], remainder='passthrough' ) - 标签编码仅适合有明确顺序的分类特征,不建议用于无顺序特征,否则会引入错误的数值关联。
日期特征处理
原始日期字符串无法直接输入模型,需转换为数值特征:
- 提取日期差值:计算
signup_date与固定日期的间隔天数,或signup_date和bgc_date的时间差,缺失值用中位数填充:import pandas as pd # 转换为日期格式 refined_df['signup_date'] = pd.to_datetime(refined_df['signup_date'], errors='coerce') refined_df['bgc_date'] = pd.to_datetime(refined_df['bgc_date'], errors='coerce') # 生成数值型日期特征 refined_df['signup_days'] = (pd.Timestamp('2024-01-01') - refined_df['signup_date']).dt.days refined_df['bgc_days'] = (pd.Timestamp('2024-01-01') - refined_df['bgc_date']).dt.days # 填充缺失值 refined_df[['signup_days', 'bgc_days']] = refined_df[['signup_days', 'bgc_days']].fillna( refined_df[['signup_days', 'bgc_days']].median() ) # 更新特征集 X = refined_df[['city_name','signup_os','signup_channel','signup_days','bgc_days']] - 也可提取年、月、日、星期几等时间分量作为数值特征。
2. 是否存在无需转换的决策树分类器?
不存在。Sklearn中的DecisionTreeClassifier、RandomForestClassifier等所有树模型,同样要求输入为数值型特征,无法直接处理字符串或原始日期格式。必须先将日期和分类特征转换为数值后才能训练。
不过树模型对特征缩放不敏感,日期特征转成数值后无需标准化,直接使用原始差值或时间分量即可。
内容的提问来源于stack exchange,提问作者ERJAN
相关产品推荐
相关产品推荐

