You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 如何处理该类型转换问题?
  2. 是否存在无需额外转换即可接受日期值的决策树分类器?

解答

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:57:46