编辑代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

def generate_social_network_data(n_users=500, seed=42):
    """生成社交网络用户模拟数据"""
    np.random.seed(seed)
    
    data = {
        'user_id': np.arange(n_users),  # 用户ID
        'age': np.random.randint(18, 65, n_users),  # 年龄范围18-64
        'gender': np.random.choice(['M', 'F'], n_users),  # 性别
        'active_days': np.random.poisson(20, n_users),  # 每月活跃天数(泊松分布)
        'friend_count': np.random.randint(0, 1000, n_users),  # 好友数量
        'post_count': np.random.poisson(15, n_users),  # 发布内容数量
        'avg_time_spent': np.random.normal(60, 15, n_users)  # 平均每天花费时间(正态分布)
    }
    
    return pd.DataFrame(data)

def analyze_and_visualize_data(df):
    """分析和可视化社交网络用户数据"""
    print(f"成功生成{len(df)}条用户数据")
    
    # 数据概览
    print("\n数据基本统计信息:")
    print(df.describe())
    
    # 1. 年龄分布直方图
    plt.figure(figsize=(10, 6))
    sns.histplot(df['age'], bins=20, kde=True)
    plt.title('用户年龄分布')
    plt.xlabel('年龄')
    plt.ylabel('用户数量')
    plt.tight_layout()
    plt.savefig('age_distribution.png')
    plt.close()
    
    # 2. 性别分布饼图
    gender_counts = df['gender'].value_counts()
    plt.figure(figsize=(8, 8))
    plt.pie(gender_counts, labels=gender_counts.index, autopct='%1.1f%%', startangle=90)
    plt.title('用户性别分布')
    plt.tight_layout()
    plt.savefig('gender_distribution.png')
    plt.close()
    
    # 3. 活跃天数与好友数量关系散点图
    plt.figure(figsize=(10, 6))
    sns.scatterplot(x='active_days', y='friend_count', hue='gender', data=df, alpha=0.6)
    plt.title('活跃天数与好友数量关系')
    plt.xlabel('每月活跃天数')
    plt.ylabel('好友数量')
    plt.tight_layout()
    plt.savefig('active_friend_relationship.png')
    plt.close()
    
    # 4. 各特征相关性热图
    plt.figure(figsize=(12, 8))
    correlation = df.drop(['user_id'], axis=1).corr()
    sns.heatmap(correlation, annot=True, cmap='coolwarm', fmt='.2f')
    plt.title('特征相关性热图')
    plt.tight_layout()
    plt.savefig('feature_correlation.png')
    plt.close()
    
    # 5. 不同性别用户的平均使用时间对比
    plt.figure(figsize=(10, 6))
    sns.boxplot(x='gender', y='avg_time_spent', data=df)
    plt.title('不同性别用户的平均使用时间对比')
    plt.xlabel('性别')
    plt.ylabel('平均使用时间(分钟)')
    plt.tight_layout()
    plt.savefig('gender_time_comparison.png')
    plt.close()
    
    # 6. 发布内容数量分布(对数刻度)
    plt.figure(figsize=(10, 6))
    sns.histplot(df['post_count'], bins=30, log_scale=True)
    plt.title('发布内容数量分布(对数刻度)')
    plt.xlabel('发布内容数量')
    plt.ylabel('用户数量')
    plt.tight_layout()
    plt.savefig('post_count_distribution.png')
    plt.close()
    
    # 7. 年龄分组与活跃程度关系
    df['age_group'] = pd.cut(df['age'], bins=[18, 25, 35, 45, 55, 65], 
                             labels=['18-25', '26-35', '36-45', '46-55', '56+'])
    plt.figure(figsize=(12, 6))
    sns.barplot(x='age_group', y='active_days', data=df, estimator=np.mean)
    plt.title('不同年龄组的平均活跃天数')
    plt.xlabel('年龄组')
    plt.ylabel('平均活跃天数')
    plt.tight_layout()
    plt.savefig('age_active_relationship.png')
    plt.close()
    
    # 8. 好友数量与使用时间的回归分析
    plt.figure(figsize=(10, 6))
    sns.regplot(x='friend_count', y='avg_time_spent', data=df, scatter_kws={'alpha':0.3})
    plt.title('好友数量与使用时间的关系')
    plt.xlabel('好友数量')
    plt.ylabel('平均使用时间(分钟)')
    plt.tight_layout()
    plt.savefig('friend_time_regression.png')
    plt.close()
    
    # 9. 性别与年龄的交叉表
    gender_age = pd.crosstab(df['age_group'], df['gender'])
    print("\n性别与年龄组的交叉表:")
    print(gender_age)
    
    # 10. 不同活动水平的用户占比
    df['activity_level'] = pd.qcut(df['active_days'], q=3, labels=['低', '中', '高'])
    activity_counts = df['activity_level'].value_counts()
    print("\n不同活动水平的用户占比:")
    print(activity_counts / len(df) * 100)
    
    print("\n数据分析和可视化已完成,图表已保存到当前目录!")

if __name__ == "__main__":
    # 生成数据
    df = generate_social_network_data(n_users=500)
    
    # 分析和可视化数据
    analyze_and_visualize_data(df)