當前位置:首頁 » 操作系統 » lw優化演算法

lw優化演算法

發布時間: 2023-08-14 22:47:36

『壹』 關於遺傳演算法優化BP神經網路的問題

程序:
1、未經遺傳演算法優化的BP神經網路建模
clear;
clc;
%%%%%%%%%%%%%輸入參數%%%%%%%%%%%%%%
N=2000; %數據總個數
M=1500; %訓練數據
%%%%%%%%%%%%%訓練數據%%%%%%%%%%%%%%
for i=1:N
input(i,1)=-5+rand*10;
input(i,2)=-5+rand*10;
end
output=input(:,1).^2+input(:,2).^2;
save data input output

load data.mat

%從1到N隨機排序
k=rand(1,N);
[m,n]=sort(k);
%找出訓練數據和預測數據
input_train=input(n(1:M),:)';
output_train=output(n(1:M),:)';
input_test=input(n((M+1):N),:)';
output_test=output(n((M+1):N),:)';
%數據歸一化
[inputn,inputs]=mapminmax(input_train);
[outputn,outputs]=mapminmax(output_train);
%構建BP神經網路
net=newff(inputn,outputn,5);
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
net.trainParam.goal=0.0000004;
%BP神經網路訓練
net=train(net,inputn,outputn);
%測試樣本歸一化
inputn_test=mapminmax('apply',input_test,inputs);
%BP神經網路預測
an=sim(net,inputn_test);
%%網路得到數據反歸一化
BPoutput=mapminmax('reverse',an,outputs);

figure(1)
%plot(BPoutput,':og');
scatter(1:(N-M),BPoutput,'rx');
hold on;
%plot(output_test,'-*');
scatter(1:(N-M),output_test,'o');
legend('預測輸出','期望輸出','fontsize',12);
title('BP網路預測輸出','fontsize',12);
xlabel('樣本','fontsize',12);
xlabel('優化前輸出的誤差','fontsize',12);

figure(2)
error=BPoutput-output_test;
plot(1:(N-M),error);
xlabel('樣本','fontsize',12);
ylabel('優化前輸出的誤差','fontsize',12);
%save net net inputs outputs
2、遺傳演算法優化的BP神經網路建模
(1)主程序
%清空環境變數
clc
clear

%讀取數據
load data.mat

%節點個數
inputnum=2;
hiddennum=5;
outputnum=1;

%訓練數據和預測數據
input_train=input(1:1500,:)';
input_test=input(1501:2000,:)';
output_train=output(1:1500)';
output_test=output(1501:2000)';

%選連樣本輸入輸出數據歸一化
[inputn,inputps]=mapminmax(input_train);
[outputn,outputps]=mapminmax(output_train);

%構建網路
net=newff(inputn,outputn,hiddennum);

%% 遺傳演算法參數初始化
maxgen=10; %進化代數,即迭代次數
sizepop=30; %種群規模
pcross=[0.3]; %交叉概率選擇,0和1之間
pmutation=[0.1]; %變異概率選擇,0和1之間

%節點總數
numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;

lenchrom=ones(1,numsum);
bound=[-3*ones(numsum,1) 3*ones(numsum,1)]; %數據范圍

%------------------------------------------------------種群初始化------------------------------%------------------

--------
indivials=struct('fitness',zeros(1,sizepop), 'chrom',[]); %將種群信息定義為一個結構體
%avgfitness=[]; %每一代種群的平均適應度
bestfitness=[]; %每一代種群的最佳適應度
bestchrom=[]; %適應度最好的染色體
%初始化種群
for i=1:sizepop
%隨機產生一個種群
indivials.chrom(i,:)=Code(lenchrom,bound); %編碼
x=indivials.chrom(i,:);
%計算適應度
indivials.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn); %染色體的適應度
end

%找最好的染色體
[bestfitness bestindex]=min(indivials.fitness);
bestchrom=indivials.chrom(bestindex,:); %最好的染色體
%avgfitness=sum(indivials.fitness)/sizepop; %染色體的平均適應度
% 記錄每一代進化中最好的適應度和平均適應度
%trace=[avgfitness bestfitness];

%% 迭代求解最佳初始閥值和權值
% 進化開始
for i=1:maxgen
i
% 選擇
indivials=Select(indivials,sizepop);
% avgfitness=sum(indivials.fitness)/sizepop;
%交叉
indivials.chrom=Cross(pcross,lenchrom,indivials.chrom,sizepop,bound);
% 變異
indivials.chrom=Mutation(pmutation,lenchrom,indivials.chrom,sizepop,i,maxgen,bound);

