Pyspark MLlib 中的自定义算法:'function' 对象没有属性“_input_kwargs”

Custom algorithm in Pyspark MLlib: 'function' object has no attribute '_input_kwargs'

我正在尝试在 Pyspark 中运行我自己的 MLlib 管道算法,但我无法克服以下错误:

'function' object has no attribute '_input_kwargs'

我已经将我的代码缩减为:

from pyspark import keyword_only
from pyspark.ml.param import Params

class SimpleAlgorithm(Params):

    @keyword_only
    def __init__(self, threshold=2.0):

        super(SimpleAlgorithm, self).__init__()
        kwargs = self.__init__._input_kwargs
        self.setParams(**kwargs)

    @keyword_only
    def setParams(self, threshold=2.0):

        kwargs = self.setParams._input_kwargs
        return self._set(**kwargs)

但是当我这样做时:

test_alg = SimpleAlgorithm()

我收到上面显示的错误。请问有人知道我做错了什么吗? (我看到了一个明显相关的问题 但是,作为一个 Python 新手,我不确定我是否理解答案或者它是否与我相关。)

EDIT 如果它有帮助,这里是在 Spark 2.1 Databricks 集群上 运行 之后错误的完整堆栈跟踪:

----> 1 test_alg = SimpleAlgorithm()

/databricks/spark/python/pyspark/__init__.py in wrapper(self, *args, **kwargs)
     99             raise TypeError("Method %s forces keyword arguments." % func.__name__)
    100         self._input_kwargs = kwargs
--> 101         return func(self, **kwargs)
    102     return wrapper
    103 

<ipython-input-12-dcb888c97487> in __init__(self, threshold)
      8 
      9         #super(SimpleAlgorithm, self).__init__()
---> 10         kwargs = self.__init__._input_kwargs
     11         self.setParams(**kwargs)
     12 

AttributeError: 'function' object has no attribute '_input_kwargs'

问题出在这一行:

kwargs = self.__init__._input_kwargs

您正在尝试访问 function 对象 self.__init__ 上的属性 _input_kwargs,它不存在。

如果您只是想设置 threshold 属性,我通常会这样做:

class SimpleAlgorithm(Params):

    @keyword_only
    def __init__(self, threshold=2.0):
        super(SimpleAlgorithm, self).__init__()
        self.threshold = threshold

编辑:

我检查了您链接的源代码,发现 keyword_only 包装器的实现从 Spark 2.1 更改为 Spark 2.2。您的代码确实适用于 Spark 2.1,但如果您使用的是 Spark 2.2,则应将其替换为:

from pyspark import keyword_only
from pyspark.ml.param import Params

class SimpleAlgorithm(Params):

    @keyword_only
    def __init__(self, threshold=2.0):

        super(SimpleAlgorithm, self).__init__()
        kwargs = self._input_kwargs
        self.setParams(**kwargs)

    @keyword_only
    def setParams(self, threshold=2.0):

        kwargs = self._input_kwargs
        return self._set(**kwargs)

Link to v2.2 keyword_only implementation

Link to v2.2 example usage

我想为@timchap 的回答做贡献。如果您在使用 Spark 2.1.0Zeppelin 0.7.3 上工作,但您的代码在 spark 2.2.0 上运行,您可以检查版本并以这种方式获取兼容版本

from pyspark import keyword_only
from pyspark.ml.param import Params

class SimpleAlgorithm(Params):

    @keyword_only
    def __init__(self, threshold=2.0):

        super(SimpleAlgorithm, self).__init__()
        if spark.version.startswith('2.1'):
            kwargs = self.__init__._input_kwargs
        else:
            kwargs = self._input_kwargs
        self.setParams(**kwargs)

    @keyword_only
    def setParams(self, threshold=2.0):

        if spark.version.startswith('2.1'):
            kwargs = self.__init__._input_kwargs
        else:
            kwargs = self._input_kwargs
        return self._set(**kwargs)