目录
需求
用布谷鸟搜索算法cs、粒子群优化算法pso优化svm分类,并进行pr曲线输出
数据集–pred.xlsx
数据集–cupcake or muffin.xlsx
算法介绍
布谷鸟搜索算法cs
布谷鸟搜索算法是一种基于鸟类觅食行为的启发式搜索算法,通过模拟布谷鸟在树林中觅食的行为,来寻找最优解。
优点
- 高效性:布谷鸟搜索算法通过利用鸟类觅食的行为,将搜索空间划分为不同的领域,并根据领域内的信息指导搜索方向,提高搜索效率。
- 自适应性:布谷鸟搜索算法具有自适应性,能够根据搜索过程中的反馈信息调整搜索的策略,从而适应不同的问题类型和搜索空间。
- 算法简单:布谷鸟搜索算法的核心思想简单易懂,实现起来相对较简单。
缺点
- 参数选择:布谷鸟搜索算法中存在一些参数,如觅食成功率、搜索半径等,需要根据具体问题进行调整,选择合适的参数可能需要一定的经验和试验。
- 局部最优解:布谷鸟搜索算法可能陷入局部最优解,而难以跳出。虽然可以通过随机扰动等方式,增加跳出局部最优解的机会,但仍然存在一定的概率陷入局部最优解。
- 启发式搜索能力有限:布谷鸟搜索算法在处理复杂问题时,可能由于搜索空间过大或问题结构复杂,导致搜索效果不佳。
粒子群优化算法pso
粒子群优化算法是一种基于群体智能的优化算法,它模拟了鸟群或鱼群的行为,通过多个个体(粒子)之间的协作和信息交流来优化问题。
优点
- 算法简单,易于实现和理解。PSO算法的原理较为直观,基本流程简单,容易理解和编写代码实现。
- 全局搜索能力较强。PSO算法通过粒子之间的信息交流和协作来寻找全局最优解,从而可以在复杂的搜索空间中找到全局最优解。
- 收敛速度快。由于群体智能的机制,粒子可以通过相互协作和信息交流来引导搜索,因此PSO算法的收敛速度较快。
- 对于多目标优化问题有较好的适应性。PSO算法可以通过修改适应度函数的方式来适应多目标优化问题,并搜索多个最优解。
缺点
- 对初始参数和控制参数敏感。初始参数和控制参数的选择对PSO算法的性能有很大影响,不合适的参数选择可能导致算法陷入局部最优解或者收敛速度过慢。
- 缺乏对搜索空间的探索能力。PSO算法主要通过粒子之间的信息交流和协作来搜索最优解,但对于搜索空间的探索能力相对较弱,容易陷入局部最优解。
- 算法存在早熟收敛问题。由于算法的全局搜索能力较强,当算法开始收敛时,粒子往往会聚集在某一区域,导致算法早熟收敛,无法进一步搜索更好的解。
支持向量机分类svc
支持向量机分类算法是一种常用的分类算法,主要思想是通过找到最大间隔来实现分类,使得不同类别的数据点能够尽可能地被分开。
优点
- 在处理高维数据时表现较好:支持向量机通过引入核函数可以将原始特征映射到高维空间,从而使得数据在高维空间中更容易分离。
- 样本量较小时仍能表现良好:SVC通过寻找最优超平面来进行分类,在样本量较小时也能保持较好的泛化性能。
- 可处理非线性问题:通过使用非线性核函数,SVC可以处理非线性问题,如多项式核函数、高斯核函数等。
- 结果具有较好的泛化能力:SVC通过最大化分类间隔来进行分类,可以有效避免过拟合问题,具有较好的泛化能力。
缺点
- 计算复杂度较高:SVC在训练时需要解优化问题,计算复杂度较高,特别是对于大规模数据集而言。
- 对于噪声敏感:SVC对于噪声敏感,噪声会对最大间隔超平面的确定产生影响,从而影响分类结果。
- 对缺失数据敏感:SVC对于缺失数据敏感,缺失数据的处理需要额外的步骤。
- 参数选择较为困难:SVC的性能很大程度上依赖于选择合适的参数,例如核函数类型、核函数参数等,参数选择较为困难。
- 只适用于二分类问题:原始的SVC算法只适用于二分类问题,对于多分类问题需要进行扩展或使用其他方法。
建模
svc二分类基础,pr输出
#实现svm二分类,pr曲线表示
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets,metrics
import pandas as pd
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\cupcake or muffin.xlsx"
data = pd.read_excel(path)
x=np.array(list(zip(data.Sugar,data.Butter)))#数据
# print(x)
y=np.where(data['CakeType']=='muffin',0,1)#标签
# print(y)
#建立模型并训练
clf=svm.SVC(probability= True)
clf.fit(x,y)
#模型预测
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\pred.xlsx"
data1 = pd.read_excel(path)
x_test=np.array(list(zip(data1.Sugar,data1.Butter)))#需要预测的数据
y_test=np.where(data1['CakeType']=='muffin',0,1)#标签
y_pred=clf.predict(x_test)#预测类别
print(y_pred)
y_prob=clf.predict_proba(x_test)[:,1]
print(y_test)
print(y_prob)#预测每个类别概率
print(len(np.where(y_pred == y_test)[0]) / len(y_test) * 100)
#绘制pr
#y_true是正确标签,y_prob是概率输出值,thresholds是阈值
precision, recall, thresholds = metrics.precision_recall_curve(y_test, y_prob, pos_label=None, sample_weight=None)
fig = plt.figure()
plt.plot(precision, recall, label='Logistic')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.legend()
plt.show()
pso优化svc
import csv
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.metrics import explained_variance_score
from sklearn import svm
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import explained_variance_score
from sklearn import metrics
from sklearn.metrics import mean_absolute_error # 平方绝对误差
import random
import pandas as pd
class PSO:
def __init__(self, parameters):
"""
particle swarm optimization
parameter: a list type, like [NGEN, pop_size, var_num_min, var_num_max]
"""
# 初始化
self.NGEN = parameters[0] # 迭代的代数
self.pop_size = parameters[1] # 种群大小
self.var_num = len(parameters[2]) # 变量个数
self.bound = [] # 变量的约束范围
self.bound.append(parameters[2])
self.bound.append(parameters[3])
self.pop_x = np.zeros((self.pop_size, self.var_num)) # 所有粒子的位置
self.pop_v = np.zeros((self.pop_size, self.var_num)) # 所有粒子的速度
self.p_best = np.zeros((self.pop_size, self.var_num)) # 每个粒子最优的位置
self.g_best = np.zeros((1, self.var_num)) # 全局最优的位置
# 初始化第0代初始全局最优解
temp = -1
for i in range(self.pop_size):
for j in range(self.var_num):
self.pop_x[i][j] = random.uniform(self.bound[0][j], self.bound[1][j])
self.pop_v[i][j] = random.uniform(0, 1)
self.p_best[i] = self.pop_x[i] # 储存最优的个体
fit = self.fitness(self.p_best[i])
if fit > temp:
self.g_best = self.p_best[i]
temp = fit
def fitness(self, ind_var):
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\cupcake or muffin.xlsx"
data = pd.read_excel(path)
x_train = np.array(list(zip(data.Sugar, data.Butter))) # 数据
y_train = np.where(data['CakeType'] == 'muffin', 1, 2) # 标签
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\pred.xlsx"
data1 = pd.read_excel(path)
x_test = np.array(list(zip(data1.Sugar, data1.Butter))) # 需要预测的数据
y_test = np.where(data1['CakeType'] == 'muffin', 1, 2) # 标签
"""
个体适应值计算
"""
x1 = ind_var[0]
x2 = ind_var[1]
x3 = ind_var[2]
if x1 == 0: x1 = 0.001
if x2 == 0: x2 = 0.001
if x3 == 0: x3 = 0.001
clf = svm.SVC(C=x1, degree=x2, gamma=x3,probability=True)
clf.fit(x_train, y_train)
y_pred = clf.predict(x_test) # 预测类别
print("true = ",len(np.where(y_pred == y_test)[0]) / len(y_test) * 100)
print("R2 = ", metrics.r2_score(y_test, y_pred)) # R2
return len(np.where(y_pred == y_test)[0]) / len(y_test) * 100
def update_operator(self, pop_size):
"""
更新算子:更新下一时刻的位置和速度
"""
c1 = 2 # 学习因子,一般为2
c2 = 2
w = 0.4 # 自身权重因子
for i in range(pop_size):
# 更新速度
self.pop_v[i] = w * self.pop_v[i] + c1 * random.uniform(0, 1) * (
self.p_best[i] - self.pop_x[i]) + c2 * random.uniform(0, 1) * (self.g_best - self.pop_x[i])
# 更新位置
self.pop_x[i] = self.pop_x[i] + self.pop_v[i]
# 越界保护
for j in range(self.var_num):
if self.pop_x[i][j] < self.bound[0][j]:
self.pop_x[i][j] = self.bound[0][j]
if self.pop_x[i][j] > self.bound[1][j]:
self.pop_x[i][j] = self.bound[1][j]
# 更新p_best和g_best
if self.fitness(self.pop_x[i]) > self.fitness(self.p_best[i]):
self.p_best[i] = self.pop_x[i]
if self.fitness(self.pop_x[i]) > self.fitness(self.g_best):
self.g_best = self.pop_x[i]
def main(self):
popobj = []
self.ng_best = np.zeros((1, self.var_num))[0]
for gen in range(self.NGEN):
self.update_operator(self.pop_size)
popobj.append(self.fitness(self.g_best))
print('############ Generation {} ############'.format(str(gen + 1)))
if self.fitness(self.g_best) > self.fitness(self.ng_best):
self.ng_best = self.g_best.copy()
print('最好的位置:{}'.format(self.ng_best))
print('最大的函数值:{}'.format(self.fitness(self.ng_best)))
print("---- End of (successful) Searching ----")
# plt.figure()
# fig = plt.gcf()
# fig.set_size_inches(18.5, 10.5)
# plt.title("Figure1")
# plt.xlabel("iterators", size=14)
# plt.ylabel("fitness", size=14)
# t = [t for t in range(self.NGEN)]
# plt.plot(t, popobj, color='b', linewidth=2)
# plt.show()
plt.figure()
plt.title("PSO-SVM")
plt.xlabel("GENS", size=14)
plt.ylabel("R2", size=14)
t = [t for t in range(self.NGEN)]
plt.plot(t, popobj, 'b', linewidth=2)
plt.show()
if __name__ == '__main__':
NGEN = 10
popsize = 5
#C【0.0001,200】gamma【0.0001,50】
low = [0.0001,3,0.0001]
up = [200,3,50]
parameters = [NGEN, popsize, low, up]
pso = PSO(parameters)
pso.main()
cs优化svc
# -*- coding: utf-8 -*-
"""
Created on Fri May 6 11:23:08 2022
@author: 工作站1
"""
import time
from random import uniform
from random import randint
import math
from sklearn.svm import SVC
import numpy as np
import random
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.metrics import explained_variance_score
from sklearn import svm
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import explained_variance_score
from sklearn import metrics
from sklearn.metrics import mean_absolute_error # 平方绝对误差
import random
import pandas as pd
# 根据levy飞行计算新的巢穴位置
def GetNewNestViaLevy(Xt, Xbest, Lb, Ub, lamuda):
beta = 1.5
sigma_u = (math.gamma(1 + beta) * math.sin(math.pi * beta / 2) / (
math.gamma((1 + beta) / 2) * beta * (2 ** ((beta - 1) / 2)))) ** (1 / beta)
sigma_v = 1
for i in range(Xt.shape[0]):
s = Xt[i, :]
u = np.random.normal(0, sigma_u, 1)
v = np.random.normal(0, sigma_v, 1)
Ls = u / ((abs(v)) ** (1 / beta))
stepsize = lamuda * Ls * (s - Xbest) # lamuda的设置关系到点的活力程度
s = s + stepsize * np.random.randn(1, len(s)) # 产生满足正态分布的序列
Xt[i, :] = s
Xt[i, :] = simplebounds(s, Lb, Ub)
return Xt
# 按pa抛弃部分巢穴
def empty_nests(nest, Lb, Ub, pa):
n = nest.shape[0]
nest1 = nest.copy()
nest2 = nest.copy()
rand_m = pa - np.random.rand(n, nest.shape[1])
rand_m = np.heaviside(rand_m, 0)
np.random.shuffle(nest1)
np.random.shuffle(nest2)
# stepsize = np.random.rand(1,1) * (nest1 - nest)
stepsize = np.random.rand(1, 1) * (nest1 - nest2)
new_nest = nest + stepsize * rand_m
nest = simplebounds(new_nest, Lb, Ub)
return nest
# 获得最优解
def get_best_nest(nest, newnest, Nbest, nest_best):
fitall = 0
for i in range(nest.shape[0]):
temp1 = fitness(nest[i, :])
temp2 = fitness(newnest[i, :])
if temp1 > temp2:
nest[i, :] = newnest[i, :]
if temp2 < Nbest:
Nbest = temp2
nest_best = nest[i, :]
fitall = fitall + temp2
else:
fitall = fitall + temp1
meanfit = fitall / nest.shape[0]
return nest, Nbest, nest_best, meanfit
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\cupcake or muffin.xlsx"
data2 = pd.read_excel(path)
x_train = np.array(list(zip(data2.Sugar, data2.Butter))) # 数据
y_train = np.where(data2['CakeType'] == 'muffin', 1, 2) # 标签
path = "C:\\Users\\孙海涛\\Desktop\\SVM分类练习数据集\\pred.xlsx"
data1 = pd.read_excel(path)
x_test = np.array(list(zip(data1.Sugar, data1.Butter))) # 需要预测的数据
y_test = np.where(data1['CakeType'] == 'muffin', 1, 2) # 标签
# 定义适应度函数
def fitness(nest_n):
"""
个体适应值计算
"""
x1 = nest_n[0]
x2 = nest_n[1]
clf = svm.SVC(C=x1, gamma=x2, probability=True)
clf.fit(x_train, y_train)
y_pred = clf.predict(x_test) # 预测类别
print("true = ", len(np.where(y_pred == y_test)[0]) / len(y_test) * 100)
return 1 -len(np.where(y_pred == y_test)[0]) / len(y_test) * 100
# 边界限制
def simplebounds(s, Lb, Ub):
for i in range(s.shape[0]):
for j in range(s.shape[1]):
if s[i][j] < Lb[j]:
s[i][j] = Lb[j]
if s[i][j] > Ub[j]:
s[i][j] = Ub[j]
return s
def Get_CS(lamuda=1, pa=0.25):
# C【0.0001,200】gamma【0.0001,50】
Lb = [0.0001, 0.0001] # 下界
Ub = [200, 50] # 上界
population_size = 5 #种群数量
dim = 2 #维度
nest = np.random.uniform(Lb[0], Ub[0], (population_size, dim)) # 初始化位置
nest_best = nest[0, :]
Nbest = fitness(nest_best)
nest, Nbest, nest_best, fitmean = get_best_nest(nest, nest, Nbest, nest_best)
F = []
#迭代次数
for i in range(5):
nest_c = nest.copy()
newnest = GetNewNestViaLevy(nest_c, nest_best, Lb, Ub, lamuda) # 根据莱维飞行产生新的位置
nest, Nbest, nest_best, fitmean = get_best_nest(nest, newnest, Nbest, nest_best) # 判断新的位置优劣进行替换
nest_e = nest.copy()
newnest = empty_nests(nest_e, Lb, Ub, pa) # 丢弃部分巢穴
nest, Nbest, nest_best, fitmean = get_best_nest(nest, newnest, Nbest, nest_best) # 再次判断新的位置优劣进行替换
F.append(1 - Nbest)
print("最优解的适应度函数值", 1 - Nbest)
print('最优参数组合', nest_best)
# 画迭代图
plt.figure()
plt.xlabel("GENS")
plt.ylabel("R2")
t = [t for t in range(1, 6)]
plt.plot(t, F)
plt.xticks(size=15)
plt.yticks(size=15)
plt.show()
return Nbest
if __name__ == "__main__":
Get_CS(1, 0.25)