% 計算適應度
for j=1:sizepop
x=indivials.chrom(j,:); %解碼
indivials.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);
end

%找到最小和最大適應度的染色體及它們在種群中的位置
[newbestfitness,newbestindex]=min(indivials.fitness);
[worestfitness,worestindex]=max(indivials.fitness);
% 代替上一次進化中最好的染色體
if bestfitness>newbestfitness
bestfitness=newbestfitness;
bestchrom=indivials.chrom(newbestindex,:);
end
indivials.chrom(worestindex,:)=bestchrom;
indivials.fitness(worestindex)=bestfitness;

%avgfitness=sum(indivials.fitness)/sizepop;

% trace=[trace;avgfitness bestfitness]; %記錄每一代進化中最好的適應度和平均適應度

end
%% 遺傳演算法結果分析
%figure(3)
%[r c]=size(trace);
%plot([1:r]',trace(:,2),'b--');
%title(['適應度曲線 ' '終止代數=' num2str(maxgen)]);
%xlabel('進化代數');ylabel('適應度');
%legend('平均適應度','最佳適應度');
disp('適應度 變數');
x=bestchrom;

%% 把最優初始閥值權值賦予網路預測
% %用遺傳演算法優化的BP網路進行值預測
w1=x(1:inputnum*hiddennum);
B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
B2=x

(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);

net.iw{1,1}=reshape(w1,hiddennum,inputnum);
net.lw{2,1}=reshape(w2,outputnum,hiddennum);
net.b{1}=reshape(B1,hiddennum,1);
net.b{2}=B2;

%% BP網路訓練
%網路進化參數
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
%net.trainParam.goal=0.00001;

%網路訓練
[net,per2]=train(net,inputn,outputn);

%% BP網路預測
%數據歸一化
inputn_test=mapminmax('apply',input_test,inputps);
an=sim(net,inputn_test);
test_simu=mapminmax('reverse',an,outputps);
error=test_simu-output_test;

%figure(4);
hold on;plot(1:500,error,'r');
legend('優化前的誤差','優化後的誤差','fontsize',12)

(2)編碼子程序code.m
function ret=Code(lenchrom,bound)
%本函數將變數編碼成染色體,用於隨機初始化一個種群
% lenchrom input : 染色體長度
% bound input : 變數的取值范圍
% ret output: 染色體的編碼值
flag=0;
while flag==0
pick=rand(1,length(lenchrom));
ret=bound(:,1)'+(bound(:,2)-bound(:,1))'.*pick; %線性插值,編碼結果以實數向量存入ret中
flag=test(lenchrom,bound,ret); %檢驗染色體的可行性
end

(3)適應度函數fun.m
function error = fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn)
%該函數用來計算適應度值
%x input 個體
%inputnum input 輸入層節點數
%outputnum input 隱含層節點數
%net input 網路
%inputn input 訓練輸入數據
%outputn input 訓練輸出數據
%error output 個體適應度值
%提取
w1=x(1:inputnum*hiddennum);
B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);
net=newff(inputn,outputn,hiddennum);
%網路進化參數
net.trainParam.epochs=20;
net.trainParam.lr=0.1;
net.trainParam.goal=0.00001;
net.trainParam.show=100;
net.trainParam.showWindow=0;
%網路權值賦值
net.iw{1,1}=reshape(w1,hiddennum,inputnum);
net.lw{2,1}=reshape(w2,outputnum,hiddennum);
net.b{1}=reshape(B1,hiddennum,1);
net.b{2}=B2;
%網路訓練
net=train(net,inputn,outputn);
an=sim(net,inputn);
error=sum(abs(an-outputn));

(4)選擇操作Select.m
function ret=select(indivials,sizepop)
% 該函數用於進行選擇操作
% indivials input 種群信息
% sizepop input 種群規模
% ret output 選擇後的新種群

%求適應度值倒數
[a bestch]=min(indivials.fitness);
%b=indivials.chrom(bestch);
%c=indivials.fitness(bestch);
fitness1=10./indivials.fitness; %indivials.fitness為個體適應度值

%個體選擇概率
sumfitness=sum(fitness1);
sumf=fitness1./sumfitness;

%採用輪盤賭法選擇新個體
index=[];
for i=1:sizepop %sizepop為種群數
pick=rand;
while pick==0
pick=rand;
end
for i=1:sizepop
pick=pick-sumf(i);
if pick<0
index=[index i];
break;
end
end
end
%index=[index bestch];
%新種群
indivials.chrom=indivials.chrom(index,:); %indivials.chrom為種群中個體
indivials.fitness=indivials.fitness(index);
%indivials.chrom=[indivials.chrom;b];
%indivials.fitness=[indivials.fitness;c];
ret=indivials;

