了解这个lambda函数如何工作

4

我曾经认为自己理解lambda函数的工作原理,尽管我自己不使用它们。但是下面这个来自这篇教程的lambda函数完全让我困惑:

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

那很容易。更多内容:
# 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)

现在有一句话我不太理解:
plot_decision_boundary(lambda x: clf.predict(x))

我已经多次阅读有关lambda的工作原理,但我仍然不明白这里的x如何传递之前正确的值。x如何映射到相关的值?

5个回答

11

Lambdas是匿名函数。Lambda体只能是表达式(函数可以放置的子集),因为它们必须与其他代码内联。

plot_decision_boundary(lambda x: clf.predict(x))可以重写为

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

这里更清楚地解释了正在发生的事情。 plot_decision_boundary获得一个可调用对象,并使用单个参数np.c_[xx.ravel(),yy.ravel() 调用它。

但是在这种情况下不应该使用lambda。你可以直接这样做:

plot_decision_boundary(clf.predict)

在Python教程的大传统中,lambda又一次被滥用了。


2
你是对的,它可以在不使用它的情况下正常工作。非常非常有趣。 - Ada Stra
我不明白变量x从哪里获取它的值。 - VMMF
@VMMF - 你是指lambda函数中的x参数还是plot_decision_boundary中的X?lambda函数不是必需的。它的x参数只是将它调用时的参数转发给它所调用的函数。而X是一个全局变量,在函数中可见。 - tdelaney
在你编写的函数中,为什么没有传递 x 参数:plot_decision_boundary(call_clf_predict)。是因为 x 在 plot_decision_boundary 函数内部后面被传递了吗? - VMMF

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

这行代码传递了一个接受单个参数的函数到方法中。当Lambda表达式被执行时,或者该方法被传入参数调用时,它将执行clf.predict(x)
在该方法内部,该函数被命名为pred_func并在此处使用其单个参数。
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])

所以运行的代码是:
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) 

2

plot_decision_boundary(pred_func)实际上需要三个输入:X,y,pred_func

如果clf.predict(x)只需要x作为其输入,则不需要lambda。但是,对于其他预测函数,可能需要更多的输入(例如func(parameters, x)作为pred_func),以及一个不带参数的外部函数plot_decision_boundary,我们需要从一开始就插入它们:

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

2

x 是你在这里传递的连接后的 Numpy 对象:

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

pred_func是传递给plot_decision_boundary()的参数;通过调用它,您调用由lambda定义的函数对象。上面的语句翻译为:

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

太好了,谢谢。现在我会做一些作业来深入了解! - Ada Stra

1
我们希望绘制轮廓线,因此需要为X轴、Y轴和相应的Z轴数值提供不同的坐标。
pred_func() is clf.predict(x), ie. the lambda function

因此,当您生成网格并将其连接起来(这是一个理解连接的好链接),并将其传递到pred_func中时,实际上是将lambda函数的x参数中的值传递给输出来自lambda函数clf.predict()的预测,即用于绘制轮廓的Z矩阵(输出z,对应于feature1和feature2的不同值)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接