当前位置:   article > 正文

机器学习大作业_机器学习 大作业

机器学习 大作业

文章目录


这是机器学习的一个大作业,主要用到了逻辑斯蒂算法、KNN算法、随机森林算法。
数据集是糖尿病的数据集。

import pandas as pd
import numpy as np
import warnings
import math
import lightgbm as lgb
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV,cross_val_score
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from sklearn.decomposition import PCA
from sklearn.metrics import roc_curve


from matplotlib import rcParams
warnings.filterwarnings('ignore')
#步骤1 todo:读取数据
df = pd.read_csv('diabetes_data_upload.csv', delimiter=',')
df.columns = ['Age', 'Gender', 'Polyuria', 'Polydipsia', 'sudden weight loss', 'weakness', 'Polyphagia', 'Genital thrush', 'visual blurring', 'Itching', 'Irritability', 'delayed healing', 'partial paresis', 'muscle stiffness', 'Alopecia', 'Obesity', 'class']
#步骤1.1 了解数据基本信息
print(df.head())
print(df.describe())
#步骤1.2 查看数据是否有缺失值情况
print('数据缺失值情况:\n', df.isna().sum())
# 数据清洗,去掉weakness
# data.drop(columns=['weakness'],axis=1,inplace=True)
#步骤1.3 对数据进行处理
df['Gender'] = df['Gender'].map({'Male': 1, 'Female': 0})
# 步骤1.4 目标变量中为字符串型数据,使用labelEncoder处理编码(spam-1,ham-0)
le = LabelEncoder()#转换成数值数据,对定型特征多值化
for col in df.columns:
    if df[col].dtype == 'object':
        df[col] = le.fit_transform(df[col])
# 步骤1.5 标准化处理,使用StandardScaler
#对 DataFrame 中的除最后一列外的所有数值类型的特征进行标准化处理,即将每个特征减去其均值后再除以标准差。
scaler = StandardScaler()
df[df.columns[:-1]] = scaler.fit_transform(df[df.columns[:-1]])
# 步骤1.6 特征工程
X = df[df.columns[:-1]]
y = df['class']
#步骤1.7 todo:对整体数据按照train_size进行划分,得到训练集和测试集, random_state确保结果的一致性
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.66)


# 步骤2 todo:可视化分析
# 统计年龄变量的分布情况
plt.figure(figsize=(8, 5))
# 将年龄划分为10个区间
age_bins = pd.cut(df['Age'], bins=10,labels=['{}-{}'.format(i*6+30, i*6+35) for i in range(10)])
# 统计每个区间的样本数量
age_counts = age_bins.value_counts().sort_index()
plt.bar(x=age_counts.index.astype(str), height=age_counts.values)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('年龄特征分布与异常值', fontsize=15)
plt.xlabel('年龄')
plt.ylabel('Count')
plt.savefig('./results/Age characteristic_distribution_and_outliers.png')
plt.show()
#统计不同性别糖尿病的情况
#将数据集 df 中的所有样本根据 'Gender' 列的取值进行分类,
# 并计算每个分类中 'class' 列的计数,最后将不同分类的计数以柱状图的形式绘制出来
plt.figure(figsize=(8, 5))
sns.countplot(x='Gender', data=df, hue='class')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('不同性别糖尿病的情况', fontsize=15)
plt.xticks(ticks=[0, 1], labels=['Female', 'Male'])
plt.savefig('./results/Diabetes_mellitus_of_different_genders.png')
plt.show()
#统计Polydipsia(过度口渴)对糖尿病的情况
plt.figure(figsize=(8, 5))
sns.countplot(x='Polydipsia', data=df, hue='class')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('过度口渴对糖尿病的情况', fontsize=15)
plt.xticks(ticks=[0, 1], labels=['Female', 'Male'])
plt.savefig('./results/Excessive_thirst_in_the_case_of_diabetes.png')
plt.show()
#统计Polyuria(多尿症)对糖尿病的情况
plt.figure(figsize=(8, 5))
sns.countplot(x='Polyuria', data=df, hue='class')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('多尿症对糖尿病的情况', fontsize=15)
plt.xticks(ticks=[0, 1], labels=['Female', 'Male'])
plt.savefig('./results/Polyuria_is_a_case_of_diabetes.png')
plt.show()

# PCA 降维可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
df_pca = pd.DataFrame(X_pca, columns=['PC1', 'PC2'])
df_pca['class'] = y
sns.set(font_scale=1.2)
sns.scatterplot(x='PC1', y='PC2', hue='class', data=df_pca)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('主成分可视化', fontsize=10)
plt.savefig('./results/PCA_Visualization.png')
plt.show()
# 相关性分析
corr = df.corr()#计算相关性矩阵
#创建矩阵掩码以隐藏重复值
mask = np.triu(np.ones_like(corr, dtype=bool))
# 设置全局图形风格
plt.figure(figsize=(9, 6))
# 绘制相关性热图
sns.heatmap(corr, mask=mask, cmap='coolwarm', annot=True, fmt='.2f', annot_kws={'size': 5})
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
plt.title('相关性热图', fontsize=15)
plt.savefig('./results/Correlation_Matrix.png')
plt.show()

