【預(yù)測模型】基于遺傳算法優(yōu)化BP神經(jīng)網(wǎng)絡(luò)房價(jià)預(yù)測matlab源碼
一、簡介
1 遺傳算法概述
遺傳算法(Genetic Algorithm,GA)是進(jìn)化計(jì)算的一部分,是模擬達(dá)爾文的遺傳選擇和自然淘汰的生物進(jìn)化過程的計(jì)算模型,是一種通過模擬自然進(jìn)化過程搜索最優(yōu)解的方法。該算法簡單、通用,魯棒性強(qiáng),適于并行處理。
2 遺傳算法的特點(diǎn)和應(yīng)用
遺傳算法是一類可用于復(fù)雜系統(tǒng)優(yōu)化的具有魯棒性的搜索算法,與傳統(tǒng)的優(yōu)化算法相比,具有以下特點(diǎn):
(1)以決策變量的編碼作為運(yùn)算對象。傳統(tǒng)的優(yōu)化算法往往直接利用決策變量的實(shí)際值本身來進(jìn)行優(yōu)化計(jì)算,但遺傳算法是使用決策變量的某種形式的編碼作為運(yùn)算對象。這種對決策變量的編碼處理方式,使得我們在優(yōu)化計(jì)算中可借鑒生物學(xué)中染色體和基因等概念,可以模仿自然界中生物的遺傳和進(jìn)化激勵(lì),也可以很方便地應(yīng)用遺傳操作算子。
(2)直接以適應(yīng)度作為搜索信息。傳統(tǒng)的優(yōu)化算法不僅需要利用目標(biāo)函數(shù)值,而且搜索過程往往受目標(biāo)函數(shù)的連續(xù)性約束,有可能還需要滿足“目標(biāo)函數(shù)的導(dǎo)數(shù)必須存在”的要求以確定搜索方向。遺傳算法僅使用由目標(biāo)函數(shù)值變換來的適應(yīng)度函數(shù)值就可確定進(jìn)一步的搜索范圍,無需目標(biāo)函數(shù)的導(dǎo)數(shù)值等其他輔助信息。直接利用目標(biāo)函數(shù)值或個(gè)體適應(yīng)度值也可以將搜索范圍集中到適應(yīng)度較高部分的搜索空間中,從而提高搜索效率。
(3)使用多個(gè)點(diǎn)的搜索信息,具有隱含并行性。傳統(tǒng)的優(yōu)化算法往往是從解空間的一個(gè)初始點(diǎn)開始最優(yōu)解的迭代搜索過程。單個(gè)點(diǎn)所提供的搜索信息不多,所以搜索效率不高,還有可能陷入局部最優(yōu)解而停滯;遺傳算法從由很多個(gè)體組成的初始種群開始最優(yōu)解的搜索過程,而不是從單個(gè)個(gè)體開始搜索。對初始群體進(jìn)行的、選擇、交叉、變異等運(yùn)算,產(chǎn)生出新一代群體,其中包括了許多群體信息。這些信息可以避免搜索一些不必要的點(diǎn),從而避免陷入局部最優(yōu),逐步逼近全局最優(yōu)解。
(4) 使用概率搜索而非確定性規(guī)則。傳統(tǒng)的優(yōu)化算法往往使用確定性的搜索方法,一個(gè)搜索點(diǎn)到另一個(gè)搜索點(diǎn)的轉(zhuǎn)移有確定的轉(zhuǎn)移方向和轉(zhuǎn)移關(guān)系,這種確定性可能使得搜索達(dá)不到最優(yōu)店,限制了算法的應(yīng)用范圍。遺傳算法是一種自適應(yīng)搜索技術(shù),其選擇、交叉、變異等運(yùn)算都是以一種概率方式進(jìn)行的,增加了搜索過程的靈活性,而且能以較大概率收斂于最優(yōu)解,具有較好的全局優(yōu)化求解能力。但,交叉概率、變異概率等參數(shù)也會(huì)影響算法的搜索結(jié)果和搜索效率,所以如何選擇遺傳算法的參數(shù)在其應(yīng)用中是一個(gè)比較重要的問題。
綜上,由于遺傳算法的整體搜索策略和優(yōu)化搜索方式在計(jì)算時(shí)不依賴于梯度信息或其他輔助知識(shí),只需要求解影響搜索方向的目標(biāo)函數(shù)和相應(yīng)的適應(yīng)度函數(shù),所以遺傳算法提供了一種求解復(fù)雜系統(tǒng)問題的通用框架。它不依賴于問題的具體領(lǐng)域,對問題的種類有很強(qiáng)的魯棒性,所以廣泛應(yīng)用于各種領(lǐng)域,包括:函數(shù)優(yōu)化、組合優(yōu)化生產(chǎn)調(diào)度問題、自動(dòng)控制
、機(jī)器人學(xué)、圖像處理(圖像恢復(fù)、圖像邊緣特征提取…)、人工生命、遺傳編程、機(jī)器學(xué)習(xí)。
3 遺傳算法的基本流程及實(shí)現(xiàn)技術(shù)
基本遺傳算法(Simple Genetic Algorithms,SGA)只使用選擇算子、交叉算子和變異算子這三種遺傳算子,進(jìn)化過程簡單,是其他遺傳算法的基礎(chǔ)。
3.1 遺傳算法的基本流程
通過隨機(jī)方式產(chǎn)生若干由確定長度(長度與待求解問題的精度有關(guān))編碼的初始群體;
通過適應(yīng)度函數(shù)對每個(gè)個(gè)體進(jìn)行評價(jià),選擇適應(yīng)度值高的個(gè)體參與遺傳操作,適應(yīng)度低的個(gè)體被淘汰;
經(jīng)遺傳操作(復(fù)制、交叉、變異)的個(gè)體集合形成新一代種群,直到滿足停止準(zhǔn)則(進(jìn)化代數(shù)GEN>=?);
將后代中變現(xiàn)最好的個(gè)體作為遺傳算法的執(zhí)行結(jié)果。

