Logistic Regression using Scipy's fmin_cg - python-2.7

I am trying to implement a logistic classifier using python. The goal is to train the algo to identify digits 0-9 using the mnist handwritten digits data set. However, fmin_cg seems to be changing the dimensions of my input arguments. I have tried reshaping the arguements inside cost() and gradient() with no luck; just more errors.
from scipy.io import loadmat
from numpy import shape, zeros, ones, dot, hstack, vstack, log, transpose, kron
from scipy.special import expit as sigmoid
import scipy.optimize
def cost(theta, X, y):
h = sigmoid( X.dot(theta) )
pos_class = y.T.dot( log(h) )
neg_class = (1.0-y).T.dot( log(1.0-h) )
cost = ((-1.0/m)*(pos_class+neg_class))
return cost
def gradient(theta, X, y):
h = sigmoid( X.dot(theta) )
grad = (1.0/m)*(X.T.dot((h-y)))
return grad
def one_vs_all(X, y, theta):
# add x1 feature,x1 = 1, to each example set
X = hstack( (ones((m,1)),X) )
# train the classifier for digit 9.0
temp_y = (y == 9.0)+0
result = scipy.optimize.fmin_cg( cost, fprime=gradient, x0=theta, \
args=(X, temp_y), maxiter=50, disp=False, full_output=True )
print result[1]
# Load data from Matlab file
data = loadmat('data.mat')
X,y = data['X'],data['y']
m,n = shape(X)
theta = zeros((n+1, 1))
one_vs_all(X, y, theta)
The error I receive:
Traceback (most recent call last):
File "/Users/jkarimi91/Documents/Digit Recognizer/Digit_Recognizer.py", line 36, in <module>
one_vs_all(X, y, theta)
File "/Users/jkarimi91/Documents/Digit Recognizer/Digit_Recognizer.py", line 26, in one_vs_all
args=(X, temp_y), maxiter=50, disp=False, full_output=True )
File "/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1092, in fmin_cg
res = _minimize_cg(f, x0, args, fprime, callback=callback, **opts)
File "/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 1156, in _minimize_cg
deltak = numpy.dot(gfk, gfk)
ValueError: shapes (401,5000) and (401,5000) not aligned: 5000 (dim 1) != 401 (dim 0)
[Finished in 1.0s with exit code 1]

With the current code, the cost & gradient function are each returning a 2-D array. For fmin_cg to function properly, these functions must each return a 1-D array (as noted by the documentation).

I know this might be a little late but this is supposed to work
.In your gradient function I got several memory errors,So I changed the code a little and added regularization, check it out
def gradients (theta,X,y,Lambda):
m,n = shape(X)
theta = reshape(theta,(n,1))
h = sigmoid(X.dot(theta))
h = h-y
theta[0,0] = 0
grad = ((X.T.dot(h)) / m) + (Lambda / m * theta)
return grad.ravel()

Related

Sympy returns a ConditionSet object when solving an equation, while TINspire returns a numerical value