(5)交叉操作cross.m
function ret=Cross(pcross,lenchrom,chrom,sizepop,bound)
%本函數完成交叉操作
% pcorss input : 交叉概率
% lenchrom input : 染色體的長度
% chrom input : 染色體群
% sizepop input : 種群規模
% ret output : 交叉後的染色體
for i=1:sizepop %每一輪for循環中,可能會進行一次交叉操作,染色體是隨機選擇的,交叉位置也是隨機選擇的,%但該輪for循環中是否進行交叉操作則由交叉概率決定(continue控制)
% 隨機選擇兩個染色體進行交叉
pick=rand(1,2);
while prod(pick)==0
pick=rand(1,2);
end
index=ceil(pick.*sizepop);
% 交叉概率決定是否進行交叉
pick=rand;
while pick==0
pick=rand;
end
if pick>pcross
continue;
end
flag=0;
while flag==0
% 隨機選擇交叉位
pick=rand;
while pick==0
pick=rand;
end
pos=ceil(pick.*sum(lenchrom)); %隨機選擇進行交叉的位置,即選擇第幾個變數進行交叉,注意:兩個染色體交叉的位置相同
pick=rand; %交叉開始
v1=chrom(index(1),pos);
v2=chrom(index(2),pos);
chrom(index(1),pos)=pick*v2+(1-pick)*v1;
chrom(index(2),pos)=pick*v1+(1-pick)*v2; %交叉結束
flag1=test(lenchrom,bound,chrom(index(1),:)); %檢驗染色體1的可行性
flag2=test(lenchrom,bound,chrom(index(2),:)); %檢驗染色體2的可行性
if flag1*flag2==0
flag=0;
else flag=1;
end %如果兩個染色體不是都可行,則重新交叉
end
end
ret=chrom;

(6)變異操作Mutation.m
function ret=Mutation(pmutation,lenchrom,chrom,sizepop,num,maxgen,bound)
% 本函數完成變異操作
% pcorss input : 變異概率
% lenchrom input : 染色體長度
% chrom input : 染色體群
% sizepop input : 種群規模
% opts input : 變異方法的選擇
% pop input : 當前種群的進化代數和最大的進化代數信息
% bound input : 每個個體的上屆和下屆
% maxgen input :最大迭代次數
% num input : 當前迭代次數
% ret output : 變異後的染色體
for i=1:sizepop %每一輪for循環中,可能會進行一次變異操作,染色體是隨機選擇的,變異位置也是隨機選擇的,
%但該輪for循環中是否進行變異操作則由變異概率決定(continue控制)
% 隨機選擇一個染色體進行變異
pick=rand;
while pick==0
pick=rand;
end
index=ceil(pick*sizepop);
% 變異概率決定該輪循環是否進行變異
pick=rand;
if pick>pmutation
continue;
end
flag=0;
while flag==0
% 變異位置
pick=rand;
while pick==0
pick=rand;
end
pos=ceil(pick*sum(lenchrom)); %隨機選擇了染色體變異的位置,即選擇了第pos個變數進行變異
pick=rand; %變異開始
fg=(rand*(1-num/maxgen))^2;
if pick>0.5
chrom(i,pos)=chrom(i,pos)+(bound(pos,2)-chrom(i,pos))*fg;
else
chrom(i,pos)=chrom(i,pos)-(chrom(i,pos)-bound(pos,1))*fg;
end %變異結束
flag=test(lenchrom,bound,chrom(i,:)); %檢驗染色體的可行性
end
end
ret=chrom;

『貳』 關於神經網路LM訓練演算法的一些問題

1.初始權值不一樣,如果一樣,每次訓練結果是相同的 2.是 3.在train之前修改權值,IW,LW,b,使之相同 4.取多次實驗的均值 一點淺見,僅供參考

『叄』 python怎麼做最優化

