康心伴Logo
康心伴WellAlly
Health

Python时型聚类分析教程:识别用户的昼夜节律类型 | WellAlly康心伴

5 分钟阅读

Python时型聚类分析教程:识别用户的昼夜节律类型

概述

时型(Chronotype)是指个体昼夜节律的偏好类型,主要分为:

  • 早起型(百灵鸟型):早睡早起
  • 夜猫子型:晚睡晚起
  • 中间型:介于两者之间

通过分析用户的睡眠数据、活动数据和其他时间序列数据,我们可以识别其时型,并提供个性化的健康建议。


数据准备

示例数据结构

code
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 模拟用户活动数据
def generate_user_activity_data(num_days=30):
    """生成模拟的活动数据"""
    dates = pd.date_range(start='2026-01-01', periods=num_days)

    data = []
    for date in dates:
        for hour in range(24):
            # 模拟活动水平(0-100)
            activity = np.random.normal(loc=50, scale=20)
            activity = np.clip(activity, 0, 100)

            data.append({
                'date': date,
                'hour': hour,
                'activity': activity,
                'timestamp': datetime.combine(date, datetime.min.time()) + timedelta(hours=hour)
            })

    return pd.DataFrame(data)

# 生成数据
activity_data = generate_user_activity_data(30)
print(activity_data.head())
Code collapsed

特征工程

1. 计算时型特征

code
def calculate_chronotype_features(df):
    """计算时型相关特征"""
    features = {}

    # 1. 中点时间(活动峰值的中间点)
    hourly_activity = df.groupby('hour')['activity'].mean()
    peak_hour = hourly_activity.idxmax()
    features['midpoint'] = peak_hour

    # 2. 活动开始时间(活动>阈值的最早时间)
    threshold = 50
    active_hours = hourly_activity[hourly_activity > threshold].index
    features['activity_start'] = active_hours.min() if len(active_hours) > 0 else 7

    # 3. 活动结束时间
    features['activity_end'] = active_hours.max() if len(active_hours) > 0 else 22

    # 4. 活动持续时间
    features['active_duration'] = features['activity_end'] - features['activity_start']

    # 5. 上午活动比例 (6-12点)
    morning_activity = hourly_activity[6:13].sum()
    total_activity = hourly_activity.sum()
    features['morning_ratio'] = morning_activity / total_activity

    # 6. 下午活动比例 (12-18点)
    afternoon_activity = hourly_activity[12:19].sum()
    features['afternoon_ratio'] = afternoon_activity / total_activity

    # 7. 晚间活动比例 (18-24点)
    evening_activity = hourly_activity[18:25].sum()
    features['evening_ratio'] = evening_activity / total_activity

    # 8. 活动规律性(标准差)
    features['activity_regularity'] = hourly_activity.std()

    return features

# 计算特征
chronotype_features = calculate_chronotype_features(activity_data)
print(chronotype_features)
Code collapsed

聚类分析

K-means聚类

code
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

def cluster_users(user_data_dict):
    """对多个用户进行聚类分析"""
    # 提取特征矩阵
    features_list = []
    user_ids = []

    for user_id, user_data in user_data_dict.items():
        features = calculate_chronotype_features(user_data)
        features_list.append(list(features.values()))
        user_ids.append(user_id)

    feature_matrix = np.array(features_list)

    # 标准化
    scaler = StandardScaler()
    features_scaled = scaler.fit_transform(feature_matrix)

    # K-means聚类
    kmeans = KMeans(n_clusters=3, random_state=42)
    clusters = kmeans.fit_predict(features_scaled)

    # 分类结果
    cluster_mapping = {
        0: '早起型',
        1: '中间型',
        2: '夜猫子型'
    }

    results = pd.DataFrame({
        'user_id': user_ids,
        'cluster': clusters,
        'chronotype': [cluster_mapping[c] for c in clusters]
    })

    return results, kmeans, scaler

