【数据+代码】多分类——网格搜索优化超参数

1、引言

本文涵盖主题:变量分析、数据分析、数据准备与特征工程、KNN-随机森林-SVM三种算法默认参数与网格搜索优化超参数6种方法进行对分类、总结六个部分。

本实验所使用数据包含影响预测的各种信息,如年龄、性别、血压、胆固醇水平、钠钾比和最后的药物类型。

本文主要结果汇总仪表板:

本期内容『数据+代码』已上传百度网盘。有需要的朋友可以关注公众号【小Z的科研日常】,后台回复关键词[多分类]获取

2、变量分析

特征Age

对Age变量进行统计分析,观察Age变量在数据集中的最大最小值:

print("Max Age:", df.Age.max())
print("Min Age:", df.Age.min())

可观察到:

  • Max Age: 74

  • Min Age: 15

对年龄分布进行可视化:

# 设置绘图风格和颜色方案
sns.set_style('whitegrid')
colors = ['#FFB6C1', '#87CEFA', '#FFE4E1'] # 粉红色、天蓝色、粉色
sns.set_palette(colors)

# 创建画布并设置大小
fig, ax = plt.subplots(figsize=(8, 6))

# 绘制数据分布图,并设置透明度和线宽
sns.kdeplot(df['Age'], alpha=0.8, lw=3, shade=True, ax=ax)

# 配置坐标轴标签和标题,并设置字体大小和样式
ax.set_xlabel('Age', fontsize=20, fontweight='bold', color='k')
ax.set_ylabel('Density ', fontsize=20, fontweight='bold', color='k')
ax.set_title('Distribution of Age', fontsize=24, fontweight='bold', color='k')

# 调整刻度尺的字体大小和样式
for tick in ax.xaxis.get_major_ticks():
    tick.label.set_fontsize(16)
    tick.label.set_fontweight('bold')
    tick.label.set_color('k')
for tick in ax.yaxis.get_major_ticks():
    tick.label.set_fontsize(16)
    tick.label.set_fontweight('bold')
    tick.label.set_color('k')
# 显示图像
plt.show()

由上图可知,年龄分布主要集中在15-74之间。

特征Drug

Drug共由5个类别特征,对其进行分类统计,并进行可视化:

print(df.Drug.value_counts())
# 统计每个 Drug 类别出现的频率
counts = df['Drug'].value_counts()

# 选择颜色
custom_palette = sns.color_palette('pastel', n_colors=5)

# 设置调色板
sns.set_palette(custom_palette)

# 绘制条形图
plt.figure(figsize=(9,5))
sns.barplot(x=counts.index, y=counts.values)
plt.xlabel('Drug')
plt.ylabel('Count')
plt.title('Distribution of Drug in the Dataset')
plt.show()

药物是目标列,可以观察到该特征数据分布不均。为了获得可靠的模型训练结果,可使用K折交叉验证以使模型更可靠。

其余变量分析同理,本文不在赘述。

3、数据分析

Age----Drug

对不同年龄、Drug类型进行可视化分析:

plt.figure(figsize = (9,5))
sns.swarmplot(x = "Drug", y = "Age",data = df)
plt.legend(df.Drug.value_counts().index)
plt.title("Age -- Drug")
plt.show()

print("Minimum Age of DrugB",df.Age[df.Drug == "drugB"].min())

print("Maximum Age of DrugA",df.Age[df.Drug == "drugA"].max())

根据上图:药物B仅由51岁以上的人服用;药物A仅由50岁以下的人服用。

Sex----Drug

统计不同药物中,男性、女性的分布,并对其进行可视化观察:
 

df_Sex_Drug = df.groupby(["Drug","Sex"]).size().reset_index(name = "Count")
print(df_Sex_Drug)
plt.figure(figsize = (9,5))
sns.barplot(x = "Drug",y="Count", hue = "Sex",data = df_Sex_Drug)
plt.title("Sex -- Drug")
plt.show()

上图可知:男性得到药物A、B和药物C的机会比女性多。女性得到的DrugY比男性多,药物X对男性和女性来说似乎是一样的。根据上述图表,性别特征不是一个重要的分类特征。

BP----Drug

与上述同理,先进行统计分析,其次进行可视化分析:

df_BP_Drug = df.groupby(["Drug","BP"]).size().reset_index(name = "Count")
plt.figure(figsize = (9,5))
sns.barplot(x = "Drug",y="Count", hue = "BP",data = df_BP_Drug)
plt.title("BP -- Drug")
plt.show()

