apache spark - org - Guardar modelo ML para uso futuro
spark ml regression (2)
Spark 2.0.0+
A primera vista, todos los
Transformers
y
Estimators
implementan
MLWritable
con la siguiente interfaz:
def write: MLWriter
def save(path: String): Unit
y
MLReadable
con la siguiente interfaz
def read: MLReader[T]
def load(path: String): T
Esto significa que puede usar el método de
save
para escribir el modelo en el disco, por ejemplo
import org.apache.spark.ml.PipelineModel
val model: PipelineModel
model.save("/path/to/model")
y léelo más tarde:
val reloadedModel: PipelineModel = PipelineModel.load("/path/to/model")
También se implementan métodos equivalentes en PySpark con
MLWritable
/
JavaMLWritable
y
MLReadable
/
JavaMLReadable
respectivamente:
from pyspark.ml import Pipeline, PipelineModel
model = Pipeline(...).fit(df)
model.save("/path/to/model")
reloaded_model = PipelineModel.load("/path/to/model")
SparkR proporciona funciones
write.ml
/
read.ml
, pero a partir de hoy, no son compatibles con otros idiomas compatibles:
SPARK-15572
.
Tenga en cuenta que la clase de cargador tiene que coincidir con la clase del
PipelineStage
almacenado.
Por ejemplo, si guardó
LogisticRegressionModel
, debe usar
LogisticRegressionModel.load
no
LogisticRegression.load
.
Si usa Spark <= 1.6.0 y experimenta algunos problemas con el guardado del modelo, sugeriría cambiar de versión.
Además de los métodos específicos de Spark, hay un número creciente de bibliotecas diseñadas para guardar y cargar modelos de Spark ML utilizando métodos independientes de Spark. Consulte, por ejemplo, ¿Cómo servir un modelo Spark MLlib? .
Chispa> = 1.6
Desde Spark 1.6 es posible guardar sus modelos utilizando el método de
save
.
Porque casi todos los
model
implementan la interfaz
MLWritable
.
Por ejemplo,
LinearRegressionModel
tiene y, por lo tanto, es posible guardar su modelo en la ruta deseada al usarlo.
Chispa <1.6
Creo que estás haciendo suposiciones incorrectas aquí.
Algunas operaciones en un
DataFrames
se pueden optimizar y se traduce en un rendimiento mejorado en comparación con los
RDDs
simples.
DataFrames
proporciona almacenamiento en caché eficiente y la API SQLish es posiblemente más fácil de comprender que la API RDD.
ML Pipelines son extremadamente útiles y las herramientas como el validador cruzado o los diferentes evaluadores son simplemente imprescindibles en cualquier tubería de la máquina e incluso si ninguna de las anteriores es particularmente difícil de implementar en la parte superior de la API MLlib de bajo nivel, es mucho mejor tener listo para uso, solución universal y relativamente bien probada.
Hasta ahora todo bien, pero hay algunos problemas:
-
Por lo que puedo decir, las operaciones simples en un
DataFrames
comoselect
owithColumn
muestran un rendimiento similar a sus equivalentes RDD comomap
, - en algunos casos, aumentar el número de columnas en una tubería típica puede degradar el rendimiento en comparación con las transformaciones de bajo nivel bien ajustadas. Por supuesto, puede agregar transformadores de columna de caída en el camino para corregir eso,
-
muchos algoritmos de ML, incluidos
ml.classification.NaiveBayes
son simplemente envoltorios alrededor de su APImllib
, - Los algoritmos PySpark ML / MLlib delegan el procesamiento real a sus contrapartes Scala,
- Por último, pero no menos importante, RDD todavía está disponible, incluso si está bien oculto detrás de DataFrame API
Creo que al final del día, lo que obtienes al usar ML sobre MLLib es una API bastante elegante y de alto nivel. Una cosa que puede hacer es combinar ambos para crear una tubería personalizada de varios pasos:
- use ML para cargar, limpiar y transformar datos,
-
extraer los datos requeridos (ver, por ejemplo, el método
extractLabeledPoints
) y pasarlos al algoritmo
MLLib
, - agregar validación / evaluación cruzada personalizada
-
guarde el modelo
MLLib
utilizando un método de su elección (modelo Spark o PMML )
No es una solución óptima, pero es la mejor que se me ocurre dada una API actual.
Estaba aplicando algunos algoritmos de Machine Learning como Regresión lineal, Regresión logística y Naive Bayes a algunos datos, pero estaba tratando de evitar el uso de RDD y comenzar a usar DataFrames porque los RDD son más lentos que Dataframes en pyspark (ver foto 1).
La otra razón por la que estoy usando DataFrames es porque la biblioteca ml tiene una clase muy útil para ajustar modelos que es CrossValidator esta clase devuelve un modelo después de CrossValidator , obviamente este método tiene que probar varios escenarios, y después de eso devuelve un modelo ajustado ( con las mejores combinaciones de parámetros).
El clúster que uso no es tan grande y los datos son bastante grandes y algunos ajustes toman horas, así que quiero guardar estos modelos para reutilizarlos más tarde, pero no me he dado cuenta de cómo, ¿hay algo que estoy ignorando?
Notas:
- Las clases de modelo de mllib tienen un método de salvar (es decir, NaiveBayes ), pero mllib no tiene CrossValidator y usa RDD, por lo que lo evito de forma premeditada.
- La versión actual es la chispa 1.5.1.
Parece que la funcionalidad de la API para guardar un modelo no está implementada a partir de hoy (consulte el rastreador de problemas de Spark SPARK-6725 ).
Se publicó una alternativa ( ¿Cómo guardar modelos de ML Pipeline a S3 o HDFS? ) Que implica simplemente serializar el modelo, pero es un enfoque de Java. Espero que en PySpark pueda hacer algo similar, es decir, seleccionar el modelo para escribir en el disco.