机器学习——基于python的鸢尾花SVM练习(包含超参数批量筛选、交叉验证)

写在前面——虽然本人一直对机器学习感兴趣,但是一直没有动手实践,每次都是看一点入门就放弃了。现在因为课题需要,刚好可以边实践边学习。前面写了一个基于R语言的SVM练习,后来发现还是python好用啊。网上关于鸢(yuan)尾花的各种机器学习例子很多,但大部分都是浅浅一层。我最近在学习超参数优化跟交叉验证,所以就把它们揉在了一起。如有错误,还望大家批评指正。

这里没什么要说的,网上一大堆。放两个给大家参考一下。
https://www.cnblogs.com/luyaoblog/p/6775342.html
https://blog.csdn.net/qq_45769063/article/details/106628800

from sklearn import svm
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.utils import shuffle
from sklearn.model_selection import RepeatedKFold

def Iris_label(s):
    it = {b'Iris-setosa': 0, b'Iris-versicolor': 1, b'Iris-virginica': 2}
    return it[s]

path = 'iris.data'
data = np.loadtxt(path, dtype=float, delimiter=',', converters={4: Iris_label})

x, y = np.split(data, indices_or_sections=(4,), axis=1)
x = x[:, 0:2]

x, y = shuffle(x, y, random_state=123)

train_data, test_data, train_label, test_label = train_test_split(x, y, random_state=1, train_size=0.7, test_size=0.3)

classifier = svm.SVC(C=1, kernel='rbf', gamma=10)
classifier.fit(train_data, train_label.ravel())

print("train:", classifier.score(train_data, train_label))
print("test:", classifier.score(test_data, test_label))

输出结果:
train: 0.8571428571428571
test: 0.7111111111111111

注意此时的超参数C=1, gamma=10。

通过修改C与gamma的值,来优化预测的准确率,使用交叉验证来获得更为准确的反馈,帮助我们选择最优参数。

有关交叉验证的说明如下:

当评价估计器的不同设置(”hyperparameters(超参数)”)时,例如手动为 SVM 设置的 C 参数, 由于在训练集上,通过调整参数设置使估计器的性能达到了最佳状态;但在 测试集上可能会出现 过拟合的情况。 此时, 测试集上的信息反馈足以颠覆训练好的模型,评估的指标不再有效反映出模型的泛化性能。 为了解决此类问题,还应该准备另一部分被称为 “validation set(验证集)” 的数据集,模型训练完成以后在验证集上对模型进行评估。 当验证集上的评估实验比较成功时,在测试集上进行最后的评估。
然而,通过将原始数据分为3个数据集合,我们就大大减少了可用于模型学习的样本数量, 并且得到的结果依赖于集合对(训练,验证)的随机选择。这个问题可以通过 交叉验证(CV ) 来解决。
交叉验证仍需要测试集做最后的模型评估,但不再需要验证集。最基本的方法被称之为,k-折交叉验证 。 k-折交叉验证将训练集划分为 k 个较小的集合。每一个 k 折都会遵循下面的过程:

将 k-1 份训练集子集作为 training data (训练集)训练模型
将剩余的1份训练集子集用于模型验证(也就是把它当做一个测试集来计算模型的性能指标,例如准确率)。

k-折交叉验证得出的性能指标是循环计算中每个值的平均值。 该方法虽然计算代价很高,但是它不会浪费太多的数据(如固定任意测试集的情况一样), 在处理样本数据集较少的问题(例如,逆向推理)时比较有优势。

法一:cross_val_score

参考:https://blog.csdn.net/qq_45769063/article/details/106693502
scoring的参数选择:https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter

代码其实很简单,两行就搞定了!!!

X = []
Y = []
Z = []
M = []
for C in range(5, 15, 1):
    for gamma in range(1, 11, 1):

        rbk = RepeatedKFold(n_splits=5, n_repeats=5, random_state=12)
        accuracy = cross_val_score(svm.SVC(C=C / 10, kernel='rbf', gamma=gamma), x, y.ravel(), cv=rbk, scoring='accuracy').mean()
        X.append(C / 10)
        Y.append(gamma)
        Z.append(accuracy)
        M.append((C / 10, gamma, accuracy))

print(max(Z))

classifier = svm.SVC(C=0.6, kernel='rbf', gamma=1)
classifier.fit(train_data, train_label.ravel())

print("train:", classifier.score(train_data, train_label))
print("test:", classifier.score(test_data, test_label))

输出结果:
0.8057142857142857
train: 0.8380952380952381
test: 0.7777777777777778