最優化
為什麼要做最優化呢?因為在生活中,人們總是希望幸福值或其它達到一個極值,比如做生意時希望成本最小,收入最大,所以在很多商業情境中,都會遇到求極值的情況。
函數求根
這里「函數的根」也稱「方程的根」,或「函數的零點」。
先把我們需要的包載入進來。import numpy as npimport scipy as spimport scipy.optimize as optimport matplotlib.pyplot as plt%matplotlib inline
函數求根和最優化的關系?什麼時候函數是最小值或最大值?
兩個問題一起回答:最優化就是求函數的最小值或最大值,同時也是極值,在求一個函數最小值或最大值時,它所在的位置肯定是導數為 0 的位置,所以要求一個函數的極值,必然要先求導,使其為 0,所以函數求根就是為了得到最大值最小值。
scipy.optimize 有什麼方法可以求根?
可以用 scipy.optimize 中的 bisect 或 brentq 求根。f = lambda x: np.cos(x) - x # 定義一個匿名函數x = np.linspace(-5, 5, 1000) # 先生成 1000 個 xy = f(x) # 對應生成 1000 個 f(x)plt.plot(x, y); # 看一下這個函數長什麼樣子plt.axhline(0, color='k'); # 畫一根橫線,位置在 y=0

opt.bisect(f, -5, 5) # 求取函數的根0.7390851332155535plt.plot(x, y)plt.axhline(0, color='k')plt.scatter([_], [0], c='r', s=100); # 這里的 [_] 表示上一個 Cell 中的結果,這里是 x 軸上的位置,0 是 y 上的位置

求根有兩種方法,除了上面介紹的 bisect,還有 brentq,後者比前者快很多。%timeit opt.bisect(f, -5, 5)%timeit opt.brentq(f, -5, 5)10000 loops, best of 3: 157 s per loopThe slowest run took 11.65 times longer than the fastest. This could mean that an intermediate result is being cached.10000 loops, best of 3: 35.9 s per loop
函數求最小化
求最小值就是一個最優化問題。求最大值時只需對函數做一個轉換,比如加一個負號,或者取倒數,就可轉成求最小值問題。所以兩者是同一問題。
初始值對最優化的影響是什麼?
舉例來說,先定義個函數。f = lambda x: 1-np.sin(x)/xx = np.linspace(-20., 20., 1000)y = f(x)
當初始值為 3 值,使用 minimize 函數找到最小值。minimize 函數是在新版的 scipy 里,取代了以前的很多最優化函數,是個通用的介面,背後是很多方法在支撐。x0 = 3xmin = opt.minimize(f, x0).x # x0 是起始點,起始點最好離真正的最小值點不要太遠plt.plot(x, y)plt.scatter(x0, f(x0), marker='o', s=300); # 起始點畫出來,用圓圈表示plt.scatter(xmin, f(xmin), marker='v', s=300); # 最小值點畫出來,用三角表示plt.xlim(-20, 20);

初始值為 3 時,成功找到最小值。
現在來看看初始值為 10 時,找到的最小值點。x0 = 10xmin = opt.minimize(f, x0).xplt.plot(x, y)plt.scatter(x0, f(x0), marker='o', s=300)plt.scatter(xmin, f(xmin), marker='v', s=300)plt.xlim(-20, 20);

由上圖可見,當初始值為 10 時,函數找到的是局部最小值點,可見 minimize 的默認演算法對起始點的依賴性。
那麼怎麼才能不管初始值在哪個位置,都能找到全局最小值點呢?
如何找到全局最優點?
可以使用 basinhopping 函數找到全局最優點,相關背後演算法,可以看幫助文件,有提供論文的索引和出處。
我們設初始值為 10 看是否能找到全局最小值點。x0 = 10from scipy.optimize import basinhoppingxmin = basinhopping(f,x0,stepsize = 5).xplt.plot(x, y);plt.scatter(x0, f(x0), marker='o', s=300);plt.scatter(xmin, f(xmin), marker='v', s=300);plt.xlim(-20, 20);

當起始點在比較遠的位置,依然成功找到了全局最小值點。
如何求多元函數最小值?
以二元函數為例,使用 minimize 求對應的最小值。def g(X): x,y = X return (x-1)**4 + 5 * (y-1)**2 - 2*x*yX_opt = opt.minimize(g, (8, 3)).x # (8,3) 是起始點print X_opt[ 1.88292611 1.37658521]fig, ax = plt.subplots(figsize=(6, 4)) # 定義畫布和圖形x_ = y_ = np.linspace(-1, 4, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, g((X, Y)), 50) # 等高線圖ax.plot(X_opt[0], X_opt[1], 'r*', markersize=15) # 最小點的位置是個元組ax.set_xlabel(r"$x_1$", fontsize=18)ax.set_ylabel(r"$x_2$", fontsize=18)plt.colorbar(c, ax=ax) # colorbar 表示顏色越深,高度越高fig.tight_layout()

