如何将Datetime类型时间序列作为特征进行KMeans聚类?
问题描述
有如下包含固定间隔连续数据的DataFrame(不确定tslearn KMeans聚类包是否适用):
date value 2022-09-06 01:40:50.999059 0.2732 2022-09-05 19:55:02.242936 0.9771 ...
尝试使用KMeans算法聚类时运行以下代码报错:
df.date = pd.to_datetime(df.date) data = df[["date","value"]] model = KMeans(init="random",n_clusters=k,n_init=10,max_iter=300,random_state=4) model.fit(data)
报错信息:
TypeError: The DType <class 'numpy.dtype[datetime64]'> could not be promoted by <class 'numpy.dtype[float64]'>. This means that no common DType exists for the given inputs. For example they cannot be stored in a single array unless the dtype is `object`. The full list of DTypes is: (<class 'numpy.dtype[datetime64]'>, <class 'numpy.dtype[float64]'>)
原因是KMeans要求输入为浮点型,但date列是datetime64类型,请问如何将date作为特征用于KMeans算法?
解决方法
KMeans仅支持数值型输入,需将datetime类型的date列转换为浮点/整数型特征,以下是几种可行方案:
1. 转换为时间戳数值
将datetime对象转为Unix时间戳(从1970-01-01 00:00:00 UTC开始的秒/毫秒数),得到纯数值特征:
# 转为秒级时间戳(整数/浮点型) df['date_timestamp'] = df['date'].astype('int64') // 10**9 # 若需保留毫秒精度,可改为除法 # df['date_timestamp'] = df['date'].astype('int64') / 10**9 # 用转换后的特征训练模型 data = df[["date_timestamp", "value"]] model = KMeans(init="random", n_clusters=k, n_init=10, max_iter=300, random_state=4) model.fit(data)
2. 提取时间维度特征
如果业务场景更关注时间的周期性(比如小时、星期、月份),可以从datetime中提取这些离散维度并转为数值:
# 提取小时、星期几(0=周一,6=周日)、月份等特征 df['hour'] = df['date'].dt.hour df['day_of_week'] = df['date'].dt.dayofweek df['month'] = df['date'].dt.month # 用提取的特征训练模型 data = df[["hour", "day_of_week", "month", "value"]] model = KMeans(init="random", n_clusters=k, n_init=10, max_iter=300, random_state=4) model.fit(data)
3. 标准化特征(可选但推荐)
KMeans基于距离计算,不同量级的特征会干扰聚类结果,建议对所有数值特征做标准化:
from sklearn.preprocessing import StandardScaler # 假设data是转换后的数值特征集合 scaler = StandardScaler() data_scaled = scaler.fit_transform(data) model.fit(data_scaled)
关于tslearn的适配性
tslearn的TimeSeriesKMeans是针对序列型样本(每个样本是一段连续时间序列)的聚类工具,如果你只是把单个时间点作为特征而非序列,普通sklearn的KMeans就足够;如果你的数据是按时间窗口分组的序列样本,再考虑使用tslearn的聚类方法。
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

