Ich habe kürzlich versucht, Apache Spark als Ersatz für Scikit Learn kennenzulernen, aber es scheint mir, dass Scikit selbst in einfachen Fällen viel schneller zu einem akkuraten Modell konvergiert als Spark. Zum Beispiel habe ich 1000 Datenpunkte für eine sehr einfache lineare Funktion (z = x + y) mit dem folgenden Skript generiert:
%Vor%Ich habe dann das folgende Scikit-Skript ausgeführt:
%Vor%Und dann dieses Spark-Skript: (mit Spark-Submit, keine anderen Argumente)
%Vor%Seltsamerweise ist der Fehler, den der Funke gibt, um eine Grßenordnung größer als der von Scikit (0.185 bzw. 0.045), obwohl die beiden Modelle einen nahezu identischen Aufbau haben (soweit ich das beurteilen kann). Ich verstehe, dass dies SGD mit sehr wenigen Iterationen verwendet und so die Ergebnisse abweichen können, aber ich hätte nicht gedacht, dass es irgendwo in der Nähe eines so großen Unterschieds oder eines so großen Fehlers wäre, besonders angesichts der außergewöhnlich einfachen Daten.
>Gibt es etwas, was ich in Spark falsch verstehe? Ist es nicht richtig konfiguriert? Sicherlich sollte ich einen kleineren Fehler bekommen als das?
SGD, das für Stochastic Gradient Descent steht, ist ein Online-konvexer Optimierungsalgorithmus und daher sehr schwierig zu parallelisieren, da es eine Aktualisierung pro Iteration durchführt (es gibt intelligentere Varianten wie SGD mit Minibatches, aber immer noch nicht sehr gut für parallele Umgebung.
Andererseits können Batch-Algorithmen wie L-BFGS, die ich mit Spark (LogigisticRegressionWithLBFGS) verwenden möchte, leicht parallelisiert werden, da sie eine Iteration pro Epoche vornimmt (sie muss alle Datenpunkte sehen, berechnen der Wert und der Gradient der Verlustfunktion jedes Punktes, führt dann die Aggregation durch, um den vollen Gradienten zu berechnen.)
Python wird in einer einzigen Maschine ausgeführt, deshalb funktioniert SGD gut.
Übrigens, wenn Sie in MLlib-Code suchen, ist das Äquivalent von scikit learns Lambda Lambda / Größe des Datasets (mllib optimiert 1/n*sum(l_i(x_i,f(y_i)) + lambda
, während scikit learn optimiert sum(l_i(x_i,f(y_i)) + lambda
Da Spark parallelisiert ist, muss jeder Knoten in der Lage sein, unabhängig von den anderen Knoten zu arbeiten, wenn die Berechnung im Gange ist, um [zeit-] teures Mischen zwischen den Knoten zu vermeiden. Folglich verwendet es eine Prozedur namens Stochastic Gradient Descent, um ein Minimum zu erreichen, das lokalen Gradienten nach unten folgt.
Der 'genaue' Weg zur Lösung eines [einfachen, kleinsten Quadrate] -Regressionsproblems beinhaltet das Lösen einer Matrixgleichung. Das ist wahrscheinlich das, was Scikit-Learn macht, also wird es in diesem Fall genauer sein.
Der Kompromiss besteht darin, dass das Lösen von Matrixgleichungen im Allgemeinen als N ^ 3 für eine quadratische Größe-N-Matrix skaliert, was für große Datensätze schnell undurchführbar wird. Spark tauscht Genauigkeit für Rechenleistung aus. Wie bei jeder maschinellen Lernprozedur sollten Sie in Ihren Algorithmen eine Vielzahl von Plausibilitätsprüfungen einbauen, um sicherzustellen, dass die Ergebnisse des vorherigen Schritts Sinn machen.
Hoffe, das hilft!
Tags und Links machine-learning apache-spark scikit-learn linear-regression