# 模拟多个用户数据
user_data_dict = {
    f'user_{i}': generate_user_activity_data(30)
    for i in range(100)
}

# 执行聚类
results, kmeans_model, scaler = cluster_users(user_data_dict)
print(results.head())
Code collapsed

可视化分析

时型分布可视化

code
import matplotlib.pyplot as plt
import seaborn as sns

def visualize_chronotype_distribution(results):
    """可视化时型分布"""
    plt.figure(figsize=(12, 5))

    # 子图1:时型分布饼图
    plt.subplot(1, 2, 1)
    chronotype_counts = results['chronotype'].value_counts()
    colors = ['#FFD700', '#87CEEB', '#9370DB']
    plt.pie(chronotype_counts.values,
            labels=chronotype_counts.index,
            autopct='%1.1f%%',
            colors=colors)
    plt.title('用户时型分布')

    # 子图2:各时型的活动曲线
    plt.subplot(1, 2, 2)

    for cluster in results['cluster'].unique():
        cluster_users = results[results['cluster'] == cluster]['user_id'].values
        # 计算该类别的平均活动曲线
        cluster_activity = []
        for user_id in cluster_users[:5]:  # 采样
            user_data = user_data_dict[user_id]
            hourly_avg = user_data.groupby('hour')['activity'].mean()
            cluster_activity.append(hourly_avg)

        avg_activity = pd.concat(cluster_activity, axis=1).mean(axis=0)
        plt.plot(avg_activity.index, avg_activity.values,
                label=f'类别{cluster}', linewidth=2)

    plt.xlabel('小时')
    plt.ylabel('活动水平')
    plt.title('不同时型的活动曲线')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

visualize_chronotype_distribution(results)
Code collapsed

时型评估问卷

MCTQ问卷数据分析

code
def analyze_mctq_questionnaire(responses):
    """
    分析Munich Chronotype Questionnaire (MCTQ)问卷数据

    参数:
    responses: DataFrame, 包含MCTQ问卷答案
    """
    # MCTQ主要问题
    mctq_questions = {
        'sleep_duration': '平均睡眠时长',
        'mid_sleep': '睡眠中点时间',
        'activity_peak': '活动峰值时间',
        'morningness': '早晨清醒度'
    }

    # 计算时型分数
    # 早晨清醒度分数越高 = 早起型
    morningness_score = responses['morningness'].mean()

    # 分类标准
    if morningness_score >= 4:
        chronotype = '早起型'
    elif morningness_score <= 2:
        chronotype = '夜猫子型'
    else:
        chronotype = '中间型'

    return {
        'chronotype': chronotype,
        'morningness_score': morningness_score,
        'sleep_duration': responses['sleep_duration'].mean()
    }
Code collapsed

关键要点

  1. 时型识别基于多种特征:活动模式、睡眠时间、问卷数据
  2. K-means聚类是常用方法:可无监督学习用户时型
  3. 特征工程很重要:需要设计有区分度的时型特征
  4. 考虑季节性和日常变化:工作日和周末可能不同
  5. 时型与健康相关:时型错位可能影响睡眠质量和代谢健康

常见问题

如何处理不规律的作息?

使用活动传感器的连续监测数据,而非单日数据。计算7-14天的平均模式。

时型会改变吗?

是的,时型可能随年龄、工作性质、季节而变化。建议定期重新评估。

聚类数量如何确定?

使用肘部法则(Elbow Method)或轮廓系数(Silhouette Score)确定最佳聚类数。


参考资料


发布日期:2026年3月8日 最后更新:2026年3月8日

免责声明: 本内容仅供教育参考,不能替代专业医疗建议。请咨询医生获取个性化诊断和治疗方案。

#

文章标签

健康数据分析
Python
聚类算法
时型分类
睡眠模式

觉得这篇文章有帮助?

立即体验康心伴,开始您的健康管理之旅