Can I extend the default one?
Gerçekten değil. Varsayılan Tokenizer
, pyspark.ml.wrapper.JavaTransformer
'un bir alt sınıfıdır ve pyspark.ml.feature
'dan diğer transfromerler ve tahmin edicilerle aynıdır, gerçek işleme Scala karşılığı için temsil eder. Python'u kullanmak istediğinizden, doğrudan pyspark.ml.pipeline.Transformer
'u uzatmalısınız.
import nltk
from pyspark import keyword_only ## < 2.0 -> pyspark.ml.util.keyword_only
from pyspark.ml import Transformer
from pyspark.ml.param.shared import HasInputCol, HasOutputCol, Param
from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StringType
class NLTKWordPunctTokenizer(Transformer, HasInputCol, HasOutputCol):
@keyword_only
def __init__(self, inputCol=None, outputCol=None, stopwords=None):
super(NLTKWordPunctTokenizer, self).__init__()
self.stopwords = Param(self, "stopwords", "")
self._setDefault(stopwords=set())
kwargs = self._input_kwargs
self.setParams(**kwargs)
@keyword_only
def setParams(self, inputCol=None, outputCol=None, stopwords=None):
kwargs = self._input_kwargs
return self._set(**kwargs)
def setStopwords(self, value):
self._paramMap[self.stopwords] = value
return self
def getStopwords(self):
return self.getOrDefault(self.stopwords)
def _transform(self, dataset):
stopwords = self.getStopwords()
def f(s):
tokens = nltk.tokenize.wordpunct_tokenize(s)
return [t for t in tokens if t.lower() not in stopwords]
t = ArrayType(StringType())
out_col = self.getOutputCol()
in_col = dataset[self.getInputCol()]
return dataset.withColumn(out_col, udf(f, t)(in_col))
Örnek kullanım (ML - Features verileri): Özel Python Estimator
için
sentenceDataFrame = spark.createDataFrame([
(0, "Hi I heard about Spark"),
(0, "I wish Java could use case classes"),
(1, "Logistic regression models are neat")
], ["label", "sentence"])
tokenizer = NLTKWordPunctTokenizer(
inputCol="sentence", outputCol="words",
stopwords=set(nltk.corpus.stopwords.words('english')))
tokenizer.transform(sentenceDataFrame).show()
Bu cevap iç API bağlıdır ve Spark 2.0.3, 2.1 ile uyumludur ⚠
How to Roll a Custom Estimator in PySpark mllib görüyoruz. 1, 2.2.0 veya üstü (SPARK-19348). Önceki Spark sürümleriyle uyumlu kod için lütfen bkz. revision 8.
Bunu bir Boru Hattı'nda bir adım olarak uygulamaya çalıştım ve şu hatayı aldım: AttributeError: 'NLTKWordPunctTokenizer' nesnesi '_to_java' özelliğine sahip değil. Bu, Pipeline diski yazmaya çalıştığımda ortaya çıkar (bu adımı eklemeden önce iyi çalıştı). Tanımlanması gereken bazı sınıf yöntemleri var mıdır? –
@EvanZamir Evet, hem 'Pipeline' hem de 'PipelineModel' her aşamada '_to_java' komutunu uygular ve ilgili Java nesnesini kullanarak yüklenebilir. Ne yazık ki, bu aslında 'JavaWrapper' var varsayımı altında çalışır. Bununla ilgili bir JIRA'yı gördüğüm bu belirsiz anılarım var ama yanılıyor olabilirim. – zero323
Bu, sıfır323 mü? https://issues.apache.org/jira/browse/SPARK-17025 Görünüşe göre, bu sorun gerçekten dün yapıldı. –