基于y距0的距离与每日标准差的聚类:为CART生成分类标签
嘿,我看你已经把需求梳理得很清晰了——要基于每日标准差(y-true)与0的距离做K-Means聚类,分成4个类别(组1最小,组4最大),再把这个聚类结果当作CART算法的分类标签,而且已经把日期特征X转成数值型了。下面我给你一套实操的步骤和代码,帮你顺利落地:
1. 明确聚类特征
因为每日标准差本身是非负的,所以它与0的距离就是它自身的数值,不需要额外计算绝对值。我们直接用y-true列作为K-Means的聚类特征即可。
2. K-Means聚类实现与标签修正
K-Means默认输出的聚类标签是随机分配的(比如可能把最小的簇标为2,最大的标为0),所以必须手动调整标签顺序,确保组1对应最小标准差,组4对应最大。
代码示例:
import pandas as pd from sklearn.cluster import KMeans # 假设你的数据存储在DataFrame df中,包含数值型日期X和每日标准差y-true # 提取聚类特征 cluster_features = df[['y-true']] # 初始化K-Means,设置4个簇,random_state保证结果可复现 kmeans_model = KMeans(n_clusters=4, random_state=42) # 生成初始聚类标签 df['temp_label'] = kmeans_model.fit_predict(cluster_features) # 修正标签顺序:让簇标签按中心值从小到大对应1-4 # 获取每个簇的中心值 cluster_centers = kmeans_model.cluster_centers_.flatten() # 把(原标签, 中心值)按中心值排序 sorted_clusters = sorted(enumerate(cluster_centers), key=lambda x: x[1]) # 创建原标签到新标签的映射(新标签从1开始) label_mapper = {old_label: new_label + 1 for new_label, (old_label, _) in enumerate(sorted_clusters)} # 更新为最终的分类标签 df['cart_target_label'] = df['temp_label'].map(label_mapper) # 可以删掉临时标签 df.drop('temp_label', axis=1, inplace=True)
3. 验证聚类结果
可以通过分组统计确认标签是否符合预期:
# 查看每个类别的标准差统计信息 print(df.groupby('cart_target_label')['y-true'].describe())
输出结果里,cart_target_label=1的mean应该是最小的,cart_target_label=4的mean是最大的,这样就符合你的需求了。
4. 用聚类标签训练CART模型
现在可以把cart_target_label作为分类目标,结合日期特征X训练CART分类器:
from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( df[['X']], df['cart_target_label'], test_size=0.2, random_state=42 ) # 初始化CART分类器 cart_classifier = DecisionTreeClassifier(random_state=42) # 训练模型 cart_classifier.fit(X_train, y_train) # 评估模型效果 y_pred = cart_classifier.predict(X_test) print(f"CART模型测试集准确率:{accuracy_score(y_test, y_pred):.2f}")
注意事项
- 如果你的
y-true存在负值(虽然标准差理论上不会,但如果是其他类似指标),记得把聚类特征改成abs(df['y-true']),确保是与0的距离。 random_state参数很重要,能让你的聚类和模型训练结果可复现,避免每次运行得到不同的结果。
内容的提问来源于stack exchange,提问作者Evan
相关产品推荐
相关产品推荐

