Python实现遗传算法(GA)+支持向量回归机(SVR)

本实验使用环境为Anaconda3 Jupyter,调用Sklearn包,请提前准备好。

1.引入一些常见包

主要包含pandas、numpy、绘图包、SVR、标准化、验证函数等包。

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.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
import time
from sklearn import metrics
import csv
from sklearn.svm import SVR
import matplotlib.pyplot as plt  

2.引入数据

将准备好的CSV文件导入,将数据分为目标集和特征集,比如本文预测’土壤水分’,使用’土壤温度’,‘空气湿度’,‘空气温度’,'光照强度’作为特征。使用pands进行格式化显示。

#全部数据
data=[]
#特征集
traffic_feature=[]
#目标集
traffic_target=[]
#打开数据文件
csv_file = csv.reader(open('turang.csv'))
#遍历 格式设置为float
for content in csv_file:
    content=list(map(float,content))
    if len(content)!=0:
        data.append(content)
        traffic_feature.append(content[0:4])
        traffic_target.append(content[-1])
#将数据变成np.array的格式
data=np.array(data)
traffic_feature=np.array(traffic_feature)
traffic_target=np.array(traffic_target)
#更直观的观察数据,本文中没有太多用途
df=pd.DataFrame(data=data,columns = ['土壤温度','空气湿度','空气温度','光照强度','土壤水分'])

数据最终样子 输入df即可查看
在这里插入图片描述
目标值图:
(噪音有点大…先将就用吧 - -!!,以后我会写一篇数据降噪的文章)

plt.plot(traffic_target)#测试数组
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.show()

在这里插入图片描述

3.数据标准化

使用StandardScaler()方法将数据标准化归一化。

scaler = StandardScaler() # 标准化转换
scaler.fit(traffic_feature)  # 训练标准化对象
traffic_feature= scaler.transform(traffic_feature)   # 转换数据集

标准化前:
在这里插入图片描述
标准化后:
在这里插入图片描述

4.使用支持向量回归机(SVR)

先将数据随机90%做测试集,剩下10%当验证集,随机种子任意设置。本文采取随机抽取形式,而不是时间序列。如使用时间序列预测,请将特征集和目标集的后10%留出来,做为验证集。同理如单步时间序列与从,则保留最后一行作为验证集。
如:

feature_test=traffic_feature[int(len(traffic_feature)*0.9):int(len(traffic_feature))]
target_test=traffic_target[int(len(traffic_target)*0.9):int(len(traffic_target))]

使用SVR(),参数默认,使用R方、EVS、时间作为评价指标。

feature_train,feature_test,target_train, target_test = train_test_split(traffic_feature,traffic_target,test_size=0.1,random_state=10)

start1=time.time()
model_svr = SVR()
model_svr.fit(feature_train,target_train)
predict_results1=model_svr.predict(feature_test)
end1=time.time()

plt.plot(target_test)#测试数组
plt.plot(predict_results1)#测试数组
plt.legend(['True','SVR'])
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.title("SVR")  # 标题
plt.show()
print("EVS:",explained_variance_score(target_test,predict_results1))
print("R2:",metrics.r2_score(target_test,predict_results1))
print("Time:",end1-start1)

结果:
看的出来,随机抽取的精度不高,R方只有区区0.54。(废话,噪音那么大,精度能高吗…)
在这里插入图片描述
时间序列预测结果更离谱,我就不放图了。

5.使用GA算法对SVR进行调参

对SVR参数的惩罚参数C、损失函数epsilon、核系数gamma进行调参,设置其范围为[0,10]、[0,2]、[0,100],可以自行设置。一共20代,每代10人,可以自行设置。
GA算法简单来说,就是每一代人都会有人基因突变,基因突变如果效果很好,适应度很高,那么其他人也会向其进化。
上代码:

#设置适应度,这里设置为R2
def msefunc(predictval,realval):
    print("R2 = ",metrics.r2_score(realval,predictval)) # R2
    return metrics.r2_score(realval,predictval)
 #设置优化函数,这里为SVR,参数在此绑定,使用验证集输入验证得出适应度
def SVMResult(vardim, x, bound):
    X = feature_train.tolist()
    y = target_train.tolist()
    c=x[0]
    e=x[1]
    g=x[2]
    clf = SVR(C=c,epsilon=e,gamma=g)
    clf.fit(X, y)
    predictval=clf.predict(feature_test.tolist())
    return msefunc(predictval,target_test.tolist())