上述分析表明,药物A和药物B只有高血压患者才能得到。血压低的人可以得到药物C。药物X是由高血压患者得到的。血压是分类的一个重要特征。

Na_to_K---Drug

plt.figure(figsize = (9,5))
sns.swarmplot(x = "Drug", y = "Na_to_K",data = df)
plt.title("Na_to_K -- Drug")
plt.show()
print("Minimum Na_to_K for DrugY:",df.Na_to_K[df.Drug == "DrugY"].min())

经分析,Na_to_K比率大于15的人,会得到DrugY。我们可以从这里创建一个新的特征。

Cholesterol---Drug

df_CH_Drug = df.groupby(["Drug","Cholesterol"]).size().reset_index(name = "Count")
print(df_CH_Drug)
plt.figure(figsize = (9,5))
sns.barplot(x = "Drug",y="Count", hue = "Cholesterol",data = df_CH_Drug)
plt.title("Cholesterol -- Drug")
plt.show()

胆固醇高的人可以得到药物C。胆固醇是对药物C进行分类的一个重要特征。

Na_to_K--BP--Drug

plt.figure(figsize = (9,5))
sns.swarmplot(x = "Drug", y = "Na_to_K",hue="BP",data = df)
plt.legend()
plt.title("Na_to_K -- BP -- Drug")
plt.show()

如果人们有高血压,并且Na_to_K比率低于15,他们只能得到药物A和药物B。

4、数据准备与特征工程

特征工程

经过上一章节的数据分析,如果Na_to_K数值大于15,则认定给予的药物是药物Y:

df['Na_to_K_Bigger_Than_15'] = [1 if i >=15.015 else 0 for i in df.Na_to_K]
df_NaK15 = df.groupby(["Drug","Na_to_K_Bigger_Than_15"]).size().reset_index(name = "Count")
plt.figure(figsize = (9,5))
sns.barplot(x = "Drug",y="Count", hue = "Na_to_K_Bigger_Than_15",data = df_NaK15)
plt.title("Na_to_K_Bigger_Than_15 -- Drug")
plt.show()

Na_to_K_Bigger_Than_15特征将是药物Y分类的重要特征。

标签编码

我们将非数值特征从对象转换为int64类型,以便后续进行模型训练:
 

from sklearn.preprocessing import LabelEncoder
def label_encoder(y):
    le = LabelEncoder()
    df[y] = le.fit_transform(df[y])

label_list = ["Sex","BP","Cholesterol","Na_to_K","Na_to_K_Bigger_Than_15","Drug"]
for l in label_list:
    label_encoder(l)

训练、测试集划分

from sklearn.model_selection import train_test_split
x = df.drop(["Drug"],axis=1)
y = df.Drug
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.2, random_state = 42, shuffle = True)
y_train = y_train.values.reshape(-1,1)
y_test = y_test.values.reshape(-1,1)
print("x_train shape:",x_train.shape)
print("x_test shape:",x_test.shape)
print("y_train shape:",y_train.shape)
print("y_test shape:",y_test.shape)

5、模型建立

实验将尝试三种模型并比较它们的结果。对于所有的模型,采用GridSearchCV方法来寻找最佳分数。此外,为了确保模型性能是随机的,使用5折交叉验证方法。

KNN默认参数

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
accuracies = cross_val_score(knn, x_train, y_train, cv=5)
knn.fit(x_train,y_train)
print("Train Score:",np.mean(accuracies))
print("Test Score:",knn.score(x_test,y_test))
  • Train Score: 0.59375

  • Test Score: 0.65

GridSearchCV优化KNN

为了找到KNN模型的最佳得分,将尝试不同的n_neighbors、p和weights参数值:

grid = {'n_neighbors':np.arange(1,120),
        'p':np.arange(1,3),
        'weights':['uniform','distance']
       }

knn = KNeighborsClassifier(algorithm = "auto")
knn_cv = GridSearchCV(knn,grid,cv=5)
knn_cv.fit(x_train,y_train)
print("Hyperparameters:",knn_cv.best_params_)
print("Train Score:",knn_cv.best_score_)
print("Test Score:",knn_cv.score(x_test,y_test))
  • Hyperparameters:{'n_neighbors':10, 'p': 1, 'weights': 'distance'}

  • Train Score: 0.75625

  • Test Score: 0.7