畫3D 圖。from mpl_toolkits.mplot3d import Axes3Dfrom matplotlib import cmfig = plt.figure()ax = fig.gca(projection='3d')x_ = y_ = np.linspace(-1, 4, 100)X, Y = np.meshgrid(x_, y_)surf = ax.plot_surface(X, Y, g((X,Y)), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)cset = ax.contour(X, Y, g((X,Y)), zdir='z',offset=-5, cmap=cm.coolwarm)fig.colorbar(surf, shrink=0.5, aspect=5);

曲線擬合
曲線擬合和最優化有什麼關系?
曲線擬合的問題是,給定一組數據,它可能是沿著一條線散布的,這時要找到一條最優的曲線來擬合這些數據,也就是要找到最好的線來代表這些點,這里的最優是指這些點和線之間的距離是最小的,這就是為什麼要用最優化問題來解決曲線擬合問題。
舉例說明,給一些點,找到一條線,來擬合這些點。
先給定一些點:N = 50 # 點的個數m_true = 2 # 斜率b_true = -1 # 截距dy = 2.0 # 誤差np.random.seed(0)xdata = 10 * np.random.random(N) # 50 個 x,服從均勻分布ydata = np.random.normal(b_true + m_true * xdata, dy) # dy 是標准差plt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');

上面的點整體上呈現一個線性關系,要找到一條斜線來代表這些點,這就是經典的一元線性回歸。目標就是找到最好的線,使點和線的距離最短。要優化的函數是點和線之間的距離,使其最小。點是確定的,而線是可變的,線是由參數值,斜率和截距決定的,這里就是要通過優化距離找到最優的斜率和截距。
點和線的距離定義如下:def chi2(theta, x, y): return np.sum(((y - theta[0] - theta[1] * x)) ** 2)
上式就是誤差平方和。
誤差平方和是什麼?有什麼作用?
誤差平方和公式為:
誤差平方和大,表示真實的點和預測的線之間距離太遠,說明擬合得不好,最好的線,應該是使誤差平方和最小,即最優的擬合線,這里是條直線。
誤差平方和就是要最小化的目標函數。
找到最優的函數,即斜率和截距。theta_guess = [0, 1] # 初始值theta_best = opt.minimize(chi2, theta_guess, args=(xdata, ydata)).xprint(theta_best)[-1.01442005 1.93854656]
上面兩個輸出即是預測的直線斜率和截距,我們是根據點來反推直線的斜率和截距,那麼真實的斜率和截距是多少呢?-1 和 2,很接近了,差的一點是因為有噪音的引入。xfit = np.linspace(0, 10)yfit = theta_best[0] + theta_best[1] * xfitplt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');plt.plot(xfit, yfit, '-k');

最小二乘(Least Square)是什麼?
上面用的是 minimize 方法,這個問題的目標函數是誤差平方和,這就又有一個特定的解法,即最小二乘。
最小二乘的思想就是要使得觀測點和估計點的距離的平方和達到最小,這里的「二乘」指的是用平方來度量觀測點與估計點的遠近(在古漢語中「平方」稱為「二乘」),「最小」指的是參數的估計值要保證各個觀測點與估計點的距離的平方和達到最小。
關於最小二乘估計的計算,涉及更多的數學知識,這里不想詳述,其一般的過程是用目標函數對各參數求偏導數,並令其等於 0,得到一個線性方程組。具體推導過程可參考斯坦福機器學習講義 第 7 頁。def deviations(theta, x, y): return (y - theta[0] - theta[1] * x)theta_best, ier = opt.leastsq(deviations, theta_guess, args=(xdata, ydata))print(theta_best)[-1.01442016 1.93854659]
最小二乘 leastsq 的結果跟 minimize 結果一樣。注意 leastsq 的第一個參數不再是誤差平方和 chi2,而是誤差本身 deviations,即沒有平方,也沒有和。yfit = theta_best[0] + theta_best[1] * xfitplt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');plt.plot(xfit, yfit, '-k');