通过此方法得到的最优参数分别为:C=1, gamma=10。
我们优化的目的是为了提高预测模型的泛化性,提高模型在测试集上的准确度。
0.78 > 0.71!!! nice~
还可以通过提高K的数值来进行模型优化,比如来个10折、20折交叉验证…

PS:多说一点

参考:https://stackoom.com/question/4QoaS
RepeatedKFold是重复KFold 。它执行n_repeats次。 当n_repeats=1 ,与KFold(n_splits = 5, shuffle = True)完全相同。当然,random_state要一样。

所以在RepeatedKFold中,数据集是默认被打乱滴~
所以前面打乱数据集的操作在用到这个函数的时候可以省略。

法二:GridSearchCV(推荐)

GridSearchCV的名字其实可以拆分为两部分,GridSearch和CV,即网格搜索和交叉验证。网格搜索,搜索的是参数,即在指定的参数范围内,按步长依次调整参数,利用调整的参数训练学习器,从所有的参数中找到在验证集上精度最高的参数,这其实是一个训练和比较的过程。k折交叉验证将所有数据集分成k份,不重复地每次取其中一份做测试集,用其余k-1份做训练集训练模型,之后计算该模型在测试集上的得分,将k次的得分取平均得到最后的得分。

GridSearchCV可以保证在指定的参数范围内找到精度最高的参数,但是这也是网格搜索的缺陷所在,他要求遍历所有可能参数的组合,在面对大数据集和多参数的情况下,非常耗时。

GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化结果和参数。但是这个方法适合于小数据集,一旦数据的量级上去了,很难得到结果。

C_range = []
gamma_range = []
for C in range(5, 15, 1):
    C_range.append(C / 10)

for gamma in range(1, 11, 1):
    gamma_range.append(gamma)

param_grid = dict(gamma=gamma_range, C=C_range)
print(param_grid)
rbk = RepeatedKFold(n_splits=5, n_repeats=5, random_state=12)
grid = GridSearchCV(svm.SVC(kernel='rbf'), param_grid=param_grid, scoring="accuracy", cv=rbk)
grid.fit(x, y.ravel())

print(
    "The best parameters are %s with a score of %0.2f"
    % (grid.best_params_, grid.best_score_)
)

输出结果:
{‘gamma’: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ‘C’: [0.5, 0.6, 0.7, 0.8,
0.9, 1.0, 1.1, 1.2, 1.3, 1.4]} The best parameters are {‘C’: 0.5, ‘gamma’: 1} with a score of 0.81

classifier = svm.SVC(C=0.5, kernel='rbf', gamma=1)
classifier.fit(train_data, train_label.ravel())

print("train:", classifier.score(train_data, train_label))
print("test:", classifier.score(test_data, test_label))

输出结果:
train: 0.819047619047619
test: 0.8

0.8 > 0.78
更有效果!nice~

from sklearn import svm
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.utils import shuffle
from sklearn.model_selection import RepeatedKFold
from sklearn.model_selection import GridSearchCV

def Iris_label(s):
    it = {b'Iris-setosa': 0, b'Iris-versicolor': 1, b'Iris-virginica': 2}
    return it[s]

path = 'iris.data'
data = np.loadtxt(path, dtype=float, delimiter=',', converters={4: Iris_label})

x, y = np.split(data, indices_or_sections=(4,), axis=1)
x = x[:, 0:2]
x, y = shuffle(x, y, random_state=123)

train_data, test_data, train_label, test_label = train_test_split(x, y, random_state=1, train_size=0.7, test_size=0.3)

C_range = []
gamma_range = []
for C in range(5, 15, 1):
    C_range.append(C / 10)

for gamma in range(1, 11, 1):
    gamma_range.append(gamma)

param_grid = dict(gamma=gamma_range, C=C_range)
print(param_grid)
rbk = RepeatedKFold(n_splits=5, n_repeats=5, random_state=12)
grid = GridSearchCV(svm.SVC(kernel='rbf'), param_grid=param_grid, cv=rbk)
grid.fit(train_data, train_label.ravel())

print(
    "The best parameters are %s with a score of %0.2f"
    % (grid.best_params_, grid.best_score_)
)

classifier = svm.SVC(C=0.5, kernel='rbf', gamma=1)
classifier.fit(train_data, train_label.ravel())

print("train:", classifier.score(train_data, train_label))
print("test:", classifier.score(test_data, test_label))

Original: https://blog.csdn.net/narutodzx/article/details/123902457
Author: Dzfly..
Title: 机器学习——基于python的鸢尾花SVM练习(包含超参数批量筛选、交叉验证)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/614078/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球