随机森林默认参数

from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier(random_state = 42)
accuracies = cross_val_score(rfc, x_train, y_train, cv=5)
rfc.fit(x_train,y_train)

print("Train Score:",np.mean(accuracies))
print("Test Score:",rfc.score(x_test,y_test))
  • Train Score: 0.98125

  • Test Score: 0.975

GridSearchCV优化随机森林

为了找到随机森林模型的最佳得分,将尝试不同的n_estimators和标准参数的值。

grid = {'n_estimators':np.arange(100,1000,100),
        'criterion':['gini','entropy']
       }

rf = RandomForestClassifier(random_state = 42)
rf_cv = GridSearchCV(rf,grid,cv=5)
rf_cv.fit(x_train,y_train)

print("Hyperparameters:",rf_cv.best_params_)
print("Train Score:",rf_cv.best_score_)
print("Test Score:",rf_cv.score(x_test,y_test))
  • Hyperparameters:{'criterion':'entropy','n_estimators': 100}

  • Train Score: 0.9875

  • Test Score: 0.975

SVM默认参数

from sklearn.svm import SVC
svc = SVC(random_state = 42)
accuracies = cross_val_score(svc, x_train, y_train, cv=5)
svc.fit(x_train,y_train)

print("Train Score:",np.mean(accuracies))
print("Test Score:",svc.score(x_test,y_test))
  • Train Score: 0.7125

  • Test Score: 0.65

GridSearchCV优化SVM

grid = {
    'C':[0.01,0.1,1,10],
    'kernel' : ["linear","poly","rbf","sigmoid"],
    'degree' : [1,3,5,7],
    'gamma' : [0.01,1]
}

svm  = SVC ();
svm_cv = GridSearchCV(svm, grid, cv = 5)
svm_cv.fit(x_train,y_train)
print("Best Parameters:",svm_cv.best_params_)
print("Train Score:",svm_cv.best_score_)
print("Test Score:",svm_cv.score(x_test,y_test))
  • Best Parameters: {'C': 1, 'degree': 1, 'gamma': 0.01, 'kernel': 'linear'}

  • Train Score: 0.9875

  • Test Score: 0.975

6、总结

对上述六种方法得分进行总结与可视化:

df_result_train = pd.DataFrame.from_dict(result_dict_train,orient = "index",columns=["Score"])
df_result_test = pd.DataFrame.from_dict(result_dict_test,orient = "index",columns=["Score"])

fig,ax = plt.subplots(1,2,figsize=(20,5))
sns.barplot(x = df_result_train.index,y = df_result_train.Score,ax = ax[0])
sns.barplot(x = df_result_test.index,y = df_result_test.Score,ax = ax[1])
ax[0].set_xticklabels(df_result_train.index,rotation = 75)
ax[1].set_xticklabels(df_result_test.index,rotation = 75)
plt.show()

 经上述分析与图表观察,随机森林算法和SVM算法(经过超参数调整)分类效果最佳。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我知道了。以下是使用网格搜索优化lstm分类超参数Python代码示例: ```python from sklearn.model_selection import GridSearchCV from keras.wrappers.scikit_learn import KerasClassifier from keras.models import Sequential from keras.layers import Dense, LSTM from keras.optimizers import RMSprop import numpy as np def create_model(units=128, dropout=0.2): model = Sequential() model.add(LSTM(units=units, dropout=dropout, input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(Dense(1, activation='sigmoid')) optimizer = RMSprop(lr=0.01) model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']) return model np.random.seed(42) # Load data X_train = np.load('X_train.npy') y_train = np.load('y_train.npy') # Create Keras classifier model = KerasClassifier(build_fn=create_model, verbose=0) # Define grid search parameters param_grid = { 'units': [64, 128], 'dropout': [0.2, 0.5] } # Perform grid search grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1) grid_result = grid.fit(X_train, y_train) # Print results print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_)) ``` 以上代码演示了如何使用网格搜索优化 LSTM 分类器的超参数。在此示例中,我们使用 GridSearchCV 对模型进行训练和评估。我们定义了两个超参数:LSTM 内部细胞单元的数量和丢失率(dropout rate)。GridSearchCV 迭代不同的超参数组合,并使用交叉验证评估每种组合的性能。最终,我们打印出最佳参数组合及其对应的性能得分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小Z的科研日常

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值