
"""
练习题1:基础绘制(6个样本)
题目要求
给定以下二分类模型的预测结果,手动绘制ROC曲线并计算AUC值:
y_true = [0, 1, 0, 1, 0, 1] # 真实标签(0=负类,1=正类)
y_score = [0.2, 0.7, 0.3, 0.6, 0.1, 0.8] # 模型预测得分
"""
from matplotlib import pyplot as plt
from sklearn.metrics import roc_curve, auc
y_true = [0, 1, 0, 1, 0, 1] # 真实标签(0=负类,1=正类)
y_score = [0.2, 0.7, 0.3, 0.6, 0.1, 0.8] # 模型预测得分
fpr,tpr,_ = roc_curve(y_true,y_score)
plt.figure(figsize=(10,5))
plt.plot(fpr,tpr,color='red',label="ROC")
plt.plot([0,1],[0,1],color='blue',linestyle='--',label="Guess")
plt.title("ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR")
plt.show()
roc_auc = auc(fpr, tpr)
print("AUC值:", roc_auc)

"""
练习题2:含重复得分(8个样本)
题目要求
处理有相同预测得分的情况:
y_true = [1, 0, 0, 1, 1, 0, 1, 0]
y_score = [0.8, 0.5, 0.5, 0.7, 0.6, 0.5, 0.9, 0.3]
"""
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
y_true = [1, 0, 0, 1, 0, 0, 1, 0]
y_score = [0.8, 0.5, 0.5, 0.7, 0.6, 0.5, 0.9, 0.3]
# 计算FPR、TPR和阈值
fpr, tpr, thresholds = roc_curve(y_true, y_score)
roc_auc = auc(fpr, tpr)
# 绘制ROC曲线
plt.figure(figsize=(10, 5))
plt.plot(fpr, tpr, color='red', lw=2, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='blue', linestyle='--', label='Random Guess')
plt.xlabel('False Positive Rate (FPR)')
plt.ylabel('True Positive Rate (TPR)')
plt.title('ROC Curve with Duplicate Scores')
plt.legend(loc='lower right')
plt.show()
print("AUC值:", roc_auc)

"""
练习题3:类别不平衡场景(10个样本)
题目背景
在信用卡欺诈检测中,正常交易(负类)远多于欺诈交易(正类)。给定以下模拟数据:
y_true = [0, 0, 0, 0, 0, 0, 1, 0, 1, 0] # 2个欺诈(正类),8个正常(负类)
y_score = [0.1, 0.2, 0.15, 0.05, 0.3, 0.25, 0.9, 0.4, 0.6, 0.1] # 模型输出的欺诈概率
题目要求
1.手动计算所有(FPR, TPR)点
2.绘制ROC曲线
3.观察类别不平衡对曲线形状的影响
"""
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
y_true = [0, 0, 0, 0, 0, 0, 1, 0, 1, 0] # 2个欺诈(正类),8个正常(负类)
y_score = [0.1, 0.2, 0.15, 0.05, 0.3, 0.25, 0.9, 0.4, 0.6, 0.1] # 模型输出的欺诈概率
fpr,tpr,thresholds = roc_curve(y_true, y_score)
print(fpr,tpr,thresholds)
plt.figure(figsize=(10,5))
plt.plot(fpr,tpr,color='red',label="ROC")
plt.plot([0,1],[0,1],color='blue',linestyle='--',label="Guess")
plt.title("ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR")
plt.legend()
plt.show()

