当前位置:   article > 正文

粒子群算法优化K邻近模型参数(scikit-opt包)_机器学习粒子群算法优化参数

机器学习粒子群算法优化参数

前言

  • 最近在学习scikit-opt包,尝试使用启发式算法对机器学习模型参数进行优化。
  • 因为时间关系,挑了一个简单的机器学习模型进行尝试,即K邻近分类模型。
  • 推荐读scikit-opt官方文档,了解各启发式算法输入参数与输出。

安装scitit-opt包

pip install scikit-opt
  • 1

导入必要包

#加载包
import numpy as np
import pandas as pd
from plotnine import*
import seaborn as sns
from scipy import stats

import matplotlib as mpl
import matplotlib.pyplot as plt
#中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# notebook嵌入图片
%matplotlib inline
# 提高分辨率
%config InlineBackend.figure_format='retina'

# 切分数据
from sklearn.model_selection import train_test_split
# 评价指标
from sklearn.metrics import mean_squared_error

# 忽略警告
import warnings
warnings.filterwarnings('ignore')

# 导入粒子群算法
from sko.PSO import PSO
# 交叉检验
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score
  • 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

粒子群算法

  • 首先展示一个官方小例子理解一下算法构造。

定义目标函数

def demo_func(x):
    x1, x2 = x
    return -20 * np.exp(-0.2 * np.sqrt(0.5 * (x1 ** 2 + x2 ** 2))) - np.exp(
        0.5 * (np.cos(2 * np.pi * x1) + np.cos(2 * np.pi * x2))) + 20 + np.e
  • 1
  • 2
  • 3
  • 4

不等式约束

  • 末尾的逗号,一定要加,否则会报错
constraint_ueq = (lambda x: (x[0] - 1) ** 2 + (x[1] - 0) ** 2 - 0.5 ** 2,)
  • 1

优化求解

# 迭代次数
max_iter = 50
pso = PSO(func=demo_func,
          n_dim=2,pop=40,
          max_iter=max_iter,
          lb=[-2, -2],
          ub=[2, 2],
          constraint_ueq=constraint_ueq)
pso.record_mode = True
pso.run()
print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

输出

best_x is  [9.52188498e-01 4.39396655e-05] best_y is [2.57992762]
  • 1

迭代曲线

plt.figure(dpi = 300)
plt.plot(pso.gbest_y_hist)
plt.show()
  • 1
  • 2
  • 3

请添加图片描述

利用粒子群算法调参

生成分类数据

# 生成分类数据
from sklearn.datasets import make_classification

x, y = make_classification(n_samples=1000, # 样本个数
n_features=3, # 特征个数
n_informative=2, # 有效特征个数
n_redundant=1, # 冗余特征个数(有效特征的随机组合)
n_repeated=0, # 重复特征个数(有效特征和冗余特征的随机组合)
n_classes=3, # 样本类别
n_clusters_per_class=1, # 簇的个数
random_state=42)
# 可视化分类数据集,只选择前两个特征
plt.figure(dpi = 600,figsize = (6,4))
plt.scatter(x[:,0],x[:,1],c = y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

请添加图片描述

切分数据集

# 切分数据集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=45, test_size=0.2)
  • 1
  • 2
  • 3

K邻近算法

  • 使用未调参K邻近算法,并检验模型效果
# K邻近算法
from sklearn import neighbors
knn_clf_old = neighbors.KNeighborsClassifier()
knn_clf_old.fit(x_train,y_train)
print('训练集准确率:{:.2f}'.format(accuracy_score(y_train, knn_clf_old.predict(x_train))))
print('测试集准确率:{:.2f}'.format(accuracy_score(y_test, knn_clf_old.predict(x_test))))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

输出

训练集准确率:0.95
测试集准确率:0.92
  • 1
  • 2

定义目标函数

  • 目标函数为10折交叉检验f1_macro平均值
  • 因为算法以最小化为目标,所以这里对f1_macro值取负
def knn_score(x):
    knn_score = cross_val_score(neighbors.KNeighborsClassifier(n_neighbors = int(x)),
                                x_train,y_train,scoring='f1_macro',cv=10).mean()
    return -knn_score
  • 1
  • 2
  • 3
  • 4

优化

max_iter = 50
knn_pso = PSO(func=knn_score,
              n_dim=1,pop=40,
              max_iter=max_iter,
              lb=[1],ub=[100])
knn_pso.record_mode = True
knn_pso.run()
print('best_k is ', int(knn_pso.gbest_x))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出

best_k is  [12.5256584]
  • 1

迭代曲线

plt.figure(dpi = 300)
plt.plot(knn_pso.gbest_y_hist)
plt.show()
  • 1
  • 2
  • 3

请添加图片描述
可以看到当k为12时,算法收敛。

使用最优参

knn_clf_new = neighbors.KNeighborsClassifier(n_neighbors = 12)
knn_clf_new.fit(x_train,y_train)
print('训练集准确率:{:.2f}'.format(accuracy_score(y_train, knn_clf_new.predict(x_train))))
print('测试集准确率:{:.2f}'.format(accuracy_score(y_test, knn_clf_new.predict(x_test))))
  • 1
  • 2
  • 3
  • 4

输出

训练集准确率:0.93
测试集准确率:0.90
  • 1
  • 2
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号