2

Basic Background

I am working on some code to simplify training SVMs for data with varying numbers of features, and visualizing the decision boundaries of these SVMs using "slices" specified by the user. If I have n features in my data set and m samples, I generate an (n+1)-dimensional meshgrid where each slice along the first index is an m x m x ... mesh of dimension n. I can then use my SVM to classify each data point in my meshgrid.

What I want to do next is plot a slice of these results in any two dimensions specified by the user. I have code that plots what I want when the data only has two features, but as soon as I add a third I start running into indexing problems.

Problem Statement

Say I have a three-dimensional matrix, predictions, and I want to plot these predictions over all of the values in my meshgrid mesh associated with index0=0 and index1=1, as well as the training data in those dimensions. I can do this with a function call like:

import matplotlib.pyplot as plt
plt.contourf(mesh[index0,:,:,0], mesh[index1,:,:,0], pred[:,:,0])
plt.scatter(samples[:,index0], samples[:,index1], c=labels)
plt.show()

What I want to know is how I can build my indexing arrays dynamically so that if index0=0 and index1=1, we get the above code, but if index0=1 and index1=2, we would get:

plt.contourf(mesh[index0,0,:,:], mesh[index1,0,:,:], pred[0,:,:])

and if index0=0 and index1=2, we would get:

plt.contourf(mesh[index0,:,0,:], mesh[index1,:,0,:], pred[:,0,:])

How can I go about building these dynamically? Is there a better way to go about this in general for cases where I may not know ahead of time how many features the data is going to have?

More Details

I attempted something like:

mesh_indices0 = [0]*len(mesh.shape)
mesh_indices0[0] = index0
mesh_indices0[index0+1] = ':'    # syntax error: I cannot add this dynamically
mesh_indices0[index1+1] = ':'    # same problem

I also tried going at it from the opposite direction with mesh_indices = [:]*len(mesh.shape), but that is invalid syntax as well. I thought about trying something like:

mesh_indices[index0+1] = np.r_[:len(samples[:, 1])]

where samples is my m x n set of observations. This seemed really clunky to me though, so I figured there had to be a better way.

1 Answer 1

1

I'm not sure that I fully understand what you're trying to do, but if you want to manipulate slices, you should use the python slice object:

mesh[index0,0,:,:]

is equivalent to:

mesh[index0,0,slice(0,mesh.shape[2]),slice(0,mesh.shape[3])]

Also note that you can index with a list or tuple of slices and indices:

inds = (index0, 0, slice(0,mesh.shape[2]), slice(0,mesh.shape[3]))
mesh[inds]

Putting it all together, you can make a list of :-equivalent slice objects, then replace the appropriate one with your concrete index. Or, go the other way:

mesh_indices = [0]*len(mesh.shape)
mesh_indices[0] = index0
mesh_indices[index0+1] = slice(0, mesh.shape[index0+1])
mesh_indices[index1+1] = slice(0, mesh.shape[index1+1])
Sign up to request clarification or add additional context in comments.

1 Comment

That seems to do exactly what I want it to. Thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.