4

I thought I understood how lambda functions work, though I don't use them myself. But the lambda below from this tutorial totally stumps me:

import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib

That was easy. More:

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X, y)

# Helper function to plot a decision boundary.
# If you don't fully understand this function don't worry, it just generates the contour plot below.

def plot_decision_boundary(pred_func):

    # Set min and max values and give it some padding
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    h = 0.01

    # Generate a grid of points with distance h between them
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    # Predict the function value for the whole gid
    Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # Plot the contour and training examples
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)

Now the line I don't understand:

plot_decision_boundary(lambda x: clf.predict(x))

I've read many times how lambdas work, but I just don't get how the x here passing the correct values from before. How is the x mapped to the relevant values?

5 Answers 5

11

lambdas are just anonymous functions. lambda bodies can only be an expression (as subset of what you can put into a function) because they have to fit inline with other code.

plot_decision_boundary(lambda x: clf.predict(x)) could be rewritten as

def call_clf_predict(x):
    return clf.predict(x)
plot_decision_boundary(call_clf_predict)

Here, its more clear what is going on. plot_decision_boundary gets a callable and calls it with the single parameter np.c_[xx.ravel(), yy.ravel()].

But lambda shouldn't have been used here in the first place. You could just do

plot_decision_boundary(clf.predict)

In the grand tradition of python tutorials, lambda is abused once again.

Sign up to request clarification or add additional context in comments.

4 Comments

You are right, it works without using it. Very, very interesting.
I don't understand where does variable x gets its value
@VMMF - are you referring to the x parameter in the lambda function or the X in plot_decision_boundary? The lambda wasn't necessary. its x parameter is just forwarding the paramter it was called with to the function it calls. The big X is a global variable, visible in the function.
In the function you wrote, why isn't x passed : plot_decision_boundary(call_clf_predict). Is it because x is passed later inside plot_decision_boundary?
4
plot_decision_boundary(lambda x: clf.predict(x))

This line is passing a function that takes a single argument into the method. When the lambda is evaluated, or the method is "called" with an argument x, it'll do clf.predict(x)

Within the method, that function is named pred_func and it is called with its single argument at

Z = pred_func(np.c_[xx.ravel(), yy.ravel()])

So the code that is ran is

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) 

Comments

2

x is the concatenated Numpy object you pass in here:

Z = pred_func(np.c_[xx.ravel(), yy.ravel()])

pred_func is the argument to plot_decision_boundary(); by calling it you call the function object defined by the lambda. The above line translates to:

clf.predict(np.c_[xx.ravel(), yy.ravel()])

1 Comment

That was great, thanks. Now I'll do some homework to get a deeper insight!
2

plot_decision_boundary(pred_func) actually requires three input X,y,pred_func

If clf.predict(x) only takes in x as its input, then no need for lambda. However, for other prediction functions, which may require more inputs ( such as func(parameters, x) as the pred_func), and an outer function (plot_decision_boundary) that doesn't take in parameters, we need to insert them from the beginning:

plot_decision_boundary(lambda x: func(parameters, x), X, y)    

Comments

1

We want to plot the contours, so we need different coordinates for X axis, Y axis and the corresponding values of Z axis.

pred_func() is clf.predict(x), ie. the lambda function

So when you generate the meshgrid and concatenate it (heres a good link to understand concatenation) and pass it into pred_func what you're doing is actually passing the values in the x argument of the lambda function which outputs the predictions from the lambda function clf.predict()ie. Z Matrix (outputs z, corresponding to different values of feature1 and feature2) which is used to plot the contours.

Comments

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.