其中,GEN是當(dāng)前代數(shù);M是種群規(guī)模,i代表種群數(shù)量。
3.2 遺傳算法的實(shí)現(xiàn)技術(shù)
基本遺傳算法(SGA)由編碼、適應(yīng)度函數(shù)、遺傳算子(選擇、交叉、變異)及運(yùn)行參數(shù)組成。
3.2.1 編碼
(1)二進(jìn)制編碼
二進(jìn)制編碼的字符串長度與問題所求解的精度有關(guān)。需要保證所求解空間內(nèi)的每一個(gè)個(gè)體都可以被編碼。
優(yōu)點(diǎn):編、解碼操作簡單,遺傳、交叉便于實(shí)現(xiàn)
缺點(diǎn):長度大
(2)其他編碼方法
格雷碼、浮點(diǎn)數(shù)編碼、符號(hào)編碼、多參數(shù)編碼等
3.2.2 適應(yīng)度函數(shù)
適應(yīng)度函數(shù)要有效反映每一個(gè)染色體與問題的最優(yōu)解染色體之間的差距。
3.2.3選擇算子

3.2.4 交叉算子
交叉運(yùn)算是指對兩個(gè)相互配對的染色體按某種方式相互交換其部分基因,從而形成兩個(gè)新的個(gè)體;交叉運(yùn)算是遺傳算法區(qū)別于其他進(jìn)化算法的重要特征,是產(chǎn)生新個(gè)體的主要方法。在交叉之前需要將群體中的個(gè)體進(jìn)行配對,一般采取隨機(jī)配對原則。
常用的交叉方式:
單點(diǎn)交叉
雙點(diǎn)交叉(多點(diǎn)交叉,交叉點(diǎn)數(shù)越多,個(gè)體的結(jié)構(gòu)被破壞的可能性越大,一般不采用多點(diǎn)交叉的方式)
均勻交叉
算術(shù)交叉
3.2.5 變異算子
遺傳算法中的變異運(yùn)算是指將個(gè)體染色體編碼串中的某些基因座上的基因值用該基因座的其他等位基因來替換,從而形成一個(gè)新的個(gè)體。
就遺傳算法運(yùn)算過程中產(chǎn)生新個(gè)體的能力方面來說,交叉運(yùn)算是產(chǎn)生新個(gè)體的主要方法,它決定了遺傳算法的全局搜索能力;而變異運(yùn)算只是產(chǎn)生新個(gè)體的輔助方法,但也是必不可少的一個(gè)運(yùn)算步驟,它決定了遺傳算法的局部搜索能力。交叉算子與變異算子的共同配合完成了其對搜索空間的全局搜索和局部搜索,從而使遺傳算法能以良好的搜索性能完成最優(yōu)化問題的尋優(yōu)過程。
3.2.6 運(yùn)行參數(shù)