class GAIndividual:
 
    '''
    individual of genetic algorithm
    '''
 
    def __init__(self,  vardim, bound):
        '''
        vardim: dimension of variables
        bound: boundaries of variables
        '''
        self.vardim = vardim
        self.bound = bound
        self.fitness = 0.
 
    def generate(self):
        '''
        generate a random chromsome for genetic algorithm
        '''
        len = self.vardim
        rnd = np.random.random(size=len)
        self.chrom = np.zeros(len)
        for i in range(0, len):
            self.chrom[i] = self.bound[0, i] + \
                (self.bound[1, i] - self.bound[0, i]) * rnd[i]
 
    def calculateFitness(self):
        '''
        calculate the fitness of the chromsome
        '''
        self.fitness = SVMResult(self.vardim, self.chrom, self.bound)
        
import random
import copy

 
class GeneticAlgorithm:
 
    '''
    The class for genetic algorithm
    '''
 
    def __init__(self, sizepop, vardim, bound, MAXGEN, params):
        '''
        sizepop: population sizepop人口规模
        vardim: dimension of variables变量维数
        bound: boundaries of variables变量边界
        MAXGEN: termination condition终止条件
        param: algorithm required parameters, it is a list which is consisting of crossover rate, mutation rate, alpha
        '''
        self.sizepop = sizepop
        self.MAXGEN = MAXGEN
        self.vardim = vardim
        self.bound = bound
        self.population = []
        self.fitness = np.zeros((self.sizepop, 1))
        self.trace = np.zeros((self.MAXGEN, 3))
        self.params = params
 
    def initialize(self):
        '''
        initialize the population
        '''
        for i in range(0, self.sizepop):
            ind = GAIndividual(self.vardim, self.bound)
            ind.generate()
            self.population.append(ind)
 
    def evaluate(self):
        '''
        evaluation of the population fitnesses
        '''
        for i in range(0, self.sizepop):
            self.population[i].calculateFitness()
            self.fitness[i] = self.population[i].fitness
 
    def solve(self):
        '''
        evolution process of genetic algorithm
        '''
        self.t = 0
        self.initialize()
        self.evaluate()
        best = np.max(self.fitness)
        bestIndex = np.argmax(self.fitness)
        self.best = copy.deepcopy(self.population[bestIndex])
        self.avefitness = np.mean(self.fitness)
        self.maxfitness = np.max(self.fitness)
        
        self.trace[self.t, 0] =  self.best.fitness
        self.trace[self.t, 1] =  self.avefitness
        self.trace[self.t, 2] =  self.maxfitness
        print("Generation %d: optimal function value is: %f; average function value is %f;max function value is %f"% (
            self.t, self.trace[self.t, 0], self.trace[self.t, 1],self.trace[self.t, 2]))
        while (self.t < self.MAXGEN - 1):
            self.t += 1
            self.selectionOperation()
            self.crossoverOperation()
            self.mutationOperation()
            self.evaluate()
            best = np.max(self.fitness)
            bestIndex = np.argmax(self.fitness)
            if best > self.best.fitness:
                self.best = copy.deepcopy(self.population[bestIndex])
            self.avefitness = np.mean(self.fitness)
            self.maxfitness = np.max(self.fitness)
            
            self.trace[self.t, 0] =  self.best.fitness
            self.trace[self.t, 1] = self.avefitness
            self.trace[self.t, 2] =  self.maxfitness
            print("Generation %d: optimal function value is: %f; average function value is %f;max function value is %f"% (
            self.t, self.trace[self.t, 0], self.trace[self.t, 1],self.trace[self.t, 2]))
 
        print("Optimal function value is: %f; " %
              self.trace[self.t, 0])
        print ("Optimal solution is:")
        print (self.best.chrom)
        self.printResult()
 
    def selectionOperation(self):
        '''
        selection operation for Genetic Algorithm
        '''
        newpop = []
        totalFitness = np.sum(self.fitness)
        accuFitness = np.zeros((self.sizepop, 1))
 
        sum1 = 0.
        for i in range(0, self.sizepop):
            accuFitness[i] = sum1 + self.fitness[i] / totalFitness
            sum1 = accuFitness[i]
 
        for i in range(0, self.sizepop):
            r = random.random()
            idx = 0
            for j in range(0, self.sizepop - 1):
                if j == 0 and r < accuFitness[j]:
                    idx = 0
                    break
                elif r >= accuFitness[j] and r < accuFitness[j + 1]:
                    idx = j + 1
                    break
            newpop.append(self.population[idx])
        self.population = newpop
 
    def crossoverOperation(self):
        '''
        crossover operation for genetic algorithm
        '''
        newpop = []
        for i in range(0, self.sizepop, 2):
            idx1 = random.randint(0, self.sizepop - 1)
            idx2 = random.randint(0, self.sizepop - 1)
            while idx2 == idx1:
                idx2 = random.randint(0, self.sizepop - 1)
            newpop.append(copy.deepcopy(self.population[idx1]))
            newpop.append(copy.deepcopy(self.population[idx2]))
            r = random.random()
            if r < self.params[0]:
                crossPos = random.randint(1, self.vardim - 1)
                for j in range(crossPos, self.vardim):
                    newpop[i].chrom[j] = newpop[i].chrom[
                        j] * self.params[2] + (1 - self.params[2]) * newpop[i + 1].chrom[j]
                    newpop[i + 1].chrom[j] = newpop[i + 1].chrom[j] * self.params[2] + \
                        (1 - self.params[2]) * newpop[i].chrom[j]
        self.population = newpop
 
    def mutationOperation(self):
        '''
        mutation operation for genetic algorithm
        '''
        newpop = []
        for i in range(0, self.sizepop):
            newpop.append(copy.deepcopy(self.population[i]))
            r = random.random()
            if r < self.params[1]:
                mutatePos = random.randint(0, self.vardim - 1)
                theta = random.random()
                if theta > 0.5:
                    newpop[i].chrom[mutatePos] = newpop[i].chrom[
                        mutatePos] - (newpop[i].chrom[mutatePos] - self.bound[0, mutatePos]) * (1 - random.random() ** (1 - self.t / self.MAXGEN))
                else:
                    newpop[i].chrom[mutatePos] = newpop[i].chrom[
                        mutatePos] + (self.bound[1, mutatePos] - newpop[i].chrom[mutatePos]) * (1 - random.random() ** (1 - self.t / self.MAXGEN))
        self.population = newpop
 
    def printResult(self):
        '''
        plot the result of the genetic algorithm
        '''
        x = np.arange(0, self.MAXGEN)
        y1 = self.trace[:, 0]
        y2 = self.trace[:, 1]
        y3 = self.trace[:, 2]
        #plt.plot(x, y1, 'r', label='optimal value')
        plt.plot(x, y2, 'g', label='average value')
        plt.plot(x, y3, 'b', label='max value')
        fig = plt.gcf()
        fig.set_size_inches(18.5, 10.5)
        plt.xlabel("GENS")
        plt.ylabel("R2")
        plt.title("GA")
        plt.legend()
        plt.show()       

