2017-07-02 14 views
1

Spark MLを使用してML実験を行い、20MB(Poker dataset)の小さなデータセットとパラメータグリッドのランダムフォレストでは、1時間30分かかります終わり。 scikit-learnと同様に、それははるかに少ない。Spark ML Pipeline with RandomForestは20MBのデータセットで長すぎます

環境面では、私は2つのスレーブ、それぞれ15GBのメモリ、24のコアでテストしていました。私は長い間それを取ることになっていないと仮定し、私はSparkをかなり新しくしているので、問題が私のコード内にあるかどうか疑問に思っています。

ここでは、次のとおりです。事前に

df = pd.read_csv(http://archive.ics.uci.edu/ml/machine-learning-databases/poker/poker-hand-testing.data) 
dataframe = sqlContext.createDataFrame(df) 

train, test = dataframe.randomSplit([0.7, 0.3]) 

columnTypes = dataframe.dtypes 

for ct in columnTypes: 
    if ct[1] == 'string' and ct[0] != 'label': 
     categoricalCols += [ct[0]] 
    elif ct[0] != 'label': 
     numericCols += [ct[0]] 

stages = [] 

for categoricalCol in categoricalCols: 

    stringIndexer = StringIndexer(inputCol=categoricalCol, outputCol=categoricalCol+"Index") 

stages += [stringIndexer] 

assemblerInputs = map(lambda c: c + "Index", categoricalCols) + numericCols 

assembler = VectorAssembler(inputCols=assemblerInputs, outputCol="features") 

stages += [assembler] 

labelIndexer = StringIndexer(inputCol='label', outputCol='indexedLabel', handleInvalid='skip') 

stages += [labelIndexer] 

estimator = RandomForestClassifier(labelCol="indexedLabel", featuresCol="features") 

stages += [estimator] 

parameters = {"maxDepth" : [3, 5, 10, 15], "maxBins" : [6, 12, 24, 32], "numTrees" : [3, 5, 10]} 

paramGrid = ParamGridBuilder() 
for key, value in parameters.iteritems(): 
    paramGrid.addGrid(estimator.getParam(key), value) 
estimatorParamMaps = (paramGrid.build()) 

pipeline = Pipeline(stages=stages) 

crossValidator = CrossValidator(estimator=pipeline, estimatorParamMaps=estimatorParamMaps, evaluator=MulticlassClassificationEvaluator(labelCol='indexedLabel', predictionCol='prediction', metricName='f1'), numFolds=3) 

pipelineModel = crossValidator.fit(train) 

predictions = pipelineModel.transform(test) 

evaluator = pipeline.getEvaluator().evaluate(predictions) 

おかげで、任意のコメント/提案が高く評価されている:)

+0

それはあなたの3の組み合わせに比例だとしてクロス検証が重くて長い作業ですがハイパーパラメータは、各モデルを訓練するために費やされた時間の倍数の倍数です。一例につき、最初にデータをキャッシュしたいかもしれませんが、それでも時間がかかりません。私はスパークがこの量のデータに対して過度のものであると信じています。 scikitを代わりに使用して、おそらくhttps://github.com/databricks/spark-sklearnを使用してローカルモデルトレーニングを配布したいかもしれません。 – eliasah

+1

hi @eliasahコメントをいただきありがとうございます。実際、私はspark-sklearnでそれをやっており、良い結果を得ています。しかし、私はsklearnとsparkの実行時間を比較したいと思っていましたが、1秒に1時間かかりますが、もう1時間は時間がかかります。 –

+0

sparkは、データが分散して大きいという仮説を使って、 。 – eliasah

答えて

1

以下は完全にあなたの問題を解決しないかもしれないが、それはあなたを始めるためにいくつかのポインタを与える必要があります。

最初に直面している問題は、データ量とリソースの間の不均衡であるです。

これは、ローカルコレクション(pandasデータフレーム)を並列化するため、Sparkはデフォルトの並列処理設定を使用することを意味します。これは、パーティション当たり0.5mb未満の48パーティションをもたらす可能性が最も高い。 (小さなファイルや小さなパーティションではうまくいきません)

2番目の問題は、高価な最適化/近似のテクニックに関連しています。

スパークツリーモデルは、連続変数を最適にバケットするためにいくつかのトリックを使用します。小さなデータでは、ちょうど正確な分割を取得する方法が安いです。 この場合、主に近似された分位数を使用します。

通常、単一のマシンフレームワークのシナリオでは、scikitのように、ツリーモデルは、最適フィット計算の分割候補として連続フィーチャに固有のフィーチャ値を使用します。 Apache Sparkでは、ツリーモデルは分割された候補として各フィーチャーの分位数を使用します。

また、クロス検証は3つのハイパーパラメータの組み合わせに比例して重くて長い作業であることも忘れてはならないことを付け加えてください。グリッドサーチアプローチ)。一例につき、最初にデータをキャッシュしたいかもしれませんが、それでも時間がかかりません。私はスパークがこの量のデータに対して過度のものであると信じています。代わりにscikit learnを使用し、spark-sklearnを使用して、ローカルモデルトレーニングを分散させることができます。

スパークは、データが分散して大きなものであるという仮説を用いて、個々のモデルを別々に習得します。

寄木張りやチューニングのような円柱データベースのファイル形式を使用してパフォーマンスを最適化することはもちろん可能ですが、ここでそれについて話すには広すぎます。

あなたはこの以下のブログ投稿で火花mllibでツリーモデルのスケーラビリティについての詳細を読むことができます:

関連する問題