Guest User

Untitled

a guest
Feb 19th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.12 KB | None | 0 0
  1. import pandas as p
  2. from scipy.stats import multivariate_normal
  3. import numpy as np
  4.  
  5. def tempering_schedule(type='tempering', lam=4.0, nstages=100):
  6.  
  7. if type=='tempering':
  8. r = np.array([r for r in range(nstages)])
  9. lams = ( (r+1) / nstages ) ** lam
  10. elif type=='adaptive':
  11. yield
  12.  
  13. for i in range(nstages):
  14. if i == 0: yield lams[i], 0.0
  15. if i > 0:
  16. yield lams[i], lams[i-1]
  17.  
  18. class SMCState(object):
  19.  
  20. def __init__(self, npart, npara):
  21.  
  22. self.npart = npart
  23. self.npara = npara
  24. self.liksim = np.zeros(npart)
  25. self.parasim = np.zeros((npart, npara))
  26. self.priorsim = np.zeros(npart)
  27. self.wtsim = np.ones(npart) / npart
  28. self.acpt = np.zeros(npart)
  29. self.logzt = 0.0
  30. self.c = 0.3
  31. self.ess = npart
  32. self.nresamples = 0
  33.  
  34. #def update(self, liksim=none, parasim=none
  35.  
  36. def to_dataframe(self, paranames=None, resample=True):
  37.  
  38. if paranames is None:
  39. paranames = ['para{:02d}'.format(i) for i in range(self.npara)]
  40.  
  41. df = np.c_[self.parasim, self.liksim, self.priorsim, self.wtsim]
  42. df = p.DataFrame(df, columns=paranames+['lik','prior','weight'])
  43. return df
  44.  
  45.  
  46. from tqdm import tqdm
  47.  
  48. class SMCSampler(object):
  49.  
  50. def __init__(self, likelihood, prior, paranames=None,
  51. tuning_schedule=(4.0, 500)):
  52.  
  53. self.likelihood = likelihood
  54. self.prior = prior
  55. self.tuning_schedule = tuning_schedule
  56. self.nstages = tuning_schedule[1]
  57. self.verbose = True
  58.  
  59. def initialize(self, npart=5000):
  60.  
  61. state = SMCState(npart=npart, npara=self.prior.npara)
  62. state.parasim = self.prior.rvs(size=npart)
  63.  
  64. priors = ( self.prior.logpdf(para) for para in state.parasim )
  65. likelihoods = ( self.likelihood(para) for para in state.parasim )
  66.  
  67. if self.verbose:
  68. likelihoods = tqdm(likelihoods, total=npart)
  69. #
  70.  
  71. for i,l in enumerate(likelihoods):
  72. state.liksim[i] = l
  73.  
  74. priors = tqdm(priors, total=npart)
  75. for i,l in enumerate(priors):
  76. state.priorsim[i] = l
  77. #state.liksim = list( likelihoods )
  78. return state
  79. #state.priorsim = list ( priors )
  80.  
  81.  
  82. def estimate(self, npart=5000, parallel=False):
  83.  
  84. state = self.initialize(npart=npart)
  85.  
  86. t = tempering_schedule(lam=4.0, nstages=self.nstages)
  87. if self.verbose:
  88. t = tqdm(t, total=self.nstages)
  89.  
  90. for temp in t:
  91. t.set_description('φ = %4.2f [%i resamples, avg. lik = %5.2f, pos = %5.2f, acpt = %4.2f]'
  92. % (temp[0], state.nresamples, state.liksim.mean(),
  93. state.liksim.mean()+state.priorsim.mean(), state.acpt.mean()))
  94. state = self.iterate(state, temp=temp[0], temp_old=temp[1], parallel=parallel)
  95.  
  96. #results.record(state)
  97. # #yield results
  98. return state
  99.  
  100.  
  101. def iterate(self, state, temp=1.0, temp_old=0.0, parallel=False):
  102.  
  103. delta_phi = temp - temp_old
  104.  
  105. state = self._correction(state, delta_phi=delta_phi)
  106.  
  107. if state.ess < state.npart/2:
  108. state = self._selection(state)
  109.  
  110. state = self._mutation(state, temp=temp, parallel=parallel)
  111.  
  112. return state
  113.  
  114.  
  115.  
  116. def _correction(self, state, delta_phi=1.0):
  117.  
  118. state.wtsim = np.exp(state.liksim * delta_phi ) * state.wtsim
  119. incwt = np.sum(state.wtsim)
  120. state.wtsim = state.wtsim / incwt
  121. state.logzt += np.log(incwt)
  122. state.ess = (1/(state.wtsim**2).sum())
  123. return state
  124.  
  125. def _selection(self, state, scheme='multinomial'):
  126.  
  127. if scheme=='multinomial':
  128. counts = np.random.multinomial(state.npart, state.wtsim)
  129. inds = np.repeat(range(state.npart), counts)
  130.  
  131. state.parasim = state.parasim[inds]
  132. state.liksim = state.liksim[inds]
  133. state.priorsim = state.priorsim[inds]
  134. state.wtsim = np.ones(state.npart) / state.npart
  135. state.ess = state.npart
  136. state.nresamples += 1
  137.  
  138. return state
  139.  
  140. def _mutation(self, state, temp=1.0, parallel=False):
  141.  
  142. mu = np.einsum('i,ij->j', state.wtsim, state.parasim)
  143. sigma = np.einsum('i,ij->ij', state.wtsim, state.parasim-mu)
  144. sigma = state.c**2 * sigma.T.dot(state.parasim-mu)
  145.  
  146. #sigma_chol = np.linalg.cholesky(sigma)
  147. eps = np.random.multivariate_normal(mean=np.zeros(state.npara),
  148. cov=sigma,
  149. size=state.npart)
  150. u = np.random.rand(state.npart)
  151. acpt = np.zeros((state.npart))
  152.  
  153.  
  154. for i in range(state.npart):
  155.  
  156. para0 = state.parasim[i]
  157. lik0 = state.liksim[i]
  158. pr0 = state.priorsim[i]
  159.  
  160. para1 = para0.copy()
  161. #para1 = para1 + sigma_chol @ eps[i]
  162. para1 += eps[i]
  163. lik1 = self.likelihood(para1)
  164. pr1 = self.prior.logpdf(para1)
  165.  
  166. alp = np.exp(temp*(lik1-lik0) + pr1 - pr0)
  167.  
  168.  
  169. if u[i] < alp:
  170. state.parasim[i] = para1
  171. state.liksim[i] = lik1
  172. state.priorsim[i] = pr1
  173. state.acpt[i] = 1
  174.  
  175. if acpt.mean() > 0.25:
  176. state.c = state.c * 1.1
  177. else:
  178. state.c = state.c * 0.9
  179.  
  180. return state
  181.  
  182.  
  183. class HamiltonianSMCSampler(SMCSampler):
  184.  
  185.  
  186.  
  187. def __init__(self, *args, **kwargs):
  188.  
  189. grad_loglik = kwargs.pop('gradient')
  190.  
  191. super().__init__(*args, **kwargs)
  192.  
  193. self.grad_loglik = grad_loglik
  194. self.c = 0.01
  195.  
  196. def _mutation(self, state, temp=1.0, parallel=False):
  197.  
  198. mu = np.einsum('i,ij->j', state.wtsim, state.parasim)
  199. sigma = np.einsum('i,ij->ij', state.wtsim, state.parasim-mu)
  200. sigma = sigma.T.dot(state.parasim-mu)
  201.  
  202. pdfp = multivariate_normal(cov=np.eye(2))
  203.  
  204. u = np.random.rand(state.npart)
  205. acpt = np.zeros((state.npart))
  206. for i in range(state.npart):
  207.  
  208. para0 = state.parasim[i]
  209. lik0 = state.liksim[i]
  210. pr0 = state.priorsim[i]
  211.  
  212. para1 = para0.copy()
  213. p0 = np.linalg.cholesky(sigma) @ np.random.rand(state.npara)
  214. px = p0.copy()
  215.  
  216. para1, p1 = self.Q(para1, p0.copy(), eps=state.c, L=10, psi=temp)
  217. lik1 = self.likelihood(para1)
  218. pr1 = self.prior.logpdf(para1)
  219.  
  220. u0 = pdfp.logpdf(p0)
  221. u1 = pdfp.logpdf(p1)
  222.  
  223. print(lik1,lik0)
  224. alp = np.exp(temp*(lik1-lik0) + pr1 - pr0 + u1 - u0)
  225.  
  226. if u[i] < alp:
  227. state.parasim[i] = para1
  228. state.liksim[i] = lik1
  229. state.priorsim[i] = pr1
  230. acpt[i] = 1
  231.  
  232.  
  233. if acpt.mean() > 0.65:
  234. state.c = state.c * 1.1
  235. else:
  236. state.c = state.c * 0.9
  237.  
  238. return state
  239.  
  240.  
  241.  
  242. def Q(self, theta, p, psi=1, eps=0.01, L=10):
  243.  
  244. for i in range(L):
  245. p = p + eps*psi*self.grad_loglik(theta)/2.
  246. theta = theta + eps*p
  247. p = p + eps*psi*self.grad_loglik(theta)/2.
  248.  
  249. return theta, -p
Add Comment
Please, Sign In to add comment