开跑开跑!

if __name__ == "__main__":
   bound = np.array([[0,0,0],[10,2,100]])
   ga = GeneticAlgorithm(10, 3, bound, 20, [0.9, 0.1, 0.5])
   ga.solve()

结果:
图不是很好看,GA确实容易陷入局部极值。
c、e、g等与[ 9.93055626 0.28102442 24.58580654]
在这里插入图片描述

6.融合GA-SVR模型

from sklearn.svm import SVR
import matplotlib.pyplot as plt  
start1=time.time()
model_svr = SVR(C=9.93055626,epsilon=0.28102442,gamma=24.58580654)
model_svr.fit(feature_train,target_train)
predict_results1=model_svr.predict(feature_test)
end1=time.time()

plt.plot(target_test)#测试数组
plt.plot(predict_results1)#测试数组
plt.legend(['True','SVR'])
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.title("SVR")  # 标题
plt.show()
print("EVS:",explained_variance_score(target_test,predict_results1))
print("R2:",metrics.r2_score(target_test,predict_results1))
print("Time:",end1-start1)

结果如下:

时间虽然增大,但R方和EVS均有较大提升。

  • 44
    点赞
  • 270
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
粒子群算法(PSO)和支持向量回归(SVR)都是常见的器学习算法,可以用Python实现。 粒子群算法是一种优化算法,通过模拟鸟群等自然现象来寻找问题的最优解。它的核心原理是粒子根据自身经验和邻居经验来更新自身的位置和速度,以迭代的方式搜索最优解。在Python中,我们可以使用numpy或者其他优化库来实现PSO算法支持向量回归是一种基于支持向量回归算法,它通过在特征空间中找到一个最优的超平面来进行回归预测。与普通的回归方法相比,SVR考虑到了数据的噪声和异常值,并使用支持向量的核函数来对数据进行转换。在Python中,我们可以使用scikit-learn库来实现SVR算法。 以下是一个简单的Python代码示例,展示了如何使用numpy和scikit-learn实现PSO和SVR算法: ```python import numpy as np from sklearn.svm import SVR # 粒子群算法实现 def pso(): # 初始化粒子位置和速度 # 粒子的位置表示超参数,速度表示搜索方向和强度 # 粒子个体和全局最优位置需要根据问题来定义 # 粒子更新的逻辑也需要根据问题来定义 pass # 支持向量回归实现 def svr(X, y): # 初始化SVR模型 svr_model = SVR() # 训练SVR模型 svr_model.fit(X, y) # 使用SVR模型进行预测 y_pred = svr_model.predict(X) return y_pred # 测试数据 X = np.array([[1, 2], [3, 4], [5, 6]]) y = np.array([1, 2, 3]) # 实现PSO算法 pso() # 实现SVR算法 y_pred = svr(X, y) print(y_pred) ``` 以上代码只是一个简单示例,实际的PSO和SVR算法需要根据具体问题进行适当的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值