2016-05-17 9 views
4

pySpark mllibで単純なカスタム見積もりを作成しようとしています。私はhereを持っていますが、カスタムトランスフォーマーを書くことは可能ですが、私はエスティメーターでそれを行う方法がわかりません。私はまた、@keyword_onlyが何をするのか理解していないし、なぜ多くのセッターとゲッターが必要なのですか? Scikit-学ぶsee here(カスタムモデルのための適切な文書を持っているように見えるが、pySparkはないPySpark mllibでカスタム見積もりをロールバックする方法

例モデルの疑似コード:。一般的に何のドキュメントが原因スパーク1.6 /用としてはありません話す

class NormalDeviation(): 
    def __init__(self, threshold = 3): 
    def fit(x, y=None): 
     self.model = {'mean': x.mean(), 'std': x.std()] 
    def predict(x): 
     return ((x-self.model['mean']) > self.threshold * self.model['std']) 
    def decision_function(x): # does ml-lib support this? 

答えて

9

2.0関連のAPIのほとんどは公共的なものではない。それはスパーク2.1.0(SPARK-7146を参照)に変更する必要があります。それが与えられたとするために、特定の規則に従わなければならないので

APIが比較的複雑であるTransformerまたはEstimator互換性Pipeline API。これらのメソッドの中には、読み書き、グリッド検索などの機能に必要なものがあります。 keyword_onlyのようなその他のものは単純なヘルパーに過ぎず、厳密には要求されません。

from pyspark.ml.pipeline import Estimator, Model, Pipeline 
from pyspark.ml.param.shared import * 
from pyspark.sql.functions import avg, stddev_samp 


class HasMean(Params): 

    mean = Param(Params._dummy(), "mean", "mean", 
     typeConverter=TypeConverters.toFloat) 

    def __init__(self): 
     super(HasMean, self).__init__() 

    def setMean(self, value): 
     return self._set(mean=value) 

    def getMean(self): 
     return self.getOrDefault(self.mean) 

標準偏差パラメータ:

class HasStandardDeviation(Params): 

    stddev = Param(Params._dummy(), "stddev", "stddev", 
     typeConverter=TypeConverters.toFloat) 

    def __init__(self): 
     super(HasStandardDeviation, self).__init__() 

    def setStddev(self, value): 
     return self._set(stddev=value) 

    def getStddev(self): 
     return self.getOrDefault(self.stddev) 

としきい値:

class HasCenteredThreshold(Params): 

    centered_threshold = Param(Params._dummy(), 
      "centered_threshold", "centered_threshold", 
      typeConverter=TypeConverters.toFloat) 

    def __init__(self): 
     super(HasCenteredThreshold, self).__init__() 

    def setCenteredThreshold(self, value): 
     return self._set(centered_threshold=value) 

    def getCenteredThreshold(self): 
     return self.getOrDefault(self.centered_threshold) 

を使用すると、基本的なEstimatorなどを作成できますが、平均パラメータに以下のミックスインを定義していると仮定すると、

以下:

次のように210
class NormalDeviation(Estimator, HasInputCol, 
     HasPredictionCol, HasCenteredThreshold): 

    def _fit(self, dataset): 
     c = self.getInputCol() 
     mu, sigma = dataset.agg(avg(c), stddev_samp(c)).first() 
     return (NormalDeviationModel() 
      .setInputCol(c) 
      .setMean(mu) 
      .setStddev(sigma) 
      .setCenteredThreshold(self.getCenteredThreshold()) 
      .setPredictionCol(self.getPredictionCol())) 

class NormalDeviationModel(Model, HasInputCol, HasPredictionCol, 
     HasMean, HasStandardDeviation, HasCenteredThreshold): 

    def _transform(self, dataset): 
     x = self.getInputCol() 
     y = self.getPredictionCol() 
     threshold = self.getCenteredThreshold() 
     mu = self.getMean() 
     sigma = self.getStddev() 

     return dataset.withColumn(y, (dataset[x] - mu) > threshold * sigma) 

は、最後にそれを使用することができる:

df = sc.parallelize([(1, 2.0), (2, 3.0), (3, 0.0), (4, 99.0)]).toDF(["id", "x"]) 

normal_deviation = NormalDeviation().setInputCol("x").setCenteredThreshold(1.0) 
model = Pipeline(stages=[normal_deviation]).fit(df) 

model.transform(df).show() 
## +---+----+----------+ 
## | id| x|prediction| 
## +---+----+----------+ 
## | 1| 2.0|  false| 
## | 2| 3.0|  false| 
## | 3| 0.0|  false| 
## | 4|99.0|  true| 
## +---+----+----------+ 
+0

感謝を! Estimatorの状態もパラメータとみなされますか? –

+0

モデルのパラメータとして推定量の調整されたパラメータを意味しますか?そうであれば、このように設計すると便利ですが、基本的な実装には厳しい要件ではありません。 – zero323

+0

[OK]を、どのようにこのようなカスタムステップを維持する方法についていくつかのアドバイスを得ることを望みますか? –

関連する問題