非線性最小二乘
上面是給一些點,擬合一條直線,擬合一條曲線也是一樣的。def f(x, beta0, beta1, beta2): # 首先定義一個非線性函數,有 3 個參數 return beta0 + beta1 * np.exp(-beta2 * x**2)beta = (0.25, 0.75, 0.5) # 先猜 3 個 betaxdata = np.linspace(0, 5, 50)y = f(xdata, *beta)ydata = y + 0.05 * np.random.randn(len(xdata)) # 給 y 加噪音def g(beta): return ydata - f(xdata, *beta) # 真實 y 和 預測值的差,求最優曲線時要用到beta_start = (1, 1, 1)beta_opt, beta_cov = opt.leastsq(g, beta_start)print beta_opt # 求到的 3 個最優的 beta 值[ 0.25525709 0.74270226 0.54966466]
拿估計的 beta_opt 值跟真實的 beta = (0.25, 0.75, 0.5) 值比較,差不多。fig, ax = plt.subplots()ax.scatter(xdata, ydata) # 畫點ax.plot(xdata, y, 'r', lw=2) # 真實值的線ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2) # 擬合的線ax.set_xlim(0, 5)ax.set_xlabel(r"$x$", fontsize=18)ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)fig.tight_layout()

除了使用最小二乘,還可以使用曲線擬合的方法,得到的結果是一樣的。beta_opt, beta_cov = opt.curve_fit(f, xdata, ydata)print beta_opt[ 0.25525709 0.74270226 0.54966466]
有約束的最小化
有約束的最小化是指,要求函數最小化之外,還要滿足約束條件,舉例說明。
邊界約束def f(X): x, y = X return (x-1)**2 + (y-1)**2 # 這是一個碗狀的函數x_opt = opt.minimize(f, (0, 0), method='BFGS').x # 無約束最優化
假設有約束條件,x 和 y 要在一定的范圍內,如 x 在 2 到 3 之間,y 在 0 和 2 之間。bnd_x1, bnd_x2 = (2, 3), (0, 2) # 對自變數的約束x_cons_opt = opt.minimize(f, np.array([0, 0]), method='L-BFGS-B', bounds=[bnd_x1, bnd_x2]).x # bounds 矩形約束fig, ax = plt.subplots(figsize=(6, 4))x_ = y_ = np.linspace(-1, 3, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, f((X,Y)), 50)ax.plot(x_opt[0], x_opt[1], 'b*', markersize=15) # 沒有約束下的最小值,藍色五角星ax.plot(x_cons_opt[0], x_cons_opt[1], 'r*', markersize=15) # 有約束下的最小值,紅色星星bound_rect = plt.Rectangle((bnd_x1[0], bnd_x2[0]), bnd_x1[1] - bnd_x1[0], bnd_x2[1] - bnd_x2[0], facecolor="grey")ax.add_patch(bound_rect)ax.set_xlabel(r"$x_1$", fontsize=18)ax.set_ylabel(r"$x_2$", fontsize=18)plt.colorbar(c, ax=ax)fig.tight_layout()

不等式約束
介紹下相關理論,先來看下存在等式約束的極值問題求法,比如下面的優化問題。
目標函數是 f(w),下面是等式約束,通常解法是引入拉格朗日運算元,這里使用 ββ 來表示運算元,得到拉格朗日公式為
l 是等式約束的個數。
然後分別對 w 和ββ 求偏導,使得偏導數等於 0,然後解出 w 和βiβi,至於為什麼引入拉格朗日運算元可以求出極值,原因是 f(w) 的 dw 變化方向受其他不等式的約束,dw的變化方向與f(w)的梯度垂直時才能獲得極值,而且在極值處,f(w) 的梯度與其他等式梯度的線性組合平行,因此他們之間存在線性關系。(參考《最優化與KKT條件》)
對於不等式約束的極值問題
常常利用拉格朗日對偶性將原始問題轉換為對偶問題,通過解對偶問題而得到原始問題的解。該方法應用在許多統計學習方法中。有興趣的可以參閱相關資料,這里不再贅述。def f(X): return (X[0] - 1)**2 + (X[1] - 1)**2def g(X): return X[1] - 1.75 - (X[0] - 0.75)**4x_opt = opt.minimize(f, (0, 0), method='BFGS').xconstraints = [dict(type='ineq', fun=g)] # 約束採用字典定義,約束方式為不等式約束,邊界用 g 表示x_cons_opt = opt.minimize(f, (0, 0), method='SLSQP', constraints=constraints).xfig, ax = plt.subplots(figsize=(6, 4))x_ = y_ = np.linspace(-1, 3, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, f((X, Y)), 50)ax.plot(x_opt[0], x_opt[1], 'b*', markersize=15) # 藍色星星,沒有約束下的最小值ax.plot(x_, 1.75 + (x_-0.75)**4, '', markersize=15)ax.fill_between(x_, 1.75 + (x_-0.75)**4, 3, color="grey")ax.plot(x_cons_opt[0], x_cons_opt[1], 'r*', markersize=15) # 在區域約束下的最小值ax.set_ylim(-1, 3)ax.set_xlabel(r"$x_0$", fontsize=18)ax.set_ylabel(r"$x_1$", fontsize=18)plt.colorbar(c, ax=ax)fig.tight_layout()

