支持向量机 (SVM) 模型调参:网格搜索和交叉验证
本代码示例使用 Python 中的 scikit-learn 库来演示如何对支持向量机 (SVM) 模型进行调参。
首先,导入所需的库和模块:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
读取数据并进行预处理:
data = pd.read_excel('处理后的数据.xlsx')
X = data[['特征1', '特征2', '特征3', '特征4', '特征5', '特征6', '特征7', '特征8', '特征9']]
y = data['类别']
拆分数据集为训练集和测试集:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
方法一:手动调参
定义初始最佳成绩为0。
best_score = 0 # 最佳成绩
使用嵌套循环遍历不同的参数组合:
# 对每种参数组合都训练一个模型,评估其成绩,找到最佳参数组合
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
svm = SVC(gamma=gamma, C=C).fit(X_train, y_train)
score = svm.score(X_test, y_test) # 在测试集上评估SVC
# 如果得到了更高的分数,则保存该分数和对应的参数
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
print("Best score: {:.2f}".format(best_score)) # 输出最佳成绩
print("Best parameters: {}".format(best_parameters)) # 输出最佳参数组合
**改进:**使用验证集进行参数选择,避免过拟合
# 首先,将数据拆分为(训练+验证集)与测试集
X_train_valid, X_test, y_train_valid, y_test = train_test_split(X, y, random_state=0)
# 然后,将(训练+验证集)拆分为训练集与验证集
X_train, X_valid, y_train, y_valid = train_test_split(X_train_valid, y_train_valid, random_state=1)
best_score = 0
# 对每种参数组合都训练一个模型,评估其成绩,找到最佳参数组合
for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
for C in [0.001, 0.01, 0.1, 1, 10, 100]:
svm = SVC(gamma=gamma, C=C).fit(X_train, y_train)
score = svm.score(X_valid, y_valid) # 注意!这里改为在验证集上评估模型
if score > best_score:
best_score = score
best_parameters = {'C': C, 'gamma': gamma}
print("Training_set size: {} , Validation_set size: {} , Test_set size: {}"
.format(X_train.shape[0], X_valid.shape[0], X_test.shape[0]))
# 利用调参得到的最佳参数组合,在(训练+验证集)上重新构建一个模型,并在测试集上进行评估
svm = SVC(**best_parameters)
svm.fit(X_train_valid, y_train_valid)
test_score = svm.score(X_test, y_test) # 测试集只用做最终评估,不参与调参,保证测试的客观性
print("Best score on validation_set: {:.2f}".format(best_score))
print("Best parameters: ", best_parameters)
print("Test_set score with best parameters: {:.2f}".format(test_score)) # 输出测试成绩
方法二:使用 GridSearchCV 进行网格搜索
from sklearn.model_selection import GridSearchCV # 引入网格搜索类
# 定义参数列表
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}
# 定义GridSearchCV对象,注意参数
# 参数1-模型
# 参数2-参数列表
# 参数3-交叉验证次数(网格搜索具有交叉验证功能)
grid_search = GridSearchCV(SVC(), param_grid, cv=10)
# 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
grid_search.fit(X_train, y_train) # 将训练数据交给GridSearchCV对象
# 输出最佳参数组合及最佳成绩(利用.best_params_和.best_score_属性)
print("Best parameters: {}".format(grid_search.best_params_))
print("Best cross-validation score: {:.2f}".format(grid_search.best_score_))
代码解释
-
导入所需的库和模块:
numpy:用于处理数组和数值计算。pandas:用于处理数据和数据分析。matplotlib.pyplot:用于数据可视化。sklearn.datasets:用于加载数据集。sklearn.model_selection:用于拆分数据集为训练集和测试集。sklearn.svm:支持向量机模型。sklearn.metrics:评估模型性能的指标。
-
读取数据并进行预处理:
- 使用
pandas的read_excel函数读取 Excel 文件中的数据。 - 将特征列和类别列分别赋值给
X和y。
- 使用
-
拆分数据集为训练集和测试集:
- 使用
train_test_split函数,将X和y分别拆分为训练集和测试集,其中测试集占总数据的 30%。
- 使用
-
方法一:手动调参
- 定义初始最佳成绩为 0。
- 使用嵌套循环遍历不同的参数组合,分别为
gamma和C。 - 对于每种参数组合,训练一个
SVC模型,并使用score方法在测试集上评估模型的准确率。 - 如果得到的准确率高于当前最佳成绩,则更新最佳成绩和最佳参数组合。
- 最后,输出最佳成绩和最佳参数组合。
-
改进:使用验证集进行参数选择,避免过拟合
- 将数据拆分为 (训练+验证集) 和测试集,并进一步将 (训练+验证集) 拆分为训练集和验证集。
- 在训练模型后,使用验证集评估模型性能,而不是测试集。
- 使用验证集找到最佳参数组合后,再使用该参数组合在整个 (训练+验证集) 上训练模型,最后在测试集上进行最终评估。
-
方法二:使用
GridSearchCV进行网格搜索- 导入
GridSearchCV类。 - 定义参数列表,包含要调节的参数及其可能取值。
- 定义
GridSearchCV对象,传入模型、参数列表和交叉验证次数。 - 使用
train_test_split函数拆分数据集为训练集和测试集。 - 将训练数据交给
GridSearchCV对象进行调参,GridSearchCV会自动遍历所有参数组合,并在交叉验证集上评估模型性能。 - 最后,输出最佳参数组合和最佳交叉验证分数。
- 导入
通过使用 GridSearchCV 进行网格搜索,可以更有效地找到最佳参数组合,并避免手动遍历所有参数组合的繁琐操作。同时,交叉验证可以更准确地评估模型性能,避免过拟合问题。
原文地址: http://www.cveoy.top/t/topic/qgnZ 著作权归作者所有。请勿转载和采集!