粒子群算法 SVM
程序员文章站
2022-05-20 22:48:45
...
粒子群算法 SVM
SVM是调的包,辣鸡代码仅供参考,数据集有需要留下邮箱
#运用粒子群算法优化SVM正则参数C,以及核函数RBF函数的gamma的问题
import random
import numpy as np
from sklearn import svm
from sklearn import model_selection
import matplotlib.pyplot as plt
#设置PSO关键参数
particle_num = 30 #粒子数量,个数要适量,不能太大和太小
particle_dim = 2 #每个粒子的维度,维度要与优化的参数个数相同
iter_num = 400 # 最大迭代次数
c1 = 1.5 # 参考自己历史最优的权重
c2 = 1 # 参考全局最优的的权重
w_max = 1 # 惯性因子,表示粒子之前运动方向在本次方向上的惯性
w_min = 0.5
min_value = 0.0001 # 参数最小值
best_fit = []
no_change = 0 #全局最优未改变次数,达到50次则终止程序
#读取数据并进行预处理
def load_data(data_file):
data = [] #存储特征
label = [] #存储标签
f = open(data_file)
for line in f.readlines():
lines = line.strip().split(' ')
label.append(float(lines[0]))#提取标签
#提取特征
index = 0
tmp = [] #存储每个标签对应的特征
#数据预处理,对于缺少的特征以0补上
for i in range(1, len(lines)):
li = lines[i].strip().split(":")
if int(li[0]) - 1 == index: #特征存在
tmp.append(float(li[1]))
else: #特征不存在以零补上,并将当前的添加上
while (int(li[0]) - 1 > index):
tmp.append(0)
index += 1
tmp.append(float(li[1]))
index += 1
while len(tmp) < 13: #处理特征在最后缺少的情况
tmp.append(0)
data.append(tmp)
f.close()
return np.array(data), np.array(label).T
#PSO
#1.粒子及其运动方向初始化
def inti_origin():
particle_loc = [] #记录所有粒子移动过的位置,为一个二维数组,
particle_dir = [] #记录所有粒子要移动的方向,及其历史方向,为二维数组
for i in range(particle_num):
tempA = [] #存储每个粒子的参数
tempB = [] #存储每个例子的移动方向
for j in range(particle_dim):
a = random.random()*(20-min_value) #随机参数
b = random.random() # 随机移动方向
tempA.append(a)
tempB.append(b)
particle_loc.append(tempA)
particle_dir.append(tempB)
return particle_loc,particle_dir
#2.计算SVM的适应度函数值,并寻找局部和全局最优适应度,及其对应的参数
def fitness(particle_loc,trainX, trainY,pbest_fit,gbest_fit,pbest_loc,gbest_loc):
#particle_loc粒子所在位置集合
#pbest_fit 局部最优适应度
#gbest_fit 全局最优适应度
#pbest_loc 局部最优参数
#gbest_loc 全局最优参数
fit_value = []
#对每个粒子计算其适应度,以3-fold拆分数据,RBF为核函数,求出3个适应度值,取平局值为最终结果
for i in range(particle_num):
rbf_svm = svm.SVC(kernel='rbf', C=particle_loc[i][0], gamma=particle_loc[i][1])
cv_scores = model_selection.cross_val_score(rbf_svm, trainX, trainY, cv=3, scoring='accuracy')
fit_value.append(cv_scores.mean())
k = 0 # 记录循环下标
for i in range(len(fit_value)):
if(pbest_fit[k] < fit_value[k]): #新的局部最优出现
pbest_fit[k] = fit_value[k]
pbest_loc[k] = particle_loc[k]
if(fit_value[k] > gbest_fit): #新的全局最优出现
gbest_fit = fit_value[k]
gbest_loc = particle_loc[k]
print('最优适应度为{},对应参数是{}'.format(gbest_fit,gbest_loc))
best_fit.append(gbest_fit)
return pbest_fit,gbest_fit,pbest_loc,gbest_loc
#3.更新粒子的位置
def updata(particle_loc,particle_dir,pbest_loc,gbest_loc,k):
#k为当前迭代次数,动态更新w时使用
w = w_max - (w_max-w_min)*((k+1)/iter_num) #w采用新的更新方式
for i in range(particle_num): # 速度更新
#新的速度由三部分组成
a1 = [w * particle_dir[i][0],w * particle_dir[i][1]]
a2 = [c1 * random.random() * (pbest_loc[i][0] - particle_loc[i][0]),c1 * random.random() * (pbest_loc[i][1] - particle_loc[i][1])] #参考局部
a3 = [c2 * random.random() * (gbest_loc[0] - particle_loc[i][0]),c2 * random.random() * (gbest_loc[1] - particle_loc[i][1])] #参考全局
new_dir = [a1[0]+a2[0]+a3[0],a1[1]+a2[1]+a3[1]]
particle_dir[i] = new_dir #更新速度
particle_loc[i] = [particle_dir[i][0] + new_dir[0],particle_dir[i][1] + new_dir[1]] #更新位置
#由于SVM的要求是参数不能小于零,并且应该保持在一定范围保证其性能,所以要对更新后的参数进行判断
particle_loc[i][0] = max(particle_loc[i][0], min_value)
particle_loc[i][1] = max(particle_loc[i][1], min_value)
return particle_dir,particle_loc
#画适应度折线图
def plot(best_fit):
X = []
Y = []
for i in range(len(best_fit)):
X.append(i + 1)
Y.append(best_fit[i])
plt.plot(X, Y)
plt.xlabel('迭代次数', size=15)
plt.ylabel('适应度', size=15)
plt.show()
#画散点图
def plot_point(pbest_loc):
X = []
Y = []
for i in range(len(pbest_loc)):
X.append(pbest_loc[i][0])
Y.append(pbest_loc[i][1])
plt.figure(figsize=(20, 8), dpi=100) #创建画布
plt.scatter(X,Y)
plt.show()
if __name__ == '__main__':
#读取数据
trainX, trainY = load_data('rbf_data.txt')
#初始化
particle_loc, particle_dir = inti_origin()
all_fitness = [] #记录所有计算过的适应度的值
pbest_fit = [] #记录每个粒子各自的最优适应度
pbest_loc = [] #记录每个粒子各自的最优位置
for i in range(particle_num):
pbest_fit.append(0.0)
pbest_loc.append([0.0,0.0])
gbest_fit = 0.0 #全局最优适应度
gbest_loc = [0.0,0.0] #全局最优位置
for i in range(iter_num):
print('迭代次数:',i+1,end=",")
old_gbest_fit = gbest_fit
pbest_fit,gbest_fit,pbest_loc,gbest_loc = fitness(particle_loc, trainX, trainY,pbest_fit,gbest_fit,pbest_loc,gbest_loc)
#如果过连续50代没有产生新的最优值则停止循环
if(old_gbest_fit == gbest_fit):
no_change += 1
else:
no_change = 0
if(no_change == 50):
break
particle_dir, particle_loc = updata(particle_loc,particle_dir,pbest_loc,gbest_loc,i)
plot_point(pbest_loc)
plot(best_fit)
上一篇: MATLAB 图像处理2 二值化,背景估计,连通区域分析
下一篇: 子集和问题 深搜回溯法