"""
练习场景描述:
你是一家医疗机构的数据分析师,你的任务是分析Pima Indians Diabetes Database数据集,以预测患者是否患有糖尿病。数据集包含了一系列与患者健康相关的指标,如怀孕次数、葡萄糖浓度、血压等。你需要使用逻辑回归模型来训练一个分类器,以根据这些指标预测患者是否患有糖尿病。
具体步骤:
1.使用pandas库加载数据集,并进行初步的数据探索,了解数据集的字段和分布情况。
2.对数据进行预处理,包括处理缺失值、标准化或归一化特征值等。
3.使用numpy库进行特征选择或特征工程,以提高模型的性能。
4.划分训练集和测试集,使用训练集训练逻辑回归模型,并使用测试集评估模型的性能。
5.使用matplotlib库绘制ROC曲线或混淆矩阵,以直观展示模型的分类效果。
6.根据评估结果调整模型的参数,以提高模型的性能。
题目:
基于上述练习场景,请完成以下任务:
1.加载Pima Indians Diabetes Database数据集,并进行初步的数据探索。
2.对数据进行预处理,包括处理缺失值和标准化特征值。
3.使用逻辑回归模型进行训练,并评估模型的性能。
4.绘制ROC曲线,展示模型的分类效果。
5.根据你的理解,提出至少一个改进模型性能的方法,并尝试实现。
"""
# 导入必要的库和模块
import pandas as pd # 用于数据操作和分析
import numpy as np # 用于数值计算
from sklearn.model_selection import train_test_split # 用于划分训练集和测试集
from sklearn.preprocessing import StandardScaler # 用于标准化数据
from sklearn.linear_model import LogisticRegression # 用于逻辑回归模型
from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, auc # 用于模型评估
import matplotlib.pyplot as plt # 用于绘制图形
# 设置中文字体,确保中文标签不会乱码
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体为SimHei
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 1. 加载数据集
columns = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin',
'BMI', 'DiabetesPedigreeFunction', 'Age', 'Outcome'] # 定义数据列名
data = pd.read_csv("./diabetes.csv", header=None, names=columns) # 读取数据文件并指定列名
# 2. 数据探索
print("数据集的前几行:")
print(data.head()) # 打印数据集的前5行数据
print("\n数据集的信息:")
print(data.info()) # 打印数据集的信息,包括数据类型和缺失值
print("\n数据集的描述性统计:")
print(data.describe()) # 打印数据的描述性统计,查看均值、标准差等
# 3. 数据预处理
# 3.1 处理缺失值,将所有0替换为NaN
data.replace(0, pd.NA, inplace=True) # 替换0为NaN,0可能是缺失值的标志
# 3.2 将所有列转换为数值类型
data = data.apply(pd.to_numeric, errors='coerce') # 将数据转换为数值类型,错误值设为NaN
# 3.3 使用中位数填充缺失值
data.fillna(data.median(), inplace=True) # 用每一列的中位数填充缺失值
# 查看是否仍有缺失值
print("\n缺失值处理后:")
print(data.isnull().sum()) # 查看每列是否仍然有缺失值
# 3.4 特征标准化
X = data.drop(columns='Outcome') # 特征变量(去除结果列'Outcome')
y = data['Outcome'] # 标签(结果列)
scaler = StandardScaler() # 初始化标准化器
X_scaled = scaler.fit_transform(X) # 对特征数据进行标准化,零均值,单位方差
# 4. 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 将数据集划分为训练集(80%)和测试集(20%),random_state确保可复现
print(f"\n训练集大小: {X_train.shape}") # 打印训练集的大小
print(f"测试集大小: {X_test.shape}") # 打印测试集的大小
# 5. 训练逻辑回归模型
model = LogisticRegression(max_iter=200) # 初始化逻辑回归模型,max_iter设置最大迭代次数为200
model.fit(X_train, y_train) # 在训练集上训练模型
# 6. 评估模型性能
y_pred = model.predict(X_test) # 在测试集上进行预测
accuracy = accuracy_score(y_test, y_pred) # 计算准确率
print(f"\n模型准确率: {accuracy * 100:.2f}%") # 打印准确率(百分比)
# 7. 绘制ROC曲线
fpr, tpr, thresholds = roc_curve(y_test, model.predict_proba(X_test)[:, 1])
# 计算假阳性率(fpr)、真阳性率(tpr)和阈值(thresholds),用于绘制ROC曲线
roc_auc = auc(fpr, tpr) # 计算AUC值(曲线下面积)
plt.figure(figsize=(8, 6)) # 设置图形大小
plt.plot(fpr, tpr, color='blue', label=f'ROC曲线 (AUC = {roc_auc:.2f})') # 绘制ROC曲线,并显示AUC值
plt.plot([0, 1], [0, 1], color='red', linestyle='--') # 绘制参考线(对角线)
plt.xlim([0.0, 1.0]) # 设置x轴范围
plt.ylim([0.0, 1.05]) # 设置y轴范围
plt.xlabel('假阳性率 (False Positive Rate)') # x轴标签
plt.ylabel('真阳性率 (True Positive Rate)') # y轴标签
plt.title('接收者操作特征曲线 (ROC)') # 图形标题
plt.legend(loc='lower right') # 显示图例
plt.show() # 显示图形
# 8. 调整模型超参数并重新评估
# 调整逻辑回归模型的正则化参数C
# 使用网格搜索调整参数
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {
'C': [0.01, 0.1, 1, 10, 100],
'solver': ['liblinear', 'lbfgs']
}
# 初始化逻辑回归模型
log_reg = LogisticRegression(max_iter=200)
# 使用网格搜索进行超参数调整
grid_search = GridSearchCV(log_reg, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
# 输出最佳参数
print(f"最佳参数: {grid_search.best_params_}")
# 使用最佳参数训练模型
best_model = grid_search.best_estimator_
best_model.fit(X_train, y_train)
# 在测试集上评估模型
y_pred_best = best_model.predict(X_test)
best_accuracy = accuracy_score(y_test, y_pred_best)
print(f"\n最佳模型准确率: {best_accuracy * 100:.2f}%")
# 绘制最佳模型的ROC曲线
fpr_best, tpr_best, thresholds_best = roc_curve(y_test, best_model.predict_proba(X_test)[:, 1])
roc_auc_best = auc(fpr_best, tpr_best)
plt.figure(figsize=(8, 6))
plt.plot(fpr_best, tpr_best, color='green', label=f'最佳ROC曲线 (AUC = {roc_auc_best:.2f})')
plt.plot([0, 1], [0, 1], color='red', linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假阳性率 (False Positive Rate)')
plt.ylabel('真阳性率 (True Positive Rate)')
plt.title('最佳接收者操作特征曲线 (ROC)')
plt.legend(loc='lower right')
plt.show()
