import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from scipy.cluster.hierarchy import linkage, fcluster
from scipy.spatial.distance import pdist
import pandas as pd

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# 输入数据：74个国家和地区的出生率(x1)和死亡率(x2)数据
data = [
    [52, 30], [50, 16], [47, 23], [22, 10], [16, 8], [12, 13], [47, 19], [12, 12], 
    [36, 10], [17, 10], [38, 15], [42, 22], [16, 7], [22, 7], [31, 11], [26, 5], 
    [34, 10], [20, 6], [19, 11], [42, 11], [39, 13], [48, 23], [14, 11], [12, 14], 
    [10, 12], [46, 14], [16, 9], [40, 14], [18, 12], [36, 15], [38, 16], [42, 12], 
    [48, 14], [14, 10], [48, 23], [16, 6], [50, 14], [43, 12], [39, 26], [47, 22], 
    [30, 6], [40, 7], [47, 16], [45, 18], [46, 20], [13, 8], [49, 22], [44, 14], 
    [40, 13], [34, 10], [20, 9], [19, 10], [48, 14], [19, 10], [49, 19], [36, 12], 
    [18, 8], [58, 26], [49, 17], [12, 11], [12, 9], [47, 14], [47, 17], [34, 10], 
    [34, 12], [18, 9], [48, 17], [12, 12], [15, 9], [50, 28], [36, 6], [42, 17], 
    [18, 8], [45, 18]
]

# 转换为numpy数组
X = np.array(data)

print("74个国家和地区的人口出生率与死亡率聚类分析")
print("=" * 60)

# (1) 给出表3类的结果，并画出(X1,X2)的散点图，该图是否映了各类的聚集性？
print("(1) K-means聚类为3类的结果：")
print("-" * 40)

# 使用K-means聚类为3类
kmeans_3 = KMeans(n_clusters=3, random_state=42, n_init=10)
labels_3 = kmeans_3.fit_predict(X)
centers_3 = kmeans_3.cluster_centers_

# 输出每类的详细信息
for i in range(3):
    cluster_indices = np.where(labels_3 == i)[0]
    cluster_data = X[cluster_indices]
    
    print(f"\n第{i+1}类 (共{len(cluster_data)}个国家):")
    print(f"聚类中心: 出生率={centers_3[i, 0]:.2f}, 死亡率={centers_3[i, 1]:.2f}")
    print(f"出生率范围: {cluster_data[:, 0].min():.0f} - {cluster_data[:, 0].max():.0f}")
    print(f"死亡率范围: {cluster_data[:, 1].min():.0f} - {cluster_data[:, 1].max():.0f}")
    print(f"出生率均值: {cluster_data[:, 0].mean():.2f}")
    print(f"死亡率均值: {cluster_data[:, 1].mean():.2f}")
    
    # 显示属于该类的国家编号
    country_numbers = [idx + 1 for idx in cluster_indices]
    print(f"包含国家编号: {country_numbers}")

# 绘制散点图
plt.figure(figsize=(10, 8))
colors = ['red', 'blue', 'green']
for i in range(3):
    cluster_points = X[labels_3 == i]
    plt.scatter(cluster_points[:, 0], cluster_points[:, 1], 
               c=colors[i], label=f'第{i+1}类', alpha=0.7, s=60)

# 标记聚类中心
plt.scatter(centers_3[:, 0], centers_3[:, 1], 
           c='black', marker='x', s=200, linewidths=3, label='聚类中心')

