python apache-spark scikit-learn pyspark random-forest

python - ¿Cómo acceder a las predicciones individuales en Spark RandomForest?



apache-spark scikit-learn (1)

Deseo utilizar el módulo pyspark.mllib.tree.RandomForest para obtener una matriz de proximidad para mis observaciones.

Hasta ahora, mis datos eran lo suficientemente pequeños como para cargarlos directamente en la memoria. Por lo tanto, utilicé sklearn.ensemble.RandomForestClassifier para obtener la matriz de proximidad de la siguiente manera: supongamos que X es una matriz que contiene las características e Y es un vector que contiene las etiquetas. Entrené el bosque aleatorio para distinguir entre los objetos con la etiqueta "0" y la etiqueta "1". Al tener el bosque aleatorio entrenado, quería obtener una medida de proximidad entre cada par de observaciones en mi conjunto de datos al contar en cuántos árboles de decisión las dos observaciones tienen el mismo nodo final (= hoja). Entonces, para 100 árboles de decisión, la medida de proximidad entre dos observaciones puede variar desde 0 (nunca caer en la misma hoja final) y 100 (han caído en la misma hoja final en todos los árboles de decisión). La implementación de Python de esto:

import numpy from sklearn import ensemble ## data print X.shape, Y.shape # X is a matrix that holds the 4281 features and contains 8562 observations and Y contains 8562 labels >> (8562, 4281) (8562,) ## train the tree n_trees = 100 rand_tree = sklearn.ensemble.RandomForestClassifier(n_estimators=n_tress) rand_tree.fit(X, Y) ## get proximity matrix apply_mat = rand_tree.apply(X) obs_num = len(apply_mat) sim_mat = numpy.eye(obs_num) * len(apply_mat[0]) # max values that they can be similar at = N estimators for i in xrange(obs_num): for j in xrange(i, obs_num): vec_i = apply_mat[i] vec_j = apply_mat[j] sim_val = len(vec_i[vec_i==vec_j]) sim_mat[i][j] = sim_val sim_mat[j][i] = sim_val sim_mat_norm = sim_mat / len(apply_mat[0]) print sim_mat_norm.shape >> (8562, 8562)

Ahora, trabajo con datos que son demasiado grandes para caber en la memoria y, por lo tanto, decidí trabajar con Spark. Puedo cargar los datos y ajustarlos, pero no encontré una forma de "aplicar" el bosque aleatorio a los datos para obtener la matriz de proximidad. ¿Hay alguna forma de obtenerlo? (Utilizo la misma implementación que en la documentación de Spark: https://spark.apache.org/docs/1.2.0/mllib-ensembles.html#classification ):

from pyspark.mllib.tree import RandomForest from pyspark.mllib.util import MLUtils # Load and parse the data file into an RDD of LabeledPoint. data = MLUtils.loadLibSVMFile(sc, ''data/mllib/sample_libsvm_data.txt'') # Split the data into training and test sets (30% held out for testing) (trainingData, testData) = data.randomSplit([0.7, 0.3]) model = RandomForest.trainClassifier(trainingData, numClasses=2, categoricalFeaturesInfo={}, numTrees=3, featureSubsetStrategy="auto", impurity=''gini'', maxDepth=4, maxBins=32)

También me complacerá escuchar otras ideas que puedan resolver mi problema. ¡Gracias!


El modelo PySpark MLlib no proporciona una forma directa de acceder a esta información. En teoría, puede tratar de extraer los modelos directamente y predecir individualmente para cada árbol:

from pyspark.mllib.tree import DecisionTreeMode numTrees = 3 trees = [DecisionTreeModel(model._java_model.trees()[i]) for i in range(numTrees)] predictions = [t.predict(testData) for t in trees]

Pero, en su lugar, es mejor usar el modelo ML:

from pyspark.ml.feature import StringIndexer from pyspark.ml.classification import RandomForestClassifier df = sqlContext.read.format("libsvm").load("data/mllib/sample_libsvm_data.txt") indexer = StringIndexer(inputCol="label", outputCol="indexed").fit(df) df_indexed = indexer.transform(df) model = RandomForestClassifier( numTrees=3, maxDepth=2, labelCol="indexed", seed=42 ).fit(df_indexed)

y use rawPrediction o columnas de probability :

model.transform(df).select("rawPrediction", "probability").show(5, False) ## +---------------------------------------+-----------------------------------------+ ## |rawPrediction |probability | ## +---------------------------------------+-----------------------------------------+ ## |[0.0,3.0] |[0.0,1.0] | ## |[2.979591836734694,0.02040816326530612]|[0.9931972789115647,0.006802721088435374]| ## |[2.979591836734694,0.02040816326530612]|[0.9931972789115647,0.006802721088435374]| ## |[2.979591836734694,0.02040816326530612]|[0.9931972789115647,0.006802721088435374]| ## |[2.979591836734694,0.02040816326530612]|[0.9931972789115647,0.006802721088435374]| ## +---------------------------------------+-----------------------------------------+

Nota : Si crees que tus datos requieren chispa, entonces construir una matriz de distancia / similitud completa es poco probable que sea una buena idea. Solo digo.