Ich versuche, den Konstruktor für Pyspark-Pipeline zu wickeln. init Konstruktor und Affepatch im neu verpackten Konstruktor. Allerdings stoße ich auf einen Fehler, der mit der Art Pipeline zu tun zu haben scheint. init verwendet DekorateureWrapping pyspark Pipeline .__ init__ und Dekoratoren
Hier ist der Code, der tatsächlich funktioniert der Affe Patch:
def monkeyPatchPipeline():
oldInit = Pipeline.__init__
def newInit(self, **keywordArgs):
oldInit(self, stages=keywordArgs["stages"])
Pipeline.__init__ = newInit
Allerdings, wenn ich ein einfaches Programm laufen:
import PythonSparkCombinatorLibrary
from pyspark.ml import Pipeline
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.feature import HashingTF, Tokenizer
PythonSparkCombinatorLibrary.TransformWrapper.monkeyPatchPipeline()
tokenizer = Tokenizer(inputCol="text", outputCol="words")
hashingTF = HashingTF(inputCol=tokenizer.getOutputCol(),outputCol="features")
lr = LogisticRegression(maxIter=10, regParam=0.001)
pipeline = Pipeline(stages=[tokenizer, hashingTF, lr])
ich diesen Fehler:
Traceback (most recent call last):
File "C:\<my path>\PythonApplication1\main.py", line 26, in <module>
pipeline = Pipeline(stages=[tokenizer, hashingTF, lr])
File "C:<my path>PythonApplication1 \PythonSparkCombinatorLibrary.py", line 36, in newInit
oldInit(self, stages=keywordArgs["stages"])
File "C:\<pyspark_path>\pyspark\__init__.py", line 98, in wrapper
return func(*args, **kwargs)
File "C:\<pyspark_path>\pyspark\ml\pipeline.py", line 63, in __init__
kwargs = self.__init__._input_kwargs
AttributeError: 'function' object has no attribute '_input_kwargs'
Blick in den Pyspark Interfa Ich sehe diese Pipeline. init sieht wie folgt aus:
@keyword_only
def __init__(self, stages=None):
"""
__init__(self, stages=None)
"""
if stages is None:
stages = []
super(Pipeline, self).__init__()
kwargs = self.__init__._input_kwargs
self.setParams(**kwargs)
Und in Anbetracht der @keyword_only Dekorateur, ich kontrolliert auch, dass Code:
def keyword_only(func):
"""
A decorator that forces keyword arguments in the wrapped method
and saves actual input keyword arguments in `_input_kwargs`.
"""
@wraps(func)
def wrapper(*args, **kwargs):
if len(args) > 1:
raise TypeError("Method %s forces keyword arguments." % func.__name__)
wrapper._input_kwargs = kwargs
return func(*args, **kwargs)
return wrapper
ich total verwirrt bin sowohl darüber, wie dieser Code funktioniert in erster Linie und auch, warum es Probleme mit meinem eigenen Wrapper zu verursachen scheint. Ich sehe, dass Wrapper ein _input_kwargs Feld zu sich selbst hinzufügt, aber wie ist Pipeline .__ init__ über das Lesen dieses Feldes mit self .__ init __._ input_kwargs? Und warum passiert nicht das Gleiche, wenn ich Pipeline .__ init__ erneut einpacke?