Python打卡 DAY 18

聚类后的分析:推断簇的类型

知识点回顾:

1.  推断簇含义的2个思路:先选特征和后选特征

2.  通过可视化图形借助ai定义簇的含义

3.  科研逻辑闭环:通过精度判断特征工程价值

作业:参考示例代码对心脏病数据集采取类似操作,并且评估特征工程后模型效果有无提升。

 

# 先运行之前预处理好的代码
import pandas as pd
import pandas as pd    #用于数据处理和分析,可处理表格数据。
import numpy as np     #用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt    #用于绘制各种类型的图表
import seaborn as sns   #基于matplotlib的高级绘图库,能绘制更美观的统计图形。
import warnings
warnings.filterwarnings("ignore")
 
 # 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
data = pd.read_csv('D:\python学习\学习资源(代码)\python60-days-challenge-master\python60-days-challenge-master\heart.csv')    #读取数据

from sklearn.model_selection import train_test_split
X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target'] # 标签
# # 按照8:2划分训练集和测试集
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns

# 标准化数据(聚类前通常需要标准化)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# X_scaled

import numpy as np
import pandas as pd
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score
import matplotlib.pyplot as plt
import seaborn as sns

# 评估不同 k 下的指标
k_range = range(2, 11)  # 测试k从 2 到 10
inertia_values = []
silhouette_scores = []
ch_scores = []
db_scores = []

for k in k_range:
    kmeans = KMeans(n_clusters=k, random_state=42)  
    kmeans_labels = kmeans.fit_predict(X_scaled)
    inertia_values.append(kmeans.inertia_) # 惯性(肘部法则)
    silhouette = silhouette_score(X_scaled, kmeans_labels) # 轮廓系数
    silhouette_scores.append(silhouette)
    ch = calinski_harabasz_score(X_scaled, kmeans_labels) # CH 指数
    ch_scores.append(ch)
    db = davies_bouldin_score(X_scaled, kmeans_labels) # DB 指数
    db_scores.append(db)
    
    print(f"k={k}, 轮廓系数: {silhouette:.3f}, 惯性: {kmeans.inertia_:.2f}, CH 指数: {ch:.2f}, DB 指数: {db:.3f}")


selected_k = 3  # 示例值,根据图表调整

# 使用选择的k进行kmeans聚类
kmeans = KMeans(n_clusters=selected_k, random_state=42)
kmeans_labels = kmeans.fit_predict(X_scaled)
X['KMeans_Cluster'] = kmeans_labels

# 使用 PCA 降维到 2D 进行可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# KMeans聚类结果可视化
plt.figure(figsize=(6, 5))
sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=kmeans_labels, palette='viridis')
plt.title(f'KMeans Clustering with k={selected_k} (PCA Visualization)')
plt.xlabel('PCA Component 1')
plt.ylabel('PCA Component 2')
plt.show()

# 打印 KMeans聚类标签的前几行
print(f"KMeans Cluster labels (k={selected_k}) added to X:")
print(X[['KMeans_Cluster']].value_counts())

print(X.columns)

x1= X.drop('KMeans_Cluster',axis=1) # 删除聚类标签列
y1 = X['KMeans_Cluster']
# 构建随机森林,用shap重要性来筛选重要性
import shap
import numpy as np
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)  # 随机森林模型
model.fit(x1, y1)  # 训练模型,此时无需在意准确率 直接全部数据用来训练了

shap.initjs() # 初始化JavaScript环境,用于SHAP值的可视化
explainer = shap.TreeExplainer(model) # 创建一个TreeExplainer对象,用于解释模型的输出
shap_values = explainer.shap_values(x1) # 计算SHAP值,用于解释模型的预测结果
shap_values.shape # 第一维是样本数,第二维是特征数,第三维是类别数

print("--- 1. SHAP 特征重要性条形图 ---")
shap.summary_plot(shap_values[:,:,0],x1,plot_type="bar",show=False) #  这里的show=False表示不直接显示图形,这样可以继续用plt来修改元素,不然就直接输出了
plt.title("SHAP Feature Importance Bar Plot") 
print(plt.show())

# 此时判断一下这几个特征是离散型还是连续型
import pandas as pd
selected_features = ['thalach', 'fbs',
                     'exang', 'slope','oldpeak']

for feature in selected_features:
    unique_count = X[feature].nunique() # 唯一值指的是在某一列或某个特征中,不重复出现的值
    # 连续型变量通常有很多唯一值,而离散型变量的唯一值较少
    print(f'{feature} 的唯一值数量: {unique_count}')
    if unique_count < 10:  # 这里 10 是一个经验阈值,可以根据实际情况调整
        print(f'{feature} 可能是离散型变量')
    else:
        print(f'{feature} 可能是连续型变量')

 

