コード
import numpy as np import matplotlib.pyplot as plt class RBFkernel: def __init__(self,*param): self.param = list(param) def __call__(self,x1,x2): a,s,w = self.param return a**2*np.exp(-((x1-x2)/s)**2) + w*(x1==x2) x0 = (0,5,10,20,25,33,50) y0 = (156,152,148,135,156,145,158) x1 = np.linspace(0,50,201) kernel = RBFkernel(10,5,3) # 適当なパラメータを使うカーネル関数 k00 = kernel(*np.meshgrid(x0,x0)) k00_1 = np.linalg.inv(k00) # 逆行列 k01 = kernel(*np.meshgrid(x0,x1,indexing='ij')) k10 = k01.T k11 = kernel(*np.meshgrid(x1,x1)) mu = k10.dot(k00_1.dot(y0)) sigma = k11 - k10.dot(k00_1.dot(k01)) plt.scatter(x0,y0,c='#ff77aa') plt.plot(x1,mu,'g') # 推測された平均 std = np.sqrt(sigma.diagonal()) # 各点の標準偏差は共分散行列の対角成分 plt.fill_between(x1,mu-std,mu+std,alpha=0.2,color='g') # 推測された標準偏差の中の領域 plt.show() class Kernel: def __init__(self,param,bound=None): self.param = np.array(param) if(bound==None): bound = np.zeros([len(param),2]) bound[:,1] = np.inf self.bound = np.array(bound) def __call__(self,x1,x2): a,s,w = self.param return a**2*np.exp(-0.5*((x1-x2)/s)**2) + w**2*(x1==x2) class Gausskatei: def __init__(self,kernel): self.kernel = kernel def gakushuu(self,x0,y0): # パラメータを調整せず学習 self.x0 = x0 self.y0 = y0 self.k00 = self.kernel(*np.meshgrid(x0,x0)) self.k00_1 = np.linalg.inv(self.k00) def yosoku(self,x): # xからyを予測 k00_1 = self.k00_1 k01 = self.kernel(*np.meshgrid(self.x0,x,indexing='ij')) k10 = k01.T k11 = self.kernel(*np.meshgrid(x,x)) mu = k10.dot(k00_1.dot(self.y0)) sigma = k11 - k10.dot(k00_1.dot(k01)) std = np.sqrt(sigma.diagonal()) return mu,std def logyuudo(self,param=None): # 対数尤度 if(param is None): k00 = self.k00 k00_1 = self.k00_1 else: self.kernel.param = param k00 = self.kernel(*np.meshgrid(self.x0,self.x0)) k00_1 = np.linalg.inv(k00) return -(np.linalg.slogdet(k00)[1]+self.y0.dot(k00_1.dot(self.y0))) def saitekika(self,x0,y0,kurikaeshi=1000): # パラメータを調整して学習 self.x0 = x0 self.y0 = y0 param = self.kernel.param logbound = np.log(self.kernel.bound) s = (logbound[:,1]-logbound[:,0])/10. n_param = len(param) theta0 = np.log(param) p0 = self.logyuudo(param) lis_theta = [] lis_p = [] for i in range(kurikaeshi): idou = np.random.normal(0,s,n_param) hazure = (theta0+idou<logbound[:,0])|(theta0+idou>logbound[:,1]) while(np.any(hazure)): idou[hazure] = np.random.normal(0,s,n_param)[hazure] hazure = (theta0+idou<logbound[:,0])|(theta0+idou>logbound[:,1]) theta1 = theta0 + idou param = np.exp(theta1) p1 = self.logyuudo(param) r = np.exp(p1-p0) if(r>=1 or r>np.random.random()): theta0 = theta1 p0 = p1 lis_theta.append(theta0) lis_p.append(p0) self.ar_theta = np.array(lis_theta) self.ar_p = np.array(lis_p) self.kernel.param = np.exp(lis_theta[np.argmax(lis_p)]) self.k00 = self.kernel(*np.meshgrid(x0,x0)) self.k00_1 = np.linalg.inv(self.k00) n = 7 # 既知の点の数 x0 = (0,5,10,20,25,33,50) # 既知の点 y0 = (156,152,148,135,156,145,158) param0 = [10,5,1] # パラメータの初期値 bound = [[1e-2,1e2],[1e-2,1e2],[1e-2,1e2]] # 下限上限 kernel = Kernel(param0,bound) x1 = np.linspace(0,50,200) gp = Gausskatei(kernel) gp.gakushuu(x0,y0) # パラメータを調整せずに学習 plt.figure(figsize=[5,8]) for i in [0,1]: if(i): gp.saitekika(x0,y0,1000) # パラメータを調整する plt.subplot(211+i) plt.plot(x0,y0,'. ') mu,std = gp.yosoku(x1) plt.plot(x1,mu,'g') plt.fill_between(x1,mu-std,mu+std,alpha=0.2,color='g') plt.title('a=%.3f, s=%.3f, w=%.3f'%tuple(gp.kernel.param)) plt.tight_layout() plt.show()
コード
https://qiita.com/phyblas/items/d756803ec932ab621c56 こちらのサイトを参考にして、特定済みの2次元データからRBFカーネルのパラメータを予測したいです。 特定済みの値をそのままx0,y0に代入して実行したところ、エラーが出てしまいました。 ### 発生している問題・エラーメッセージ --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-63-3d592025a82f> in <module>() 11 for i in [0,1]: 12 if(i): ---> 13 gp.saitekika(x0,y0,1000) # パラメータを調整する 14 plt.subplot(211+i) 15 plt.plot(x0,y0,'. ') 1 frames <ipython-input-62-54f0617fec3e> in saitekika(self, x0, y0, kurikaeshi) 49 n_param = len(param) 50 theta0 = np.log(param) ---> 51 p0 = self.logyuudo(param) 52 lis_theta = [] 53 lis_p = [] <ipython-input-62-54f0617fec3e> in logyuudo(self, param) 39 k00 = self.kernel(*np.meshgrid(self.x0,self.x0)) 40 k00_1 = np.linalg.inv(k00) ---> 41 return -(np.linalg.slogdet(k00)[1]+self.y0.dot(k00_1.dot(self.y0))) 42 43 def saitekika(self,x0,y0,kurikaeshi=1000): # パラメータを調整して学習 AttributeError: 'tuple' object has no attribute 'dot' ### 該当のソースコード n = 7 # 既知の点の数 x0 = (0,5,10,20,25,33,50) # 既知の点 y0 = (156,152,148,135,156,145,158) param0 = [10,5,1] # パラメータの初期値 bound = [[1e-2,1e2],[1e-2,1e2],[1e-2,1e2]] # 下限上限 kernel = Kernel(param0,bound) x1 = np.linspace(0,50,200) gp = Gausskatei(kernel) gp.gakushuu(x0,y0) # パラメータを調整せずに学習 plt.figure(figsize=[5,8]) for i in [0,1]: if(i): gp.saitekika(x0,y0,1000) # パラメータを調整する plt.subplot(211+i) plt.plot(x0,y0,'. ') mu,std = gp.yosoku(x1) plt.plot(x1,mu,'g') plt.fill_between(x1,mu-std,mu+std,alpha=0.2,color='g') plt.title('a=%.3f, s=%.3f, w=%.3f'%tuple(gp.kernel.param)) plt.tight_layout() plt.show() ### 試したこと turpleがdotに反応しないことはわかりましたが、どうすればよいか全くわからず、何も試せておりません。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー