2012-04-11 13 views
13

¿Puede alguien el cálculo de mediana/cuantiles en el mapa reducir?La mediana de la computación en el mapa reduce

Mi comprensión de la mediana de Datafu es que los creadores de mapas 'n' ordenar los datos y envían los datos a "1" reductor que se encarga de clasificar todos los datos de n creadores de mapas y la búsqueda de la mediana (valor medio) ¿Es correcto mi entendimiento ?,

si es así, este enfoque escala para cantidades masivas de datos ya que puedo ver claramente el único reductor que lucha para realizar la tarea final. Gracias

Respuesta

12

Tratando de encontrar la mediana (número medio) en una serie va a requerir que 1 reductor pase el rango completo de números para determinar cuál es el valor 'medio'.

Según el rango y la singularidad de los valores en su conjunto de entrada, puede introducir un combinador para generar la frecuencia de cada valor, reduciendo el número de salidas de mapa enviadas a su único reductor. Su reductor puede consumir los pares de valor de clasificación/frecuencia para identificar la mediana.

Otra forma de escalar esto (de nuevo si conoce el rango y la distribución aproximada de valores) es usar un particionador personalizado que distribuye las claves por rangos de rango (0-99 ir al reductor 0, 100-199 al reductor 2, y así sucesivamente). Sin embargo, esto requerirá algún trabajo secundario para examinar las salidas del reductor y realizar el cálculo mediano final (conociendo por ejemplo el número de llaves en cada reductor, puede calcular qué salida del reductor contendrá la mediana y en qué desviación)

2

O ((n log n)/p) para ordenarlo luego O (1) para obtener la mediana.

Sí ... puede obtener O (n/p) pero no puede usar la funcionalidad de ordenación de fábrica en Hadoop. Simplemente ordenaría y obtendría el artículo central a menos que pueda justificar las 2-20 horas de tiempo de desarrollo para codificar el algoritmo paralelo k-ésimo más grande.

7

¿Realmente necesita la exacta mediana y cuantiles?

Muchas veces, es mejor obtener solo valores aproximados y trabajar con ellos, en particular si usa esto para, p. Ej. particionamiento de datos.

De hecho, puede utilizar los cuantiles aproximadas para acelerar la búsqueda de los cuantiles exactas (en realidad en O(n/p) tiempo), aquí es un esbozo de la estrategia:

  1. Tener un mapeador para cada la partición calcula los cuantiles deseados y los envía a un nuevo conjunto de datos. Este conjunto de datos debe ser de varios órdenes de magnitud más pequeños (a menos que solicite demasiados cuantiles)
  2. Dentro de este conjunto de datos, calcule los cuantiles nuevamente, similar a "mediana de medianas". Estas son tus estimaciones iniciales.
  3. Repartición de los datos de acuerdo con estos cuantiles (o incluso particiones adicionales obtenidas de esta manera). El objetivo es que al final, el cuantil verdadero esté garantizado en una partición, y debe haber como máximo uno de los cuantiles deseados en cada partición
  4. Dentro de cada una de las particiones, realice una selección rápida (en O(n)) para encuentra el verdadero cuantil

Cada uno de los pasos es en tiempo lineal. El paso más costoso es la parte 3, ya que requerirá que se redistribuya todo el conjunto de datos, por lo que genera O(n) tráfico de red. Probablemente pueda optimizar el proceso eligiendo cuantiles "alternativos" para la primera iteración. Diga, quiere encontrar la mediana global. No puede encontrarlo fácilmente en un proceso lineal, pero puede probablemente limitarlo a 1/kth del conjunto de datos, cuando se divide en k particiones. Entonces, en lugar de hacer que cada nodo informe su mediana, haga que cada nodo reporte los objetos en (k-1)/(2k) y (k + 1)/(2k). Esto debería permitirle reducir el rango de valores donde la verdadera mediana debe ser mentir significativamente. Por lo tanto, en el siguiente paso, cada nodo puede enviar esos objetos que están dentro del rango deseado a un solo nodo maestro, y elegir la mediana dentro de este rango solamente.

+0

Encontrar cuantiles exactas podría ser muy costoso en este enfoque amy ser mejor que el enfoque ingenuo, aunque . Los pasos 1 a 4 realmente ayudan a dividir el conjunto en la mitad y a resolver el mismo problema en un espacio más pequeño. Pero en este enfoque, puede tomar iteraciones logn del paso 1 al paso 4 para obtener realmente el cuantil. – Sourabh

0

En muchos escenarios del mundo real, la cardinalidad de los valores en un conjunto de datos será relativamente pequeña. En tales casos, el problema se puede resolver de manera eficiente con dos trabajos MapReduce:

  1. determinar las frecuencias de los valores del conjunto de datos (Word Count trabajo, básicamente)
  2. Identidad asignador + un reductor que calcula la mediana basado en < valor - frecuencia> pares

Tarea 1. Reduce drásticamente la cantidad de datos y se puede ejecutar completamente en paralelo. El reductor del trabajo 2. solo tendrá que procesar n (n = cardinality of your value set) elementos en lugar de todos los valores, como con el enfoque ingenuo.

A continuación, un ejemplo de reductor del trabajo 2. Es un script de python que se puede usar directamente en la transmisión de Hadoop. Toma valores en el conjunto de datos son ints, pero se pueden adoptar fácilmente para double s

import sys 

item_to_index_range = [] 
total_count = 0 

# Store in memory a mapping of a value to the range of indexes it has in a sorted list of all values 
for line in sys.stdin: 
    item, count = line.strip().split("\t", 1) 
    new_total_count = total_count + int(count) 
    item_to_index_range.append((item, (total_count + 1, new_total_count + 1))) 
    total_count = new_total_count 

# Calculate index(es) of middle items 
middle_items_indexes = [(total_count/2) + 1] 
if total_count % 2 == 0: 
    middle_items_indexes += [total_count/2] 

# Retrieve middle item(s) 
middle_items = [] 
for i in middle_items_indexes: 
    for item, index_range in item_to_index_range: 
     if i in range(*index_range): 
      middle_items.append(item) 
      continue 

print sum(middle_items)/float(len(middle_items)) 

Esta respuesta se acumula en la parte superior de una sugerencia inicialmente procedente del answer de Chris White. La respuesta sugiere usar un combinador como medio para calcular frecuencias de valores. Sin embargo, en MapReduce, no se garantiza que los combinadores siempre se ejecuten. Esto tiene algunos efectos secundarios:

  • reductor primero tendrá que calcular el valor final de < -> frecuencia pares y luego calcular la mediana.
  • En el peor de los casos, combinadores nunca será ejecutado y el reductor todavía tendrá que luchar con el procesamiento de todos los valores individuales
Cuestiones relacionadas