python训练营打卡第15天

复习日

仔细回顾一下之前14天的内容

尝试找到一个kaggle或者其他地方的结构化数据集,用之前的内容完成一个全新的项目,这样你也是独立完成了一个专属于自己的项目

要求:

1.有数据地址的提供数据地址,没有地址的上传网盘贴出地址即可。
2.尽可能与他人不同,优先选择本专业相关数据集
3.探索一下开源数据的网站有哪些?

数据地址:

中国空气污染 - Heywhale.comhttps://www.heywhale.com/mw/dataset/67f13657ae7aa2e45cd48197

数据说明:

此数据集包含来自中国五个主要城市(北京、上海、广州、成都和深圳)的合成但真实的空气污染数据。它从 2015 年到 2025 年,提供有关空气质量、气象条件和污染水平的宝贵信息。该数据集由 3000 行 24 列组成,涵盖了各种空气污染物、天气状况和地理细节。
该数据集专为数据分析、机器学习模型和空气质量预测应用程序而设计。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
from sklearn.model_selection import train_test_split
from imblearn.over_sampling import SMOTE
import xgboost as xgb
import lightgbm as lgb
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import classification_report, confusion_matrix
import shap

warnings.filterwarnings("ignore")

# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows 系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
# 设置图片清晰度
plt.rcParams['figure.dpi'] = 300

def evaluate_model(model, X_test, y_test):
    """
    评估模型的性能,打印分类报告、混淆矩阵和评估指标
    """
    pred = model.predict(X_test)
    print("\n分类报告:")
    print(classification_report(y_test, pred))
    print("混淆矩阵:")
    print(confusion_matrix(y_test, pred))

    accuracy = accuracy_score(y_test, pred)
    precision = precision_score(y_test, pred)
    recall = recall_score(y_test, pred)
    f1 = f1_score(y_test, pred)
    print("模型评估指标:")
    print(f"准确率: {accuracy:.4f}")
    print(f"精确率: {precision:.4f}")
    print(f"召回率: {recall:.4f}")
    print(f"F1 值: {f1:.4f}")

# 读取数据
data = pd.read_csv("E:\shucai\air_pollution_china.csv")

# 删除无关列(如时间戳,若不需要时间特征)
# 这里没有时间戳列,所以此步骤可略过

# 处理缺失值
data = data.dropna()

# 提取特征和目标变量
X = data.drop(columns=['AQI'])
y = data['AQI']

# 对非数值型特征进行编码
X = pd.get_dummies(X, columns=['Season', 'City', 'Day of Week', 'Weather Condition'])

# 查看y中各个类别的样本数量
class_counts = y.value_counts()

# 获取样本数量大于等于2的类别
valid_classes = class_counts[class_counts >= 2].index

# 保留有效类别的样本
valid_indices = y.isin(valid_classes)
X = X[valid_indices]
y = y[valid_indices]

# 计算连续特征的相关系数矩阵(包含所有数值特征)
continuous_cols = X.select_dtypes(include=np.number).columns.tolist()
correlation_matrix = X[continuous_cols].corr()

# 绘制热力图
plt.figure(figsize=(30, 20))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('连续特征相关性热力图')
plt.show()

# 划分训练集和测试集(20%作为测试集)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y  # 分层抽样保持类别平衡
)

# 打印数据集形状
print(f"训练集形状: {X_train.shape}, 测试集形状: {X_test.shape}")

# ------------------------- 随机森林模型 -------------------------
rf_model = RandomForestClassifier(random_state=42, n_estimators=100, n_jobs=-1)
rf_model.fit(X_train, y_train)
evaluate_model(rf_model, X_test, y_test)

# ------------------------- XGBoost 模型 -------------------------
xgb_model = xgb.XGBClassifier(random_state=42, n_estimators=100, learning_rate=0.1)
xgb_model.fit(X_train, y_train)
evaluate_model(xgb_model, X_test, y_test)

# ------------------------- LightGBM 模型 -------------------------
lgb_model = lgb.LGBMClassifier(random_state=42, n_estimators=100, n_jobs=-1)
lgb_model.fit(X_train, y_train)
evaluate_model(lgb_model, X_test, y_test)

# 检查每个类别的样本数量
class_counts = y_train.value_counts()
if (class_counts < 2).any():
    print("存在样本数量少于 2 的类别,跳过 SMOTE 过采样步骤。")
    X_train_smote, y_train_smote = X_train, y_train
else:
    # ------------------------- SMOTE 过采样处理 -------------------------
    smote = SMOTE(random_state=42)
    X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)
    print("\nSMOTE 过采样后训练集形状:", X_train_smote.shape, y_train_smote.shape)

# 训练过采样后的 XGBoost 模型
xgb_model_smote = xgb.XGBClassifier(random_state=42, n_estimators=100)
xgb_model_smote.fit(X_train_smote, y_train_smote)
evaluate_model(xgb_model_smote, X_test, y_test)

explainer = shap.TreeExplainer(xgb_model)
shap_values = explainer.shap_values(X_test)

# 检查 shap_values 的类型
if isinstance(shap_values, list):
    # 如果是列表,通常表示[负类 SHAP 值, 正类 SHAP 值]
    if len(shap_values) == 2:
        shap_values_positive = shap_values[1]  # 正类的 SHAP 值
    else:
        shap_values_positive = shap_values[0]  # 只有一个类别,直接使用
else:
    # 如果不是列表,直接使用
    shap_values_positive = shap_values

# 确保 shap_values 是二维数组
if len(shap_values_positive.shape) == 1:
    shap_values_positive = shap_values_positive.reshape(-1, 1)

# 条形图:特征重要性(基于 SHAP 值绝对值均值)
shap.summary_plot(
    shap_values_positive,
    X_test,
    feature_names=X_test.columns.tolist(),
    plot_type="bar",
    color=plt.get_cmap("viridis")(np.linspace(0, 1, len(X_test.columns))),
    title="特征重要性(SHAP 值)"
)
plt.show()

# 蜂群图:特征影响分布
shap.summary_plot(
    shap_values_positive,
    X_test,
    feature_names=X_test.columns.tolist(),
    title="特征对正类预测的影响分布",
    plot_size=(8, 6)
)
plt.show()

@浙大疏锦行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值