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

基于Keras ANN的旧金山犯罪预测:日期特征转换与小时独热编码咨询

处理SF Crime数据集的特征转换(Keras ANN建模)

针对你用Keras构建ANN处理SF Crime数据集的几个特征转换问题,我给你整理了具体的实现方法和建议:

1. 将DayOfWeek转换为工作日/周末二值特征

假设你的DataFrame列DayOfWeek存储的是类似"Monday"、"Sunday"这样的字符串,两种简单的实现方式:

方法一:用Pandas isin()(推荐,性能更优)

这种方法对大数据集更友好,逻辑也直观:

# 定义周末的日期列表
weekend_list = ["Saturday", "Sunday"]
# 生成二值列:周末为1,工作日为0
df["is_weekend"] = df["DayOfWeek"].isin(weekend_list).astype(int)

方法二:用lambda函数+apply()

如果更习惯lambda的写法,也可以这样实现:

df["is_weekend"] = df["DayOfWeek"].apply(lambda x: 1 if x in ["Saturday", "Sunday"] else 0)

2. 将月份映射为四季类别特征

首先明确月份到四季的映射逻辑(可根据需求调整):

  • 冬季:12、1、2
  • 春季:3、4、5
  • 夏季:6、7、8
  • 秋季:9、10、11

同样有两种常见实现方式:

方法一:字典映射+map()(推荐,代码更易维护)

用字典存储映射关系,后续调整季节划分时只需修改字典:

season_mapping = {
    1: "Winter", 2: "Winter", 12: "Winter",
    3: "Spring", 4: "Spring", 5: "Spring",
    6: "Summer", 7: "Summer", 8: "Summer",
    9: "Fall", 10: "Fall", 11: "Fall"
}
# 假设Month列是整数类型(1-12),如果是字符串需先转int:df["Month"] = df["Month"].astype(int)
df["season"] = df["Month"].map(season_mapping)

方法二:lambda函数+apply()

如果不想额外定义字典,也可以用嵌套条件的lambda:

df["season"] = df["Month"].apply(
    lambda x: "Winter" if x in [1, 2, 12]
    else "Spring" if x in [3, 4, 5]
    else "Summer" if x in [6, 7, 8]
    else "Fall"
)

注意:如果之后要把season喂给Keras模型,需要将这个类别特征进一步转换(比如用pd.get_dummies()做独热编码,或者用Keras的嵌入层)。

3. Hour值的独热编码建议

Hour是0-23的离散数值,独热编码是可行的,但也有其他更高效的处理方式,给你几个选项:

选项一:传统独热编码(简单直接)

用Pandas的get_dummies()快速生成独热编码列:

# 生成前缀为hour的独热编码列
hour_onehot = pd.get_dummies(df["Hour"], prefix="hour")
# 合并到原DataFrame
df = pd.concat([df, hour_onehot], axis=1)
# 可选:删除原Hour列
df.drop("Hour", axis=1, inplace=True)

这种方式生成24个特征列,对于大部分数据集来说不会造成维度爆炸,适合快速实现。

选项二:在Keras模型内处理独热编码

如果不想在预处理阶段做编码,可以直接在模型中加入CategoryEncoding层:

from keras.layers import Input, CategoryEncoding

# 定义Hour的输入层
hour_input = Input(shape=(1,))
# 0-23共24个类别,output_mode设为one_hot
hour_encoded = CategoryEncoding(num_tokens=24, output_mode="one_hot")(hour_input)

这种方式更适合端到端的建模流程。

选项三:更高效的特征转换(推荐考虑)

如果想减少特征维度同时保留时间信息,可以试试以下两种方式:

  1. 分时段编码:将Hour合并为更粗的时段(如凌晨、上午、下午、晚上),再做独热编码,仅生成4个特征列:
df["time_period"] = df["Hour"].apply(
    lambda x: "night" if 0 <= x < 6
    else "morning" if 6 <= x < 12
    else "afternoon" if 12 <= x < 18
    else "evening"
)
# 对时段做独热编码
period_onehot = pd.get_dummies(df["time_period"], prefix="period")
df = pd.concat([df, period_onehot], axis=1)
  1. 循环编码(Cyclical Encoding):将Hour转换为sin和cos值,捕捉时间的周期性(比如23点和0点的相似性),仅生成2个特征列:
import numpy as np

df["hour_sin"] = np.sin(2 * np.pi * df["Hour"] / 24)
df["hour_cos"] = np.cos(2 * np.pi * df["Hour"] / 24)

这种方式维度极低,还能让模型学习到时间的循环规律,适合对效率要求较高的场景。

内容的提问来源于stack exchange,提问作者UHU

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:41:10