4 遺傳算法的基本原理
4.1 模式定理

4.2 積木塊假設(shè)
具有低階、定義長度短,且適應(yīng)度值高于群體平均適應(yīng)度值的模式稱為基因塊或積木塊。
積木塊假設(shè):個(gè)體的基因塊通過選擇、交叉、變異等遺傳算子的作用,能夠相互拼接在一起,形成適應(yīng)度更高的個(gè)體編碼串。
積木塊假設(shè)說明了用遺傳算法求解各類問題的基本思想,即通過積木塊直接相互拼接在一起能夠產(chǎn)生更好的解。
二、源代碼
clear all
clc
close all
tic
%% 全局變量
global pn
global tn
global R
global S2
global S1
global S
S1 = 12;
%% 數(shù)據(jù)處理
%% 數(shù)據(jù)處理
data1 =xlsread('數(shù)據(jù).xls');%導(dǎo)入數(shù)據(jù)
%% 訓(xùn)練數(shù)據(jù)
input = data1(1:9,2:7);%訓(xùn)練輸入
output = data1(1:9,8);%訓(xùn)練輸出
input_test = data1(10:end,2:7);%測試輸入
output_test= data1(10:end,end);%測試輸出
output_test = ? ?output_test';
M =size(input,2); %輸入節(jié)點(diǎn)個(gè)數(shù)
N =size(output,2);%輸出節(jié)點(diǎn)個(gè)數(shù)
%% 訓(xùn)練數(shù)據(jù)
p = input';
t = output';
[pn,minp,maxp,tn,mint,maxt] =premnmx(p,t);%歸一化
%% 建立神經(jīng)網(wǎng)絡(luò)
net = newff(minmax(pn),[S1,1],{'tansig','purelin'});
net.trainParam.show = 50;
net.trainParam.lr = 0.1;
net.trainParam.epochs = 1000;
net.trainParam.goal =1e-10;
[net,tr] = train(net,pn,tn);
%% 遺傳操作
R = size(p,1);
S2= size(t,1);
S = R*S1+S1*S2+S1+S2;
aa = ones(S,1)*[-1 1];
popu = 50;
initPpp = initializega(popu,aa,'gabpEval');
gen = 500;
[x,endPop,bPop,trace] = ga(aa,'gabpEval',[],initPpp,[1e-6 1 1],'maxGenTerm',gen,...
? ?'normGeomSelect',[0.09],['arithXover'],[2],'nonUnifMutation',[2 gen 3]);
%% 畫圖迭代圖
figure(1)
plot(trace(:,1),1./trace(:,3),'r-');
hold on
grid on
plot(trace(:,1),1./trace(:,2),'b-');
xlabel('迭代數(shù)')
ylabel('均方誤差')
title('均方誤差曲線圖')
figure(2)
plot(trace(:,1),trace(:,3),'r-');
hold on
grid on
plot(trace(:,1),trace(:,2),'b-');
xlabel('迭代數(shù)')
ylabel('適應(yīng)度函數(shù)值')
title('適應(yīng)度函數(shù)迭代曲線圖')
[W1,B1,W2,B2,val] = gadecod(x);
W1;
W2;
B1;
B2;
net.IW{1,1} = W1;
net.LW{2,1} = W2;
net.b{1} = B1;
net.b{2} = B2;
net = train(net,pn,tn);
k = input_test';
kn = tramnmx(k,minp,maxp);
s_bp = sim(net,kn);
s_bp2 = postmnmx(s_bp,mint,maxt)
toc
warning off %清除警告
%% 數(shù)據(jù)處理
data1 =xlsread('數(shù)據(jù).xls');%導(dǎo)入數(shù)據(jù)
%% 訓(xùn)練數(shù)據(jù)
data_p = data1(1:9,2:7);%訓(xùn)練輸入
data_t = data1(1:9,8);%訓(xùn)練輸出
data_k = data1(10:end,2:7);%測試輸入
outtest = data1(10:end,end);%測試輸出
[m1,n1] = size(data_p);%訓(xùn)練數(shù)據(jù)的大小
[m2,n2] = size(data_t);%測試數(shù)據(jù)的大小
p = data_p';%轉(zhuǎn)置 適應(yīng)BP工具箱
t = data_t';%轉(zhuǎn)置 適應(yīng)BP工具箱
[pn,minp,maxp,tn,mint,maxt] = premnmx(p,t);%歸一化
k = data_k';%測試輸入裝置
kn = tramnmx(k,minp,maxp);%測試輸入歸一化
%% BP模型
%建立網(wǎng)絡(luò)及參數(shù)設(shè)置
S1 =10;%隱含層
net = newff(minmax(pn),[S1,1],{'tansig','purelin'});%建立網(wǎng)絡(luò)
inputWeights = net.IW{1,1};%輸入層到隱含層權(quán)值
inputbias = net.b{1};%輸入層到隱含層閥值
layerWeights = net.IW{2,1};%隱含層到輸出權(quán)值
layerbias = net.b{2};%隱含層到輸出閥值
net.trainParam.show = 50;%迭代顯示步數(shù)間隔 對結(jié)果無影響
net.trainParam.lr = 0.1;%學(xué)習(xí)率
net.trainParam.mc = 0.9;%動(dòng)量因子
net.trainParam.epochs = 10000;%最大迭代次數(shù)
net.trainParam.goal =0.00001;%訓(xùn)練目標(biāo)
%% 訓(xùn)練模型
[net,tr] = train(net,pn,tn);%訓(xùn)練網(wǎng)絡(luò)
nihe = sim(net,pn);%訓(xùn)練輸出
nihe2 = postmnmx(nihe,mint,maxt);%訓(xùn)練輸出反歸一化
figure%畫圖
xk = 2;%線寬
plot(2006:2014,nihe2,'r-o',2006:2014,data_t,'b.-','linewidth',xk)%訓(xùn)練輸出與擬合值的對比圖
grid on%網(wǎng)格
legend('真實(shí)值','預(yù)測值')%圖例
title('神經(jīng)網(wǎng)預(yù)測真實(shí)值與預(yù)測值對比')%標(biāo)題
xlabel('年份')%橫坐標(biāo)標(biāo)題
ylabel('商品房平均房價(jià)')%縱坐標(biāo)標(biāo)題
%% 預(yù)測
s_bp = sim(net,kn);%預(yù)測
s_bp2 = postmnmx(s_bp,mint,maxt);%預(yù)測輸出反歸一化
s_bp2 = s_bp2';%轉(zhuǎn)置
figure%畫圖
plot(2015:2017,outtest,'r-',2015:2017,s_bp2,'b.-','linewidth',xk)%測試輸出與真實(shí)值的對比圖
grid on%加網(wǎng)格
legend('真實(shí)值','預(yù)測值')%圖例
title('神經(jīng)網(wǎng)預(yù)測真實(shí)值與預(yù)測值對比')%標(biāo)題
xlabel('年份')%橫坐標(biāo)標(biāo)題
ylabel('商品房平均房價(jià)')%縱坐標(biāo)標(biāo)題
%% 誤差分析
三、運(yùn)行結(jié)果




?