【python】布谷鸟搜索算法cs、粒子群优化算法pso优化支持向量机分类算法svc,pr曲线输出


需求

用布谷鸟搜索算法cs、粒子群优化算法pso优化svm分类,并进行pr曲线输出

数据集–pred.xlsx

在这里插入图片描述

数据集–cupcake or muffin.xlsx

在这里插入图片描述

算法介绍

布谷鸟搜索算法cs

布谷鸟搜索算法是一种基于鸟类觅食行为的启发式搜索算法,通过模拟布谷鸟在树林中觅食的行为,来寻找最优解。

优点

  1. 高效性:布谷鸟搜索算法通过利用鸟类觅食的行为,将搜索空间划分为不同的领域,并根据领域内的信息指导搜索方向,提高搜索效率。
  2. 自适应性:布谷鸟搜索算法具有自适应性,能够根据搜索过程中的反馈信息调整搜索的策略,从而适应不同的问题类型和搜索空间。
  3. 算法简单:布谷鸟搜索算法的核心思想简单易懂,实现起来相对较简单。

缺点

  1. 参数选择:布谷鸟搜索算法中存在一些参数,如觅食成功率、搜索半径等,需要根据具体问题进行调整,选择合适的参数可能需要一定的经验和试验。
  2. 局部最优解:布谷鸟搜索算法可能陷入局部最优解,而难以跳出。虽然可以通过随机扰动等方式,增加跳出局部最优解的机会,但仍然存在一定的概率陷入局部最优解。
  3. 启发式搜索能力有限:布谷鸟搜索算法在处理复杂问题时,可能由于搜索空间过大或问题结构复杂,导致搜索效果不佳。

粒子群优化算法pso

粒子群优化算法是一种基于群体智能的优化算法,它模拟了鸟群或鱼群的行为,通过多个个体(粒子)之间的协作和信息交流来优化问题。

优点

  1. 算法简单,易于实现和理解。PSO算法的原理较为直观,基本流程简单,容易理解和编写代码实现。
  2. 全局搜索能力较强。PSO算法通过粒子之间的信息交流和协作来寻找全局最优解,从而可以在复杂的搜索空间中找到全局最优解。
  3. 收敛速度快。由于群体智能的机制,粒子可以通过相互协作和信息交流来引导搜索,因此PSO算法的收敛速度较快。
  4. 对于多目标优化问题有较好的适应性。PSO算法可以通过修改适应度函数的方式来适应多目标优化问题,并搜索多个最优解。

缺点

  1. 对初始参数和控制参数敏感。初始参数和控制参数的选择对PSO算法的性能有很大影响,不合适的参数选择可能导致算法陷入局部最优解或者收敛速度过慢。
  2. 缺乏对搜索空间的探索能力。PSO算法主要通过粒子之间的信息交流和协作来搜索最优解,但对于搜索空间的探索能力相对较弱,容易陷入局部最优解。
  3. 算法存在早熟收敛问题。由于算法的全局搜索能力较强,当算法开始收敛时,粒子往往会聚集在某一区域,导致算法早熟收敛,无法进一步搜索更好的解。

支持向量机分类svc

支持向量机分类算法是一种常用的分类算法,主要思想是通过找到最大间隔来实现分类,使得不同类别的数据点能够尽可能地被分开。

优点

  1. 在处理高维数据时表现较好:支持向量机通过引入核函数可以将原始特征映射到高维空间,从而使得数据在高维空间中更容易分离。
  2. 样本量较小时仍能表现良好:SVC通过寻找最优超平面来进行分类,在样本量较小时也能保持较好的泛化性能。
  3. 可处理非线性问题:通过使用非线性核函数,SVC可以处理非线性问题,如多项式核函数、高斯核函数等。
  4. 结果具有较好的泛化能力:SVC通过最大化分类间隔来进行分类,可以有效避免过拟合问题,具有较好的泛化能力。

缺点

  1. 计算复杂度较高:SVC在训练时需要解优化问题,计算复杂度较高,特别是对于大规模数据集而言。
  2. 对于噪声敏感:SVC对于噪声敏感,噪声会对最大间隔超平面的确定产生影响,从而影响分类结果。
  3. 对缺失数据敏感:SVC对于缺失数据敏感,缺失数据的处理需要额外的步骤。
  4. 参数选择较为困难:SVC的性能很大程度上依赖于选择合适的参数,例如核函数类型、核函数参数等,参数选择较为困难。
  5. 只适用于二分类问题:原始的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)




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傻傻虎虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值