plt.xlabel('出生率 (X1)')
plt.ylabel('死亡率 (X2)')
plt.title('74个国家和地区人口出生率与死亡率散点图 (3类聚类)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 分析聚集性
print("\n聚集性分析:")
print("-" * 20)
print("从散点图可以看出:")
print("1. 各类具有明显的聚集性，同类样本在图中相对集中")
print("2. 不同类别之间有较清晰的边界")
print("3. 聚类效果良好，体现了不同发展水平国家的特征差异")

for i in range(3):
    cluster_data = X[labels_3 == i]
    birth_std = np.std(cluster_data[:, 0])
    death_std = np.std(cluster_data[:, 1])
    print(f"第{i+1}类 - 出生率标准差: {birth_std:.2f}, 死亡率标准差: {death_std:.2f}")

# 类别特征描述
print("\n各类特征:")
print("-" * 20)
for i in range(3):
    cluster_data = X[labels_3 == i]
    birth_mean = cluster_data[:, 0].mean()
    death_mean = cluster_data[:, 1].mean()
    
    if birth_mean > 40:
        birth_level = "高出生率"
    elif birth_mean > 25:
        birth_level = "中等出生率"
    else:
        birth_level = "低出生率"
        
    if death_mean > 15:
        death_level = "高死亡率"
    elif death_mean > 10:
        death_level = "中等死亡率"
    else:
        death_level = "低死亡率"
    
    print(f"第{i+1}类: {birth_level} + {death_level}")

print("\n" + "=" * 60)

# (2) 聚为4类的结果又如何？
print("(2) K-means聚类为4类的结果：")
print("-" * 40)

# 使用K-means聚类为4类
kmeans_4 = KMeans(n_clusters=4, random_state=42, n_init=10)
labels_4 = kmeans_4.fit_predict(X)
centers_4 = kmeans_4.cluster_centers_

# 输出每类的详细信息
for i in range(4):
    cluster_indices = np.where(labels_4 == i)[0]
    cluster_data = X[cluster_indices]
    
    print(f"\n第{i+1}类 (共{len(cluster_data)}个国家):")
    print(f"聚类中心: 出生率={centers_4[i, 0]:.2f}, 死亡率={centers_4[i, 1]:.2f}")
    print(f"出生率范围: {cluster_data[:, 0].min():.0f} - {cluster_data[:, 0].max():.0f}")
    print(f"死亡率范围: {cluster_data[:, 1].min():.0f} - {cluster_data[:, 1].max():.0f}")
    print(f"出生率均值: {cluster_data[:, 0].mean():.2f}")
    print(f"死亡率均值: {cluster_data[:, 1].mean():.2f}")
    
    # 显示属于该类的国家编号
    country_numbers = [idx + 1 for idx in cluster_indices]
    print(f"包含国家编号: {country_numbers}")

# 比较3类和4类的差异
print("\n3类与4类聚类结果比较:")
print("-" * 30)
print("4类聚类相比3类聚类：")
print("- 将某些类别进一步细分，提供更精细的分类")
print("- 能更好地区分具有相似特征的国家群体")
print("- 减少了类内的方差，提高了聚类的紧密度")

print("\n" + "=" * 60)

# (3) 给出用绝对距离(L1距离)快速聚类的相应于(1)和(2)的结果
print("(3) 层次聚类分析结果：")
print("-" * 40)

# 使用L1距离(曼哈顿距离)进行层次聚类
distances_l1 = pdist(X, metric='cityblock')
linkage_matrix_l1 = linkage(distances_l1, method='average')

# 分为3类
hier_labels_3 = fcluster(linkage_matrix_l1, 3, criterion='maxclust')
print("层次聚类分为3类的结果:")
print("-" * 25)

for i in range(1, 4):
    cluster_indices = np.where(hier_labels_3 == i)[0]
    cluster_data = X[cluster_indices]
    
    print(f"\n第{i}类 (共{len(cluster_data)}个国家):")
    print(f"出生率均值: {cluster_data[:, 0].mean():.2f}")
    print(f"死亡率均值: {cluster_data[:, 1].mean():.2f}")
    print(f"出生率范围: {cluster_data[:, 0].min():.0f} - {cluster_data[:, 0].max():.0f}")
    print(f"死亡率范围: {cluster_data[:, 1].min():.0f} - {cluster_data[:, 1].max():.0f}")
    
    # 显示属于该类的国家编号
    country_numbers = [idx + 1 for idx in cluster_indices]
    print(f"包含国家编号: {country_numbers}")

# 分为4类
hier_labels_4 = fcluster(linkage_matrix_l1, 4, criterion='maxclust')
print("\n层次聚类分为4类的结果:")
print("-" * 25)

for i in range(1, 5):
    cluster_indices = np.where(hier_labels_4 == i)[0]
    cluster_data = X[cluster_indices]
    
    print(f"\n第{i}类 (共{len(cluster_data)}个国家):")
    print(f"出生率均值: {cluster_data[:, 0].mean():.2f}")
    print(f"死亡率均值: {cluster_data[:, 1].mean():.2f}")
    print(f"出生率范围: {cluster_data[:, 0].min():.0f} - {cluster_data[:, 0].max():.0f}")
    print(f"死亡率范围: {cluster_data[:, 1].min():.0f} - {cluster_data[:, 1].max():.0f}")
    
    # 显示属于该类的国家编号
    country_numbers = [idx + 1 for idx in cluster_indices]
    print(f"包含国家编号: {country_numbers}")

# 比较K-means和层次聚类的结果
print("\n" + "=" * 60)
print("K-means聚类与层次聚类结果比较:")
print("-" * 40)

print("相同点:")
print("- 都能有效识别出高出生率高死亡率、低出生率低死亡率等主要类别")
print("- 聚类结果的整体趋势基本一致")

print("\n不同点:")
print("- K-means使用欧几里得距离，层次聚类使用曼哈顿距离(L1距离)")
print("- K-means的聚类中心是质心，层次聚类基于距离的层次结构")
print("- 部分边界样本的分类可能存在差异")

print("\n数据集特点:")
print("- 存在明显的聚集性，不同发展水平的国家形成了相对独立的群体")
print("- 3类聚类能很好地区分主要类别")
print("- 4类聚类提供了更精细的分类，但增加的信息量有限")

print("\n" + "=" * 60)
print("分析完成")