Here is my python code:
import sympy as sym
x = sym.Symbol('x')
f = -0.077 * sym.Pow(x - 35.80, 2) + 100
f_prime = f.diff(x)
f_integrate = sym.integrate(sym.sqrt(1 + sym.Pow(f_prime, 2)), x)
I want to be able to write this integral and solve it with Sympy (so, I want to isolate the variable b).
UPDATE
Here is now my code.
f_integrate = sym.integrate(sym.sqrt(1 + sym.Pow(f_prime, 2))-c, (x, 0, b))
g = 100
for i in range(10, 72):
bi = sym.nsolve(f_integrate.subs(c,i), g)
g = bi
return g
This code work with the initial function I wrote (f(x)= -0.077 * sym.Pow(x - 35.80, 2) + 100), but with pretty much any other function, I got this error:
Traceback (most recent call last):
File "Dragon_Ball_-_Film_3_-_Effect - Test avec les bézier.py", line 543, in <module>
drawManager(line.copy())
File "Dragon_Ball_-_Film_3_-_Effect - Test avec les bézier.py", line 199, in drawManager
t = createT(FU, f, x, distanceNextSyllable)
File "Dragon_Ball_-_Film_3_-_Effect - Test avec les bézier.py", line 107, in createT
print(getPosition(f, x, 0, distanceNextSyllable))
File "Dragon_Ball_-_Film_3_-_Effect - Test avec les bézier.py", line 95, in getPosition
bi = sym.nsolve(f_integrate.subs(c,i), g)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\site-packages\sympy\utilities\decorator.py", line 88, in func_wrapper
return func(*args, **kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\site-packages\sympy\solvers\solvers.py", line 2937, in nsolve
x = sympify(findroot(f, x0, **kwargs))
File "C:\Users\Admin\AppData\Local\Programs\Python\Python38\lib\site-packages\mpmath\calculus\optimization.py", line 985, in findroot
raise ValueError('Could not find root within given tolerance. '
ValueError: Could not find root within given tolerance. (5.9604644775390625e-8 > 2.16840434497100886801e-19)
Try another starting point or tweak arguments.
The sympy solution seems to be correct, at least wolframalpha.com gives the same result for the integral.
It looks like you are using an older version of SymPy that allowed one to write integrate(Eq(x, y), x). The way to do this now is to write integrate(x - y, x). Doing so for your equation, and using nsolve to solve for the numerical value of b, after supplying a value for c, looks like this:
>>> from sympy.abc import b, c
>>> fc = integrate(sqrt(1 + f_prime**2)-c, (x,0,b))
>>> nsolve(fc.subs(c, 10), 111)
186.052268133373
If you have a range of c values to test, use the last solution for a given c as the guess for the next c. e.g. to calculate b for c in [10, 409]
g = 100
for i in range(10, 410):
bi = nsolve(fc.subs(c,i), g)
g = bi
(This takes about 12 seconds on a fairly slow computer.)

How to use pymc to find variables in initial state to match the final state to the observation?

I have an initial state which can be represented with Gaussian function, let's say F(x), with three free parameters "amplitude, centroid, sigma".
I have to sum up the F(x) with a transformation function, G(x)= exp(a*x)+b, with two free parameters a and b.
I want to use pymc to find these five free parameters so that the final state, F(x)+G(x), represents a Gaussian function with:
amplitude=3.05
centroid=5.45
sigma=5.47
I've looked at this link and various other questions and answers: Fit two normal distributions (histograms) with MCMC using pymc?
and have written the same code, but I don't know where I should enter the previous three values.
import numpy as np
import matplotlib.pyplot as pl
from scipy.optimize import curve_fit
import pymc as mc
def GaussFunc(x, A, mu, sigma):
return A * np.exp(-0.5 * ((x - mu) / sigma)**2)
def trFunc(x,a,b):
return np.exp(a*x)+b
interval=np.arange(0, 10, 0.05)
A_ini=2.0
mu_ini=3.0
sigma_ini=1.0
initial=GaussFunc(interval, A_ini, mu_ini, sigma_ini, )
intervalT=np.arange(0, np.pi, np.pi/200.0)
a_t=0.2
b_t=-2.0
transf= trFunc(intervalT,a_t,b_t,)
final=np.zeros(200)
final=initial+transf
est_centroid_one = mc.Uniform("est_centroid_one", 0, 10 )
est_sigma_one = mc.Uniform( "est_sigma_one", 0, 5 )
est_height_one = mc.Uniform( "est_height_one", 0, 5 )
est_a_two = mc.Uniform("est_a_two", 0, 1 )
est_b_two = mc.Uniform("est_b_two", -3, 3 )
precision= 1./mc.Uniform("std", 0, 1)**2
#mc.deterministic( trace = False)
def est_profile_1(x = interval, mu = est_centroid_one, sigma = est_sigma_one, A= est_height_one):
return GaussFunc( x, A, mu, sigma )
#mc.deterministic( trace = False)
def est_profile_2(x = intervalT, a = est_a_two, b = est_b_two):
return trFunc( x, a, b )
#mc.deterministic( trace = False )
def mean( profile_1 = est_profile_1, profile_2 = est_profile_2 ):
return profile_1 + profile_2
observations = mc.Normal("obs", mean, precision, value = final, observed = True)
model = mc.Model([est_centroid_one,
est_height_one,
est_sigma_one,
est_a_two,
est_b_two,
precision])
map_ = mc.MAP( model )
map_.fit()
mcmc = mc.MCMC( model )
mcmc.sample( 50000,40000 )
print est_centroid_one,est_height_one,est_sigma_one,est_a_two,est_b_two
Thank you

Bayesian Inference with PyMC3. Compilation error.

The following two codes do a simple bayesian inference in python using PyMC3. While the first code for exponential model compiles and run perfectly fine, the second one for a simple ode model, gives an error. I do not understand why one is working and the other is not. Please help.
Code #1
import numpy as np
import pymc3 as pm
def f(a,b,x,c):
return a * np.exp(b*x)+c
#Generating Data with error
a, b = 5, 0.2
xdata = np.linspace(0, 10, 21)
ydata = f(a, b, xdata,0.5)
yerror = 5 * np.random.rand(len(xdata))
ydata += np.random.normal(0.0, np.sqrt(yerror))
model = pm.Model()
with model:
alpha = pm.Uniform('alpha', lower=a/2, upper=2*a)
beta = pm.Uniform('beta', lower=b/2, upper=2*b)
mu = f(alpha, beta, xdata,0.5)
Y_obs = pm.Normal('Y_obs', mu=mu, sd=yerror, observed=ydata)
trace = pm.sample(100, tune = 50, nchains = 1)
Code #2
import numpy as np
import pymc3 as pm
def solver(I, a, T, dt):
"""Solve u'=-a*u, u(0)=I, for t in (0,T] with steps of dt."""
dt = float(dt) # avoid integer division
N = int(round(T/dt)) # no of time intervals
print N
T = N*dt # adjust T to fit time step dt
u = np.zeros(N+1) # array of u[n] values
t = np.linspace(0, T, N+1) # time mesh
u[0] = I # assign initial condition
for n in range(0, N): # n=0,1,...,N-1
u[n+1] = (1 - a*dt)*u[n]
return np.ravel(u)
# Generating data
ydata = solver(1,1.7,10,0.1)
yerror = 5 * np.random.rand(101)
ydata += np.random.normal(0.0, np.sqrt(yerror))
model = pm.Model()
with model:
alpha = pm.Uniform('alpha', lower = 1.0, upper = 2.5)
mu = solver(1,alpha,10,0.1)
Y_obs = pm.Normal('Y_obs', mu=mu, sd=yerror, observed=ydata)
trace = pm.sample(100, nchains=1)
The error is
Traceback (most recent call last):
File "1.py", line 27, in <module>
mu = solver(1,alpha,10,0.1)
File "1.py", line 16, in solver
u[n+1] = (1 - a*dt)*u[n]
ValueError: setting an array element with a sequence.
Please help.
The error is in this line:
mu = solver(1,alpha,10,0.1)
You are trying to pass alpha as a value, but alpha is a pymc3 distribution. The function solver only works when you provide a number in the second argument.
The code #1 works because this function
def f(a,b,x,c):
return a * np.exp(b*x)+c
returns a number.

How can I implement a joint hyerprior?

I'm trying to recreate results from Bayesian Data Analysis Third Edition.
Chapter 5 Section 3 concerns tumors in rats. a Hierarchical model is fit and the hyperprior used is not one of the densities included in pymc3.
The hyperprior is a*b*(a+b)^-2.5. Here is my attempt using pymc3.
import pymc3 as pm
with pm.Model() as model:
def ab_dist(x):
#Should be log density, from what I have read
a = x[0]
b = x[1]
return a+b-5/2*(a+b)
ab = pm.DensityDist('ab', ab_dist, shape = 2, testval=[2,2])
a = ab[0]
b = ab[1]
theta = pm.Beta('theta',alpha = a,beta = b)
Y= pm.Binomial('y', n = n, p = theta, observed = y)
At this stage, I am returned an error
ValueError: Input dimension mis-match. (input[0].shape[0] = 71, input[1].shape[0] = 20000)
What have I done wrong? Have I correctly implemented the density?

Interpolating 3d data at a single point in space (Python 2.7)

I have a point cloud in 4 dimensions, where each point in the cloud has a location and a value (x,y,z,Value). In addition, I have a 'special' point, S0, within the 3d point cloud; I've used this example to find the closest 10 points in the cloud, relative to S0. Now, I have a numpy array for each of the 10 closest points and their values. How can I interpolate these 10 points, to find the interpolated value at point S0? Example code is shown below:
import numpy as np
import matplotlib.pyplot as plt
numpoints = 20
linexs = 320
lineys = 40
linezs = 60
linexe = 20
lineye = 20
lineze = 0
# Create vectors of points
xpts = np.linspace(linexs, linexe, numpoints)
ypts = np.linspace(lineys, lineye, numpoints)
zpts = np.linspace(linezs, lineze, numpoints)
lin = np.dstack((xpts,ypts,zpts))
# Image line of points
fig = plt.figure()
ax = fig.add_subplot(211, projection='3d')
ax.set_xlim(0,365); ax.set_ylim(-85, 85); ax.set_zlim(0, 100)
ax.plot_wireframe(xpts, ypts, zpts)
ax.view_init(elev=12, azim=78)
def randrange(n, vmin, vmax):
return (vmax - vmin)*np.random.rand(n) + vmin
n = 10
for n in range(21):
xs = randrange(n, 0, 350)
ys = randrange(n, -75, 75)
zs = randrange(n, 0, 100)
ax.scatter(xs, ys, zs)
dat = np.dstack((xs,ys,zs))
ax.set_xlabel('X Label')
ax.set_xlim(0,350)
ax.set_ylabel('Y Label')
ax.set_ylim(-75,75)
ax.set_zlabel('Z Label')
ax.set_zlim(0,100)
ax = fig.add_subplot(212, projection='3d')
ax.set_xlim(0,365); ax.set_ylim(-85, 85); ax.set_zlim(0, 100)
ax.plot_wireframe(xpts,ypts,zpts)
ax.view_init(elev=12, azim=78)
plt.show()
dist = []
# Calculate distance from first point to all other points in cloud
for l in range(len(xpts)):
aaa = lin[0][0]-dat
dist.append(np.sqrt(aaa[0][l][0]**2+aaa[0][l][1]**2+aaa[0][l][2]**2))
full = np.dstack((dat,dist))
aaa = full[0][full[0][:,3].argsort()]
print(aaa[0:10])
A basic example. Note that the meshgrid is not needed for the interpolation, but only to make a fast ufunc to generate an example function A=f(x,y,z), here A=x+y+z.
from scipy.interpolate import interpn
import numpy as np
#make up a regular 3d grid
X=np.linspace(-5,5,11)
Y=np.linspace(-5,5,11)
Z=np.linspace(-5,5,11)
xv,yv,zv = np.meshgrid(X,Y,Z)
# make up a function
# see http://docs.scipy.org/doc/numpy/reference/ufuncs.html
A = np.add(xv,np.add(yv,zv))
#this one is easy enough for us to know what to expect at (.5,.5,.5)
# usage : interpn(points, values, xi, method='linear', bounds_error=True, fill_value=nan)
interpn((X,Y,Z),A,[0.5,0.5,0.5])
Output:
array([ 1.5])
If you pass in an array of points of interest, it will give you multiple answers.