scipy.optimize.minimize 中包括了多種最優化演算法,每種演算法使用范圍不同,詳細參考官方文檔。

『肆』 python數據分析與應用第三章代碼3-5的數據哪來的

savetxt

import numpy as np

i2 = np.eye(2)

np.savetxt("eye.txt", i2)

3.4 讀入CSV文件

# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800

c,v=np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True) #index從0開始

3.6.1 算術平均值

np.mean(c) = np.average(c)

3.6.2 加權平均值

t = np.arange(len(c))

np.average(c, weights=t)

3.8 極值

np.min(c)

np.max(c)

np.ptp(c) 最大值與最小值的差值

3.10 統計分析

np.median(c) 中位數

np.msort(c) 升序排序

np.var(c) 方差

3.12 分析股票收益率

np.diff(c) 可以返回一個由相鄰數組元素的差

值構成的數組

returns = np.diff( arr ) / arr[ : -1] #diff返回的數組比收盤價數組少一個元素

np.std(c) 標准差

對數收益率

logreturns = np.diff( np.log(c) ) #應檢查輸入數組以確保其不含有零和負數

where 可以根據指定的條件返回所有滿足條件的數

組元素的索引值。

posretindices = np.where(returns > 0)

np.sqrt(1./252.) 平方根,浮點數

3.14 分析日期數據

# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800

dates, close=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), converters={1:datestr2num}, unpack=True)

print "Dates =", dates

def datestr2num(s):

return datetime.datetime.strptime(s, "%d-%m-%Y").date().weekday()

# 星期一 0

# 星期二 1

# 星期三 2

# 星期四 3

# 星期五 4

# 星期六 5

# 星期日 6

#output

Dates = [ 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 1. 2. 4. 0. 1. 2. 3. 4. 0.

1. 2. 3. 4.]

averages = np.zeros(5)

for i in range(5):

indices = np.where(dates == i)

prices = np.take(close, indices) #按數組的元素運算,產生一個數組作為輸出。

>>>a = [4, 3, 5, 7, 6, 8]

>>>indices = [0, 1, 4]

>>>np.take(a, indices)

array([4, 3, 6])

np.argmax(c) #返回的是數組中最大元素的索引值

np.argmin(c)

3.16 匯總數據

# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800

#得到第一個星期一和最後一個星期五

first_monday = np.ravel(np.where(dates == 0))[0]

last_friday = np.ravel(np.where(dates == 4))[-1]

#創建一個數組,用於存儲三周內每一天的索引值

weeks_indices = np.arange(first_monday, last_friday + 1)

#按照每個子數組5個元素,用split函數切分數組

weeks_indices = np.split(weeks_indices, 5)

#output

[array([1, 2, 3, 4, 5]), array([ 6, 7, 8, 9, 10]), array([11,12, 13, 14, 15])]

weeksummary = np.apply_along_axis(summarize, 1, weeks_indices,open, high, low, close)

def summarize(a, o, h, l, c): #open, high, low, close

monday_open = o[a[0]]

week_high = np.max( np.take(h, a) )

week_low = np.min( np.take(l, a) )

friday_close = c[a[-1]]

return("APPL", monday_open, week_high, week_low, friday_close)

np.savetxt("weeksummary.csv", weeksummary, delimiter=",", fmt="%s") #指定了文件名、需要保存的數組名、分隔符(在這個例子中為英文標點逗號)以及存儲浮點數的格式。

.png

格式字元串以一個百分號開始。接下來是一個可選的標志字元:-表示結果左對齊,0表示左端補0,+表示輸出符號(正號+或負號-)。第三部分為可選的輸出寬度參數,表示輸出的最小位數。第四部分是精度格式符,以」.」開頭,後面跟一個表示精度的整數。最後是一個類型指定字元,在例子中指定為字元串類型。

numpy.apply_along_axis(func1d, axis, arr, *args, **kwargs)

>>>def my_func(a):

... """Average first and last element of a 1-D array"""

... return (a[0] + a[-1]) * 0.5

>>>b = np.array([[1,2,3], [4,5,6], [7,8,9]])

>>>np.apply_along_axis(my_func, 0, b) #沿著X軸運動,取列切片

array([ 4., 5., 6.])

>>>np.apply_along_axis(my_func, 1, b) #沿著y軸運動,取行切片

array([ 2., 5., 8.])

>>>b = np.array([[8,1,7], [4,3,9], [5,2,6]])

