ModelCube(modelcube.cn)是博雅数智自主研发的一站式人工智能科研平台。为全国高校和科研机构的大数据和人工智能科研团队提供一站式科研服务。基于MLOps的实践和企业核心技术,实现了科研场景中全类型数据管理与标注,实验环境快速获取与灵活定制,模型的全生命周期管理,科研成果的管理与发布,以及 AI驱动的论文检索和学习等功能。
基于集成学习的肾结石预测
本实验的数据集是由深度学习模型生成的,该模型使用基于尿液分析的肾结石预测数据集进行训练。特征分布与原始数据集接近,但不完全相同。本实验的目的是开发一个基于草酸钙晶体形成预测肾结石存在的机器学习模型。
数据字段说明如下:
字段名称 | 字段说明 |
---|---|
id | ID |
gravity | 尿液比重 |
ph | 尿液酸碱度 |
osmo | 尿液渗透压 |
cond | 尿液电导率 |
urea | 尿液中尿素浓度 |
calc | 尿液中钙的浓度 |
target | 目标,0-无结石 1-有结石 |
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
1. 数据集基本分析
df = pd.read_csv("../dataset/1001453/train.csv")
df.sample(5)
#Check for missing values
df.isnull().sum()
#Check for duplications
df.duplicated().sum()
0
df.dtypes
df.describe()
2. 探索性数据分析
数据柱状图:
df.hist(figsize=(10, 10))
plt.show()
数字列的散点图矩阵:
sns.pairplot(df, hue="target")
plt.show()
皮尔逊相关矩阵:
corr = df.corr()
sns.heatmap(corr, cmap='coolwarm', annot=True)
plt.show()
3. 模型建立和混淆矩阵
训练集和验证集拆分:
df = df.drop(columns=["id",],axis=1)
df
y = df["target"]
X = df.drop("target",axis=1)
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X,y,test_size=0.2,random_state=12,stratify=y)
使用的度量:ROC(受试者工作特性曲线)
所选模型:
决策树分类器
随机森林分类器
逻辑回归
梯度提升分类器
XGBoost分类器
支持向量机
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from xgboost import XGBClassifier
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, cross_val_score
classifiers = [
('Decision Tree Clf', DecisionTreeClassifier(max_depth=3, min_samples_split=2, min_samples_leaf=1, random_state=42)),
('Random Forest Clf', RandomForestClassifier(n_estimators=200, max_depth=5, min_samples_split=2, random_state=42)),
('Logistic Clf', LogisticRegression(penalty='l2', C=1.0, random_state=42,solver='lbfgs',max_iter=1000)),
#lbfgs:-Limited-memory Broyden–Fletcher–Goldfarb–Shanno Algorithm for logistic regression as solver
('GB Clf', GradientBoostingClassifier(n_estimators=300, max_depth=3, min_samples_split=2, learning_rate=0.1, random_state=42)),
('XGBoost Clf', XGBClassifier(n_estimators=300, max_depth=3, learning_rate=0.1, random_state=42)),
('SVM Clf', SVC(kernel='rbf', C=1.0, gamma=0.1, random_state=42)),
]
for name, clf in classifiers:
# Cross-validation with 5-folds
cv_scores = cross_val_score(clf, X_train, y_train, cv=10, scoring='roc_auc') #Scoring metric is ROC Area under the curve
print(f"Score: {name}:", np.mean(cv_scores))
print(f"Std. Dev. for {name}:", np.std(cv_scores))
print(" ")
每个分类器的混淆矩阵:
我们的目标是具有非常低的FNR和高的召回率(否则我们会错过肾结石的潜在存在)。召回率是指正确归类为阳性的阳性样本数量与阳性样本总数之间的比率。
from sklearn.metrics import confusion_matrix
for name, clf in classifiers:
clf.fit(X_train,y_train)
y_pred = clf.predict(X_val)
cm = confusion_matrix(y_val,y_pred)
sns.heatmap(cm,
annot=True,
fmt='g',
xticklabels=['Present','Absent'],
yticklabels=['Present','Absent'])
plt.ylabel('Prediction',fontsize=13)
plt.xlabel('Actual',fontsize=13)
plt.title(f'Confusion Matrix for {name}',fontsize=17)
plt.show()
随机森林的ROC得分最高,因此我们将继续进行RF Clf的超参数调整。
4. 超参数调整
功能重要性:
基于目标变量中杂质的减少(肾结石的存在)来计算特征重要性。随机森林算法的工作原理是在随机选择的数据子集上构建多个决策树,然后将它们的预测组合起来进行最终预测。
在每个决策树中,最重要的特征在每次拆分时都会根据它们将数据划分为不同组的能力进行选择。特征重要性得分计算为随机林中所有决策树上每个特征引起的杂质减少。
这意味着具有较高重要性分数的特征是那些在预测肾结石存在方面提供最多信息获取或辨别能力的特征。通过分析特征重要性得分,我们可以深入了解哪些特征与预测目标变量最相关,哪些特征可以被丢弃以简化模型,而不会损失太多准确性。
rfc = RandomForestClassifier(n_estimators=200, max_depth=5, min_samples_split=2, random_state=42)
rfc.fit(X_train,y_train)
feat_importances = pd.Series(rfc.feature_importances_, index=X.columns)
feat_importances.plot(kind='barh')
例如,随机森林分类器的重要特征是钙(钙浓度)和尿素浓度,它们为分裂提供了更多的信息增益。
4.1 超参数调整:使用网格搜索交叉验证方法
此处需要考虑的事项:
网格搜索CV将在指定的参数网格上进行详尽搜索,以找到导致最高交叉验证分数的超参数组合
n_jobs=-1;我们希望使用所有可用的CPU核心来并行化网格搜索,这可以显著加快搜索过程!
超参数:
n_估计器:要在随机森林中构建的决策树的数量。较高数量的树可以带来更好的性能,但代价是增加计算时间和可能的过拟合。
max_depth:随机森林中每个决策树的最大深度。更深的树可以捕获数据中更复杂的关系,但也可能导致过度拟合。
min_samples_split:在决策树中拆分节点所需的最小样本数。较高的值可以导致更简单的树,并防止过度拟合。
min_samples_leaf:决策树中一个叶节点所需的最小样本数。较高的值可以导致更简单的树,并防止过度拟合。
max_features:在每个节点上寻找最佳分割时要考虑的最大功能数。较低的值可以降低树的复杂性并防止过拟合。
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [20, 50, 150, 200],
'max_depth': [None, 6, 10, 20],
'min_samples_split': [10, 15, 20],
'min_samples_leaf': [1, 2],
'max_features': ['sqrt', 'log2']
} #192 different hyperparameter settings 4 x 4 x 3 x 2 x 2
rf = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, scoring='roc_auc' ,cv=7, n_jobs=-1)
grid_search.fit(X, y) #fitting the full dataset
print("Best parameters: ", grid_search.best_params_)
print("Best score: ", grid_search.best_score_)
y_val_pred = grid_search.best_estimator_.predict(X_val)
from sklearn import metrics
fpr, tpr, thresholds = metrics.roc_curve(y_val, y_val_pred)
roc_auc = metrics.auc(fpr, tpr)
display = metrics.RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc)
display.plot()
plt.show()
在线运行本实验请登录ModelCube
http://modelcube.cn/experiment/experiment-detail/1008991
在线运行本实验请登录ModelCube
http://modelcube.cn/experiment/experiment-detail/1008991