I was making Baysien model Type-II to finding the maximum likelihood to estimate “most probable” values for hyper-parameters. After I try to run the code below I got some of error that shown in compute_posterior function. It might be something wrong with the shape.
def compute_posterior(PHI, t, alph, s2):
M = PHI.shape[1]
beta = 1/s2
H = beta*(PHI.T # PHI) + alph*np.eye(M)
SIGMA = np.linalg.inv(H)
Mu = beta * (SIGMA # (PHI.T # t))
#
return Mu, SIGMA
# Marginal log likelihood
#
# Version 1 Log Marginal (ideal)
#
def compute_log_marginal(PHI, t, alph, s2):
#
# Exploit the shape of C and the fact that M < N (usually)
#
N, M = PHI.shape
beta = 1 / s2
Mu, SIGMA = compute_posterior(PHI, t, alph, s2)
#
# Constant factor
#
logML = -N * np.log(2 * np.pi)
#
# log determinant factor (log|C|)
#
# If SIGMA becomes singular, sgn<0
#
sgn, logdet = np.linalg.slogdet(SIGMA)
#
if sgn < 0:
print("Error with alpha={0}, s2={1}".format(alph, s2))
raise np.linalg.LinAlgError("logdet sign is negative - something is wrong!")
#
logML += logdet + N*np.log(beta) + M*np.log(alph)
#
# data term (t'Ct)
#
logML -= beta * (t.T # (t - PHI # Mu))
#
logML = logML / 2.0
#
return logML
log_alph = np.linspace(-3, 6, n)
log_s2 = np.linspace(-4, 4, n)
x = df.values[:, 0:8]
t = df.values[:, 8]
n = 100
Z = np.empty((n, n))
Z_max = []
al = []
rr = []
for i, a in enumerate(log_alph):
for j, r in enumerate(log_s2):
Z[i, j] = compute_log_marginal(x,t,log_alph,log_s2)
Z_max.append(Z[i, j])
maximum = max(Z_max)
print(maximum)
# if Z[i, j] == -11.627510277032485:
# al.append(a)
# rr.append(r)
# maximum = max(Z_max)
# print(al)
# print(rr)
# print(maximum)
# maximum = -11.627510277032485
plt.contourf(log_a, log_r, Z.T)
print('The maximum point is:',maximum )
print('The max log_alpha is:',al[0] )
print('The max log_r is:',rr[0] )
plt.xlabel('log alpha')
plt.ylabel('log r')
plt.title('Contour of log alpha and log r')
After I compile I got this error, I still don't know how to figure it out
'
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-260-c7f0396b4046> in <module>
14 for i, a in enumerate(log_alph):
15 for j, r in enumerate(log_s2):
---> 16 Z[i, j] = compute_log_marginal(x,t,log_alph,log_s2)
17 Z_max.append(Z[i, j])
18 maximum = max(Z_max)
<ipython-input-233-45cfae272a38> in compute_log_marginal(PHI, t, alph, s2)
19 N, M = PHI.shape
20 beta = 1 / s2
---> 21 Mu, SIGMA = compute_posterior(PHI, t, alph, s2)
22 #
23 # Constant factor
<ipython-input-233-45cfae272a38> in compute_posterior(PHI, t, alph, s2)
2 M = PHI.shape[1]
3 beta = 1/s2
----> 4 H = beta*(PHI.T # PHI) + alph*np.eye(M)
5 SIGMA = np.linalg.inv(H)
6 Mu = beta * (SIGMA # (PHI.T # t))
ValueError: operands could not be broadcast together with shapes (100,) (8,8)
'
H = beta*(PHI.T # PHI) + alph*np.eye(M)
split operations in this line and figure out which one is throwing errors
If your logic is ok, check if all matrices have the shape that you expect.
If shapes are ok note that # is matrix multiplication and * is elementwise multiplication.
Nex time you post code try to include smaller part that is more readable or include code that everyone will be able to execute, to debug it.
Related
I am trying to show the monte carlo barrier prices for different number of simultations in the x axis. This is what i tried so far but i'm getting the error -> ValueError: x and y must have same first dimension, but have shapes (10,) and (5,).
I am new to python and as hard as i try i cannot find the error
import numpy as np
import numpy.random as npr
import matplotlib.pyplot as plt
def mc_single_barrier_do(S0, K, T, H, r, vol, N, M):
# Constants
dt = T / N # change in time
nudt = (r - 0.5 * vol ** 2) * dt # deterministic component
volsdt = vol * np.sqrt(dt) # diffusion coefficient
erdt = np.exp(r * dt) # discount factor
# Standard Error Placeholders
sum_CT = 0
sum_CT2 = 0
# Monte Carlo Method
for i in range(M):
# Barrier Crossed Flag
BARRIER = False
St = S0
for j in range(N):
epsilon = np.random.normal()
Stn = St * np.exp(nudt + volsdt * epsilon)
St = Stn
Ptn = np.exp(-2. * (H - St) * (H - Stn) / (St ** 2. * volsdt ** 2.))
Pt = Ptn
if Pt >= npr.uniform():
BARRIER = True
if np.amin(St) > H and BARRIER == False:
CT = np.maximum(St - K, 0)
else:
CT = 0.
sum_CT = sum_CT + CT
sum_CT2 = sum_CT2 + CT * CT
C0_MC = np.exp(-r * T) * sum_CT / M
return C0_MC
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
assert (method in ['MC', 'AV', 'CV'])
mean_payoffs = np.zeros(int(np.ceil(max_sample / 10)))
if method == 'MC':
for n_sample in range(10, max_sample + 1, 10):
payoffs = mc_single_barrier_do(n_sample, S0, K, T, H, r, vol, N)
mean_payoffs[int(n_sample / 10 - 1)] = np.mean(payoffs)
return mean_payoffs
r = 0.1
vol = 0.2
T = 2
N = 20
dt = T / N
S0 = 50
K = 50
H = 45
max_sample = 100
MC_price_estimates = sim_iterator(S0, T, r, vol, K, H, max_sample, N, method='MC')
x_axis1 = range(10, max_sample + 1, 10)
plt.plot(x_axis1, MC_price_estimates)
plt.xlabel("No. of Simulations")
plt.ylabel("Estimated option price")
plt.title("Ordinary Monte Carlo Method")
plt.legend()
plt.show()
in your function definition you used:
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
while when using the function you used:
MC_price_estimates = sim_iterator(S0, T, r, vol, K, H, max_sample, N, method='MC')
python has positional arguments, which means the arguments are mapped according to their position, not their name, so in the first position is mapped to the first argument, which means S0 in the second line was mapped to max_sample in the first line, just fix the arguments arrangement, or use keyword arguments S0=S0.
MC_price_estimates = sim_iterator(S0=S0, T=T, r=r, vol=vol, K=K, H=H, max_sample=max_sample, N=N, method='MC')
this is what your code will look like when you fix all arguments to be keyword arguments.
def mc_single_barrier_do(S0, K, T, H, r, vol, N, M):
# Constants
dt = T / N # change in time
nudt = (r - 0.5 * vol ** 2) * dt # deterministic component
volsdt = vol * np.sqrt(dt) # diffusion coefficient
erdt = np.exp(r * dt) # discount factor
# Standard Error Placeholders
sum_CT = 0
sum_CT2 = 0
# Monte Carlo Method
for i in range(M):
# Barrier Crossed Flag
BARRIER = False
St = S0
for j in range(N):
epsilon = np.random.normal()
Stn = St * np.exp(nudt + volsdt * epsilon)
St = Stn
Ptn = np.exp(-2. * (H - St) * (H - Stn) / (St ** 2. * volsdt ** 2.))
Pt = Ptn
if Pt >= npr.uniform():
BARRIER = True
if np.amin(St) > H and BARRIER == False:
CT = np.maximum(St - K, 0)
else:
CT = 0.
sum_CT = sum_CT + CT
sum_CT2 = sum_CT2 + CT * CT
C0_MC = np.exp(-r * T) * sum_CT / M
return C0_MC
def sim_iterator(max_sample, N, S0, T, r, vol, K, H, method):
assert (method in ['MC', 'AV', 'CV'])
mean_payoffs = np.zeros(int(np.ceil(max_sample / 10)))
if method == 'MC':
for n_sample in range(10, max_sample + 1, 10):
payoffs = mc_single_barrier_do(M=n_sample,S0= S0, K=K, T=T, H=H, r=r, vol=vol, N=N)
mean_payoffs[int(n_sample / 10 - 1)] = np.mean(payoffs)
return mean_payoffs
r = 0.1
vol = 0.2
T = 2
N = 20
dt = T / N
S0 = 50
K = 50
H = 45
max_sample = 100
MC_price_estimates = sim_iterator(S0=S0, T=T, r=r, vol=vol, K=K, H=H, max_sample=max_sample, N=N, method='MC')
x_axis1 = range(10, max_sample + 1, 10)
plt.plot(x_axis1, MC_price_estimates)
plt.xlabel("No. of Simulations")
plt.ylabel("Estimated option price")
plt.title("Ordinary Monte Carlo Method")
plt.legend()
plt.show()
I am new to this, and tried to implement this algorithm by using uniform B-Spline. And I don't know where I did it wrong, the result just doesn't come out the way it supposed to be.
I don't know if the basis is wrong or the procedure of the PIA is wrong. Is there someone that could help me out? Thank you so much!!
I use Python to implement all this.
In my understanding, the PIA is taking the given point set, P, as control points at first(iteration 0), and use these control points to calculate a b-spline, Q. Then find the difference, d, between the P and Q. Let Q+d in each iteration, until d is small enough as the threshold you set at the beginning.
I use deboor-Cox algorithm for generating the basis matrix.
def b_spline_basis(i, p, u, nodeVector):
# p means the degree of the spline
if p == 0:
if (nodeVector[i] <= u) & (u <= nodeVector[i + 1]): # if u is between two knots, the basis would be 1
result = 1.0
else:
result = 0.0
else:
# calculate non-zero intervals
length1 = nodeVector[i + p] - nodeVector[i]
length2 = nodeVector[i + p + 1] - nodeVector[i + 1]
# calculate coefficients for basis functions
if length1 == 0: # specifically 0/0
alpha = 0
else:
alpha = (u - nodeVector[i]) / length1
if length2 == 0:
beta = 0
else:
beta = (nodeVector[i + p + 1] - u) / length2
# calculate basis functions recursively
result = alpha * b_spline_basis(i, p - 1, u, nodeVector) + beta * b_spline_basis(i + 1, p - 1, u, nodeVector)
return result
And I tried the lemniscate to test whether my implementation of PIA is okay or not.
import numpy as np
import math
from bspline import b_spline
import matplotlib.pyplot as plt
import matplotlib
from bspline_basis import b_spline_basis
matplotlib.use('TkAgg')
# lemniscate with 200 points
alpha = 1
theta = np.linspace(0, 2 * np.pi, num=200)
x_real = alpha * np.sqrt(2) * np.cos(theta) / (np.sin(theta) ** 2 + 1)
y_real = alpha * np.sqrt(2) * np.cos(theta) * np.sin(theta) / (np.sin(theta) ** 2 + 1)
# draw the real points on lemniscate
plt.scatter(x_real, y_real)
# degree of bspline is 3, number of control points is 8
degree = 3
n = 8
points = []
delta = np.linspace(0, 2 * np.pi, num=8)
# x and y are the x-axis and y-axis for the control points
x = alpha * np.sqrt(2) * np.cos(delta) / (np.sin(delta) ** 2 + 1)
y = alpha * np.sqrt(2) * np.cos(delta) * np.sin(delta) / (np.sin(delta) ** 2 + 1)
plt.scatter(x, y, color='maroon')
# calculate bspline basis matrix
def bspline_basis(n, degree, knotVector):
basis = np.zeros([n, n])
for i in range(n):
j = 0
for u in delta:
basis[i][j] = b_spline_basis(i, degree, u, knotVector)
# print('knot=', knot)
# print('basis_i=', basis, 'j=',j)
j = j + 1
return basis
a = min(delta)
b = max(delta)
knotVector = [a, a, a, a, *delta[2:-2], b, b, b, b]
# basis matrix is stored in bs
bs = bspline_basis(n, degree, knotVector)
# I think if the basis is right, this plot would be a b-spline curve, but it doesn't turn out that way. I'm also confused by this.
plt.plot(np.dot(bs, np.transpose(x)), np.dot(bs, np.transpose(y)), color='red')
# the difference between real control points with calculated value
dx = x - np.transpose(np.dot(bs, np.transpose(x)))
dy = y - np.transpose(np.dot(bs, np.transpose(y)))
# norm is going to store the norm of (dx, dy)
norm = np.zeros(n)
for i in range(len(dx)):
norm[i] = math.sqrt(dx[i] ** 2 + dy[i] ** 2)
# make the biggest norm to be the error
err = max(norm)
iteration = 0
print('iteration #', iteration, ', err = ', err)
# set the threshold for the algorithm to stop
tol = 0.2
# in while loop, calculate the difference in each loop, until error is smaller than the threshold
while err > tol:
iteration = iteration + 1
x = x + dx
y = y + dy
dx = x - np.transpose(np.dot(bs, np.transpose(x)))
dy = y - np.transpose(np.dot(bs, np.transpose(y)))
for i in range(len(dx)):
norm[i] = math.sqrt(dx[i] ** 2 + dy[i] ** 2)
err = max(norm)
print('iteration #', iteration, ', err = ', err)
x_inter = np.transpose(np.dot(bs, np.transpose(x)))
y_inter = np.transpose(np.dot(bs, np.transpose(y)))
plt.show()
But the result is not even close. The err printed in each iteration gets bigger and bigger.
iteration # 0 , err = 0.8978393078534154
iteration # 1 , err = 0.5572305648715149
iteration # 2 , err = 0.8814649114823587
iteration # 3 , err = 1.406648477874589
iteration # 4 , err = 2.2515402019886657
iteration # 5 , err = 3.610001808299592
iteration # 6 , err = 5.794725750733798
iteration # 7 , err = 9.309544995196921
iteration # 8 , err = 14.966156756400013
iteration # 9 , err = 24.072299683891867
iteration # 10 , err = 38.73507669530552
iteration # 11 , err = 62.34988787737978
iteration # 12 , err = 100.3885976037046
iteration # 13 , err = 161.67015869470632
iteration # 14 , err = 260.40916333350236
iteration # 15 , err = 419.5188341631952
iteration # 16 , err = 675.9369969104991
iteration # 17 , err = 1089.2146572938898
iteration # 18 , err = 1755.3667774904786
iteration # 19 , err = 2829.2109590140344
iteration # 20 , err = 4560.398039137244
iteration # 21 , err = 7351.530766709586
iteration # 22 , err = 11851.91790312345
iteration # 23 , err = 19108.824114848438
iteration # 24 , err = 30811.492573031916
iteration # 25 , err = 49684.87189301904
iteration # 26 , err = 80124.93280280002
iteration # 27 , err = 129223.88403951934
iteration # 28 , err = 208424.68577890267
iteration # 29 , err = 336191.3189164541
iteration # 30 , err = 542318.7082430203
iteration # 31 , err = 874889.5879288138
iteration # 32 , err = 1411504.6936387809
iteration # 33 , err = 2277412.443263706
iteration # 34 , err = 3674778.915040246
...
The printed lines are too long, I won't show them all. But you get the point.
Beside, the plot is also wierd. And I just don't know where when wrong, and I upset my for days.
Is there someone can help with this? Thank you so so much!! I'm really confused right now, hoping there is someone can help me out. TAT
There are a few things we need to take care of.
First, I will put b_spline_basis into a separate file. It was almost correct but there are two changes. The intervals where the degree zero basis functions evaluate to 1 had to be adapted so that the basis functions sum up to one on the entire interval [a, b] (your version evaluated to more in the knots). This problem happens quite often, cf. e.g. here. Also, the 0/0 case needed 1 instead of 0 for alpha and beta:
def b_spline_basis(i, p, u, knotVector):
# p means the degree of the spline
if p == 0:
# The support is closed from left but open from the right ...
if (i != len(knotVector) - 2):
if ((knotVector[i] <= u) & (u < knotVector[i + 1])):
result = 1.0
else:
result = 0.0
# ... unless it is the last one, which is closed from both sides.
else:
if ((knotVector[i] <= u) & (u <= knotVector[i + 1])):
result = 1.0
else:
result = 0.0
else:
# calculate non-zero intervals
length1 = knotVector[i + p] - knotVector[i]
length2 = knotVector[i + p + 1] - knotVector[i + 1]
# calculate coefficients for basis functions
if length1 == 0: # specifically 0/0
alpha = 1 # You had 0 here.
else:
alpha = (u - knotVector[i]) / length1
if length2 == 0:
beta = 1 # You had 0 here as well.
else:
beta = (knotVector[i + p + 1] - u) / length2
# calculate basis functions recursively
result = alpha * b_spline_basis(i, p - 1, u, knotVector) + beta * b_spline_basis(i + 1, p - 1, u, knotVector)
return result
Second, I put also bspline_basis [sic] into a separate file. It is almost identical to your version but the matrix is not necessarily square in general. I would also strongly advise to rename the function; the resulting matrix is a transpose of what is usually called collocation matrix.
import numpy as np
from b_spline_basis import b_spline_basis
# calculate bspline basis matrix
def bspline_basis(n, degree, knotVector, delta):
basis = np.zeros([n, delta.size])
for i in range(n):
j = 0
for u in delta:
basis[i][j] = b_spline_basis(i, degree, u, knotVector)
# print('knot=', knot)
# print('basis_i=', basis, 'j=',j)
j = j + 1
return basis
Finally, I throw in a function for plotting a B-spline (as a curve) given its control points etc.
import numpy as np
from b_spline_basis import b_spline_basis
def plot_bspline(plt, num_samples, degree, knotVector, x_cps, y_cps, color):
beg = knotVector[0]
end = knotVector[-1]
num_cps = len(x_cps)
x_curve = np.zeros(num_samples)
y_curve = np.zeros(num_samples)
for i in range(num_samples):
for j in range(num_cps):
t_loc = i / (num_samples-1)
t = beg * (1 - t_loc) + end * t_loc
x_curve[i] += x_cps[j] * b_spline_basis(j, degree, t, knotVector)
y_curve[i] += y_cps[j] * b_spline_basis(j, degree, t, knotVector)
plt.plot(x_curve, y_curve, color=color)
Now we get back to your code, the few corrections are commented. In general, there seemed to be three sources of confusion:
The results of bspline_basis had to be transposed, because they are a transposed collocation matrix.
Evaluating using bspline_basis does not give you a B-spline as a curve but only its values in delta.
It is important to distinguish between x_target, y_target (values of the lemniscate that you want to approximate) and x_cps, y_cps (B-spline control points in the current iteration). You called both of them x, y.
import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')
from b_spline_basis import b_spline_basis
from bspline_basis import bspline_basis
from plot_bspline import plot_bspline
# lemniscate with 200 points
alpha = 1
theta = np.linspace(0, 2 * np.pi, num=200)
x_real = alpha * np.sqrt(2) * np.cos(theta) / (np.sin(theta) ** 2 + 1)
y_real = alpha * np.sqrt(2) * np.cos(theta) * np.sin(theta) / (np.sin(theta) ** 2 + 1)
# draw the real points on lemniscate
plt.scatter(x_real, y_real)
# degree of bspline is 3, number of control points is 8
degree = 3
n = 8
points = []
delta = np.linspace(0, 2 * np.pi, num=8)
# x_target and y_target are the values we want to approximate.
# They will be used as starting values for the control points as well.
x_target = alpha * np.sqrt(2) * np.cos(delta) / (np.sin(delta) ** 2 + 1)
y_target = alpha * np.sqrt(2) * np.cos(delta) * np.sin(delta) / (np.sin(delta) ** 2 + 1)
plt.scatter(x_target, y_target, color='maroon')
a = min(delta)
b = max(delta)
knotVector = [a, a, a, a, *delta[2:-2], b, b, b, b]
# basis matrix is stored in bs
bs = bspline_basis(n, degree, knotVector, delta)
# I think if the basis is right, this plot would be a b-spline curve, but it doesn't turn out that way. I'm also confused by this.
# The transpositions were wrong.
# Also, using bs does not give you a B-spline as a curve but only its values evaluated at delta, i.e., at 8 points.
plt.plot(np.dot(np.transpose(bs), x_target), np.dot(np.transpose(bs), y_target), color='red')
# If you also plot the B-spline as curve that uses x_target and y_target as control points, you will see that the red curve connects 8 of its values.
plot_bspline(plt, 100, 3, knotVector, x_target, y_target, 'green')
# Now to PIA.
# The control points in the first iteration will be the initial values.
x_cps = x_target
y_cps = y_target
# Then we have a difference between the target values and the corresponding values of our B-spline.
dx = x_target - np.transpose(np.dot(np.transpose(bs), x_cps))
dy = y_target - np.transpose(np.dot(np.transpose(bs), y_cps))
# norm is going to store the norm of (dx, dy)
norm = np.zeros(n)
for i in range(len(dx)):
norm[i] = math.sqrt(dx[i] ** 2 + dy[i] ** 2)
# make the biggest norm to be the error
err = max(norm)
iteration = 0
print('iteration #', iteration, ', err = ', err)
# set the threshold for the algorithm to stop
tol = 1e-5
# in while loop, calculate the difference in each loop, until error is smaller than the threshold
while err > tol and iteration < 100:
iteration = iteration + 1
# We change the control points ...
x_cps = x_cps + dx
y_cps = y_cps + dy
# ... and compute the difference from the target (which is constant)!
dx = x_target - np.transpose(np.dot(np.transpose(bs), x_cps))
dy = y_target - np.transpose(np.dot(np.transpose(bs), y_cps))
for i in range(len(dx)):
norm[i] = math.sqrt(dx[i] ** 2 + dy[i] ** 2)
err = max(norm)
print('iteration #', iteration, ', err = ', err)
x_inter = np.transpose(np.dot(np.transpose(bs), x_cps))
y_inter = np.transpose(np.dot(np.transpose(bs), y_cps))
# If I plot the way you did, I will again not get a B-spline as a curve but the values of the B-spline evaluated at delta. Notice that it passes the maroon points.
plt.plot(x_inter, y_inter, color='yellow')
# Let's now plot the entire B-spline as a curve. Notice that it passes through the maroon points.
plot_bspline(plt, 100, 3, knotVector, x_cps, y_cps, 'magenta')
plt.show()
If we now have a look at the plot, there is quite a lot happening:
The blue points are the samples of the lemniscate, i.e., the input.
The maroon points are the eight points on the lemniscate that we will be approximating (there seem to be only seven, since the first and last ones coincide).
The green curve is the initial guess, i.e., a B-spline that uses the maroon points as its control points.
The red polygon uses bspline_basis to connect the values of the green B-spline in the parameter values in delta. This is a corrected version of your red curve.
The magenta curve is the final guess, i.e., a B-spline that approximates the maroon points up to tol.
The yellow curve uses bspline_basis to connect the values of the magenta B-spline along delta. This is a corrected version of your x_inter, y_inter.
I wish you good luck with further B-spline experiments. If you are also into neural networks, you might enjoy a recent paper by my friends that investigated the connection between LSPIA and gradient descent:
Dany Rios and Bert Jüttler: LSPIA,(stochastic) gradient descent, and parameter correction. Journal of Computational and Applied Mathematics 406 (2022): 113921 (preprint)
implement a new function to calculate the new objective function and gradients
Got following error
for the Stochastic Gradient descent.
I don't know what seems to be the problem
as my matrix is already 30 by 1
def stochastic_objective_gradient(w, xi, yi, lam):
d = xi.shape[0]
yx = yi * xi # 1-by-d matrix
yxw = float(numpy.dot(yx, w)) # scalar
# calculate objective function Q_i
loss = numpy.log(1 + numpy.exp(-yxw)) # scalar
reg = lam / 2 * numpy.sum(w * w) # scalar
obj = loss + reg
# calculate stochastic gradient
g_loss = -yx.T / (1 + numpy.exp(yxw)) # d-by-1 matrix
g = g_loss + lam * w # d-by-1 matrix
return obj, g
def sgd(x, y, lam, stepsize, max_epoch=100, w=None):
n, d = x.shape
objvals = numpy.zeros(max_epoch) # store the objective values
if w is None:
w = numpy.zeros((d, 1)) # zero initialization
for t in range(max_epoch):
# randomly shuffle the samples
rand_indices = numpy.random.permutation(n)
x_rand = x[rand_indices, :]
y_rand = y[rand_indices, :]
objval = 0 # accumulate the objective values
for i in range(n):
xi = x_rand[i, :] # 1-by-d matrix
yi = float(y_rand[i, :]) # scalar
obj, g = stochastic_objective_gradient(w, xi, yi, lam)
objval += obj
w -= stepsize * g
stepsize *= 0.9 # decrease step size
objval /= n
objvals[t] = objval
print('Objective value at epoch t=' + str(t) + ' is ' + str(objval))
return w, objvals
What can be done to match the shape?
```
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-195-06f44b846812> in <module>()
3 lam = 0
4 stepsize = 0.1
----> 5 w, objvals_sgd = sgd(x_train, y_train, lam, stepsize)
<ipython-input-79-54d9a7949c9d> in sgd(x, y, lam, stepsize, max_epoch, w)
33 obj, g = stochastic_objective_gradient(w, xi, yi, lam)
34 objval += obj
---> 35 w -= stepsize * g
36
37 stepsize *= 0.9 # decrease step size
ValueError: non-broadcastable output operand with shape (30,1) doesn't match the broadcast shape (30,30)
```
I have written the following code for a chemical reaction kinetics assignment. The problem actually involves rabbits being born and leaving a farm instead of reactions. I'm asked to develop an Explicit Euler method program to model the rabbit population.
My program was running fine (i.e. I wasn't receiving any errors but wasn't getting the results I wanted) until just recently where I've been getting the ValueError (ValueError: setting an array element with a sequence.) message. I'm unsure of what I did to my code to prompt the error.
Any help would be appreciated.
def explicit_euler(df, x0, h, n):
# df - ODE that you wish to solve numerically
# x0 - initials values for ODE
# h - step size
# n - number of steps
for i in range(0, len(x0)):
N = np.zeros((len(x0), n))
t = 0
N[i, 0] = x0[i]
for j in range(0, n - 1):
N[i, j + 1] = N[i, j] + h * df(t, N[i, j])
t += h
return N
def df(t, N):
return [(k2 - k5) * t * N,
(k3 - k4) * t * N,
(k1 - k2 - k3 - (k6 * N)) * t * N]
N0 = [2., 10., 0.] # initial number of rabbits [Male, Female, Baby]
# "Reaction rate" coefficients
k1 = 3.5 # [events/rabbits month]
k2 = k3 = 0.15 # [events/rabbits month]
k4 = 0.1 # [events/rabbits month]
k5 = 0.5 # [events/rabbits month]
k6 = 0.1 # [events/rabbits^2 month]
h = 1 # time steps [month]
tspan = 120 # length of time [month]
n = int(tspan / h) # number of time steps
N = explicit_euler(df, N0, h, n)
t = np.linspace(0, tspan, n)
plot1, = plt.plot(t, N[0, :])
plot2, = plt.plot(t, N[1, :])
plot3, = plt.plot(t, N[2, :])
plt.xlabel('Time [months]')
plt.ylabel('Rabbits')
plt.legend((plot1, plot2, plot3), ('Male', 'Female', 'Babies'))
plt.show()
print(N)
EDIT: Forgot to include the error traceback.
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-d31ce8d859bf> in <module>()
39 n = int(tspan / h) # number of time steps
40
---> 41 N = explicit_euler(df, N0, h, n)
42 t = np.linspace(0, tspan, n)
43
<ipython-input-4-d31ce8d859bf> in explicit_euler(df, x0, h, n)
14 for j in range(0, n - 1):
15
---> 16 N[i, j + 1] = N[i, j] + h * df(t, N[i, j])
17 t += h
18
ValueError: setting an array element with a sequence.
I am trying to implement GMM Clustering for both 24 Dimension feature vector and 32 dimension feature vector, where assignment of initial parameters are done by Kmeans algorightm (K mean clustering is providing cluster centers - MU - only).
I am following this link, where it's implemented only for 2D feature vector and predefined Mu and sigma.
If anyone have the code for GMM clustering kindly post.
Predefined Lib for GMM is also there in sklearn, but it's not giving me likelyhood for each iteration. sklearn GMM
def kmeans(dataSet, k, c):
# 1. Randomly choose clusters
rng = np.random.RandomState(c)
p = rng.permutation(dataSet.shape[0])[:k]
centers = dataSet[p]
while True:
labels = pairwise_distances_argmin(dataSet, centers)
new_centers = np.array([dataSet[labels == i].mean(0) for i in range(k)]
if np.all(centers == new_centers):
break
centers = new_centers
cluster_data = [dataSet[labels == i] for i in range(k)]
l = []
covs = []
for i in range(k):
l.append(len(cluster_data[i]) * 1.0 / len(dataSet))
covs.append(np.cov(np.array(cluster_data[i]).T))
return centers, l, covs, cluster_data
return new_mu, new_covs, cluster_data
class gaussian_Mix_Model:
def __init__(self, k = 8, eps = 0.0000001):
self.k = k ## number of clusters
self.eps = eps ## threshold to stop `epsilon`
def calculate_Exp_Maxim(self, X, max_iters = 1000):
# n = number of data-points, d = dimension of data points
n, d = X.shape
mu, Cov = [], []
for i in range(1,k):
new_mu, new_covs, cluster_data = kmeans(dataSet, k, c)
# Initialize new
mu[k] = new_mu
Cov[k]= new_cov
# initialize the weights
w = [1./self.k] * self.k
R = np.zeros((n, self.k))
### LLhoods
LLhoods = []
P = lambda mu, s: np.linalg.det(s) ** -.5 ** (2 * np.pi) ** (-X.shape[1]/2.) \
* np.exp(-.5 * np.einsum('ij, ij -> i',\
X - mu, np.dot(np.linalg.inv(s) , (X - mu).T).T ) )
# Iterate till max_iters iterations
while len(LLhoods) < max_iters:
# Expectation Calcultion
## membership for each of K Clusters
for k in range(self.k):
R[:, k] = w[k] * P(mu[k], Cov[k])
# Finding the log likelihood
LLhood = np.sum(np.log(np.sum(R, axis = 1)))
# Now store the log likelihood to the list.
LLhoods.append(LLhood)
# Number of data points to each clusters
R = (R.T / np.sum(R, axis = 1)).T
N_ks = np.sum(R, axis = 0)
# Maximization and calculating the new parameters.
for k in range(self.k):
# Calculate the new means
mu[k] = 1. / N_ks[k] * np.sum(R[:, k] * X.T, axis = 1).T
x_mu = np.matrix(X - mu[k])
# Calculate new cov
Cov[k] = np.array(1 / N_ks[k] * np.dot(np.multiply(x_mu.T, R[:, k]), x_mu))
# Calculate new PiK
w[k] = 1. / n * N_ks[k]
# check for convergence
if (np.abs(LLhood - LLhoods[-2]) < self.eps) and (iteration < max_iters): break
else:
Continue
from collections import namedtuple
self.params = namedtuple('params', ['mu', 'Cov', 'w', 'LLhoods', 'num_iters'])
self.params.mu = mu
self.params.Cov = Cov
self.params.w = w
self.params.LLhoods = LLhoods
self.params.num_iters = len(LLhoods)
return self.params
# Call the GMM to find the model
gmm = gaussian_Mix_Model(3, 0.000001)
params = gmm.fit_EM(X, max_iters= 150)
# Plotting of Log-Likelihood VS Iterations.
plt.plot(LLhoods[0])
plt.savefig('Dataset_2A_GMM_Class_1_K_16.png')
plt.clf()
plt.plot(LLhoods[1])
plt.savefig('Dataset_2A_GMM_Class_2_K_16.png')
plt.clf()
plt.plot(LLhoods[2])
plt.savefig('Dataset_2A_GMM_Class_3_K_16.png')
plt.clf()