>>>np.apply_along_axis(sorted, 1, b)

array([[1, 7, 8],

[3, 4, 9],

[2, 5, 6]])

3.20 計算簡單移動平均線

(1) 使用ones函數創建一個長度為N的元素均初始化為1的數組,然後對整個數組除以N,即可得到權重。如下所示:

N = int(sys.argv[1])

weights = np.ones(N) / N

print "Weights", weights

在N = 5時,輸出結果如下:

Weights [ 0.2 0.2 0.2 0.2 0.2] #權重相等

(2) 使用這些權重值,調用convolve函數:

c = np.loadtxt('data.csv', delimiter=',', usecols=(6,),unpack=True)

sma = np.convolve(weights, c)[N-1:-N+1] #卷積是分析數學中一種重要的運算,定義為一個函數與經過翻轉和平移的另一個函數的乘積的積分。

t = np.arange(N - 1, len(c)) #作圖

plot(t, c[N-1:], lw=1.0)

plot(t, sma, lw=2.0)

show()

3.22 計算指數移動平均線

指數移動平均線(exponential moving average)。指數移動平均線使用的權重是指數衰減的。對歷史上的數據點賦予的權重以指數速度減小,但永遠不會到達0。

x = np.arange(5)

print "Exp", np.exp(x)

#output

Exp [ 1. 2.71828183 7.3890561 20.08553692 54.59815003]

Linspace 返回一個元素值在指定的范圍內均勻分布的數組。

print "Linspace", np.linspace(-1, 0, 5) #起始值、終止值、可選的元素個數

#output

Linspace [-1. -0.75 -0.5 -0.25 0. ]

(1)權重計算

N = int(sys.argv[1])

weights = np.exp(np.linspace(-1. , 0. , N))

(2)權重歸一化處理

weights /= weights.sum()

print "Weights", weights

#output

Weights [ 0.11405072 0.14644403 0.18803785 0.24144538 0.31002201]

(3)計算及作圖

c = np.loadtxt('data.csv', delimiter=',', usecols=(6,),unpack=True)

ema = np.convolve(weights, c)[N-1:-N+1]

t = np.arange(N - 1, len(c))

plot(t, c[N-1:], lw=1.0)

plot(t, ema, lw=2.0)

show()

3.26 用線性模型預測價格

(x, resials, rank, s) = np.linalg.lstsq(A, b) #系數向量x、一個殘差數組、A的秩以及A的奇異值

print x, resials, rank, s

#計算下一個預測值

print np.dot(b, x)

3.28 繪制趨勢線

>>> x = np.arange(6)

>>> x = x.reshape((2, 3))

>>> x

array([[0, 1, 2], [3, 4, 5]])

>>> np.ones_like(x) #用1填充數組

array([[1, 1, 1], [1, 1, 1]])

類似函數

zeros_like

empty_like

zeros

ones

empty

3.30 數組的修剪和壓縮

a = np.arange(5)

print "a =", a

print "Clipped", a.clip(1, 2) #將所有比給定最大值還大的元素全部設為給定的最大值,而所有比給定最小值還小的元素全部設為給定的最小值

#output

a = [0 1 2 3 4]

Clipped [1 1 2 2 2]

a = np.arange(4)

print a

print "Compressed", a.compress(a > 2) #返回一個根據給定條件篩選後的數組

#output

[0 1 2 3]

Compressed [3]

b = np.arange(1, 9)

print "b =", b

print "Factorial", b.prod() #輸出數組元素階乘結果

#output

b = [1 2 3 4 5 6 7 8]

Factorial 40320

print "Factorials", b.cumprod()

#output

熱點內容
資料庫inner 發布:2025-03-11 01:06:55 瀏覽:899
ice解壓 發布:2025-03-11 00:54:50 瀏覽:378
網址批量訪問 發布:2025-03-11 00:40:38 瀏覽:750
粉紅視頻腳本 發布:2025-03-11 00:39:56 瀏覽:445
伺服器名稱或ip從哪裡看 發布:2025-03-11 00:35:44 瀏覽:492
日本細菌戰資料庫 發布:2025-03-11 00:29:34 瀏覽:424
釣魚直播用什麼配置 發布:2025-03-11 00:28:39 瀏覽:416
高配置伺服器搭建虛擬機集群 發布:2025-03-11 00:27:18 瀏覽:370
在線印刷源碼 發布:2025-03-11 00:25:06 瀏覽:719
python矩陣轉置函數 發布:2025-03-11 00:22:53 瀏覽:549