# X["Purpose_debt consolidation"].value_counts() # 统计每个唯一值的出现次数
import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
print(plt.show())

# 绘制出每个簇对应的这四个特征的分布图
X[['KMeans_Cluster']].value_counts()


# 分别筛选出每个簇的数据
X_cluster0 = X[X['KMeans_Cluster'] == 0]
X_cluster1 = X[X['KMeans_Cluster'] == 1]
X_cluster2 = X[X['KMeans_Cluster'] == 2]

# 先绘制簇0的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster0[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
print(plt.show())

# 先绘制簇1的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster1[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
print(plt.show())

# 先绘制簇2的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster2[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
print(plt.show())

 三个簇的总结与定义

簇0

  • Thalach(最大心率):集中在140-170,偏高,说明具有较强的运动耐力和心脏功能。
  • Fbs(空腹血糖):绝大多数为0,血糖水平正常或偏低。
  • Exang(运动后胸痛):多为0(无胸痛),心血管风险较低。
  • Slope(心电图坡度):多为1和2,表示不同心电活动状态。
  • Oldpeak(旧峰值):大都在0.5以下,说明心肌缺血低,心脏健康状态较好。

总结与定义:
健康状态较佳的群体,心脏功能良好,血糖正常,无运动诱发胸痛,心肌缺血风险较低。


簇1

  • Thalach(最大心率):主要在120-150,偏中等偏低。
  • Fbs(空腹血糖):大部分偏高(非0),提示血糖略高或可能有糖尿病前期。
  • Exang(运动后胸痛):主要为1,表示存在运动诱发的胸痛,心血管风险增加。
  • Slope(心电图坡度):多为1,反映心电活动状态。
  • Oldpeak(旧峰值):多在1.0-2.0,说明存在一定的心肌缺血。

总结与定义:
潜在风险群体,心脏负荷较大,血糖偏高,有运动诱发胸痛,存在心肌缺血风险。


簇2

  • Thalach(最大心率):偏高,集中在140-160。
  • Fbs(空腹血糖):为1,提示血糖略高或可能有糖尿病前期。
  • Exang(运动后胸痛):多为0,少为1,存在运动诱发胸痛。
  • Slope(心电图坡度):多为2,显示心电变化较为显著。
  • Oldpeak(旧峰值):多在1及以下,心肌缺血不太严重。

总结与定义:
高风险群体,心电变化明显,心肌缺血不太严重,血糖可能偏高,需密切监控和干预。


总体概述:

  • 簇0:健康、心脏功能良好、血糖正常、无显著心肌缺血。
  • 簇1:存在潜在心血管风险,血糖偏高,运动引发胸痛,心肌缺血迹象明显。
  • 簇2:高风险群体,心电变化明显,血糖可能偏高,需重点关注。

@浙大疏锦行

 

Python中实现打卡兑换礼物的功能,通常会涉及到以下几个步骤: 1. **数据结构设计**:创建一个数据库或数据结构来存储用户的打卡记录,比如字典或列表,其中每个元素包含用户ID、日期等信息。 ```python users_gifts = {} # 使用字典,key为用户ID,value为打卡记录 ``` 2. **添加打卡功能**:编写函数,当用户调用时,检查用户是否存在并更新打卡次数。例如,可以使用`datetime`库来记录每日打卡时间。 ```python import datetime def check_in(user_id): today = datetime.datetime.now().strftime("%Y-%m-%d") if user_id not in users_gifts: users_gifts[user_id] = {today: 1} else: if today not in users_gifts[user_id]: users_gifts[user_id][today] = 1 else: users_gifts[user_id][today] += 1 ``` 3. **条件判断与兑换规则**:设定一个规则,如连续7天打卡即可兑换一份礼物。可以遍历用户的打卡记录,检查是否符合条件。 ```python def can_exchange(user_id): user_history = users_gifts.get(user_id, {}) consecutive_days = {} for date, count in user_history.items(): if date - consecutive_days.get(date, '') <= datetime.timedelta(days=6): # 连续6天 consecutive_days[date] = count if len(consecutive_days) == 7: # 找到7连日 return True return False ``` 4. **兑换操作**:如果满足兑换条件,可以删除已达到兑换的打卡记录,并通知用户兑换成功。 ```python def redeem_gift(user_id): if can_exchange(user_id): for day, _ in list(users_gifts[user_id].items())[:7]: # 删除前7天的打卡记录 del users_gifts[user_id][day] print(f"恭喜用户{user_id},您的7天连续打卡已成功兑换礼物!") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值