# 步骤3 todo:模型训练、测试、评估
# 步骤3.1 todo:模型训练和评估
#定义基分类器
lr = LogisticRegression()
knn = KNeighborsClassifier()
rf = RandomForestClassifier()
# 建立五种模型并交叉验证,使用sklearn中的不同分类器,LogisticRegression, KNeighborsClassifier, RandomForestClassifier,
models = [lr, knn, rf]
names = ['Logistic Regression', 'KNN', 'Random Forest']
scores = []
for model in models:
    score = cross_val_score(model, X, y, cv=5, scoring='accuracy').mean()
    scores.append(score)
cv_test=score
# 输出各模型预测平均得分
results = pd.DataFrame({'Model': names, 'Score': scores})
print(results)
# 使用Stacking集成学习(LR),定义元分类器
stack = StackingClassifier(estimators=[('lr', lr), ('knn', knn), ('rf', rf)],
                           final_estimator=LogisticRegression())
params = {
    'lr__C': [0.1,0.5],
    'knn__n_neighbors': [3,5],
    'rf__n_estimators': [50,100],
    'rf__max_depth': [5,7],
    'final_estimator__C': [1.0,10]
}
grid = GridSearchCV(stack, params, cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X, y)
# 打印出最佳的模型参数
print(grid.best_params_)
## 最佳模型已经通过网格搜索得到了,不需要再次拟合,直接使用即可
best_model = grid.best_estimator_
best_model.fit(X_train, y_train)

# 步骤3.2 todo: 计算分类评价指标:测试集的准确率accuracy、精确率precision、召回率recall和综合评价指标 F1 值
y_pred = grid.predict(X_test)#利用最优模型来预测
accuracy = accuracy_score(y_test, y_pred)  # 准确率
precision = precision_score(y_test, y_pred, average='macro')  # 精确率
recall = recall_score(y_test, y_pred, average='macro')  # 召回率
f1 = f1_score(y_test, y_pred, average='macro')  # F1值
print('Accuracy: {:.6f}'.format(accuracy))
print('Precision: {:.6f}'.format(precision))
print('Recall: {:.6f}'.format(recall))
print('F1 score: {:.6f}'.format(f1))
print('cv_test: {:.6f}'.format(cv_test))
# 将评价指标保存到本地
df = pd.DataFrame({'Accuracy': [accuracy], 'Precision': [precision], 'Recall': [recall], 'F1 score': [f1], 'cv_test': [cv_test]})
file_name_csv = 'evaluation_results.csv'
df.to_csv(file_name_csv, index=False)
# 步骤3.3 todo: 绘制ROC曲线,计算auc,度量分类模型的预测能力
#计算预测概率值
y_prob = grid.predict_proba(X_test)[:, 1]
#计算假正率(fpr)、真正率(tpr)以及阈值(thresholds)
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
#计算auc值
auc_score = roc_auc_score(y_test, y_prob)
#绘制ROC曲线
plt.plot(fpr, tpr, color='blue', label='ROC curve (area = %0.2f)' % auc_score)
plt.plot([0, 1], [0, 1], color='red', linestyle='--', label='Random Guess')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.04])
plt.xlabel('假正例率')
plt.ylabel('真正例率(召回率)')
plt.title('Receiver operating characteristic (ROC) Curve')
plt.legend(loc="lower right")
plt.savefig('./results/ROC_Curve.png')
plt.show()

# 步骤3.4 todo:特征重要性分析(RF)
feature_importances = grid.best_estimator_.named_estimators_['rf'].feature_importances_
# 获取特征名称
feature_names = X.columns
# 对数据框进行排序
feature_df = pd.DataFrame({'Feature': feature_names, 'Importance': feature_importances})
feature_df.sort_values(by='Importance', ascending=False, inplace=True)
# 归一化特征重要性
total_importance = feature_df['Importance'].sum()
feature_df['Importance_perc'] = feature_df['Importance'] / total_importance * 100
#使用 seaborn 绘制条形图展示特征的重要性
plt.figure(figsize=(9,6))
ax = sns.barplot(x='Feature', y='Importance_perc', data=feature_df)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90, fontsize=8)
ax.set_ylabel('Importance (%)', fontsize=8)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
ax.set_title("随机森林特征分析", fontsize=15, pad=10)
plt.savefig('./results/Random_Forest_Feature_Importance.png')
plt.show()
print("模型结束")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/617275
推荐阅读
相关标签
  

闽ICP备14008679号