2017/01/23

Jak działa algorytm map-reduce?

Map, Reduce i wielowątkowość w Pythonie

MapReduce jest własnościową platformą Google do przetwarzania równoległego. Nazwa sugeruje związek z operacjami map i reduce, jednak przeglądając przykłady, spotkałem się od razu z pojęciami mapperów, reduktorów, partycjonerów itd, bezpośrednio powiązanych z implementacjami realizującymi algorytm (jak np. hadoopowy mapreduce).
Poniższy przykład ilustruje podstawy algorytmu przy pomocy elementarnych elementów biblioteki standardowej Pythona - metody map z multiprocessing.pool i reduce z functools (w Pythonie 2 będącej funkcją podstawową).
Program wieloprocesowo zlicza wystąpienia poszczególnych znaków w zadanym ciągu liter.
'''prosty wielowatkowy program
ilustrujacy idee algorytmu map-reduce'''

import multiprocessing
from functools import reduce

def policz_litery(lancuch):
    '''funkcja map'''
    unikalne_znaki = set(lancuch)
    wystapienia = { k:0 for k in unikalne_znaki }
    for litera in lancuch:
        wystapienia[litera] += 1
    return wystapienia

def polacz_slowniki(slownik1, slownik2):
    '''funkcja redukuje dwa slowniki z licznikami liter do jednego slownika'''
    wynik = slownik1
    for litera in slownik2.keys():
        if litera in wynik:
            wynik[litera] += slownik2[litera]
        else:
            wynik[litera] = slownik2[litera]
    return wynik

#tekst w ktorym policzymy wystapienia liter
lorem_ipsum = '''Lorem ipsum dolor sit amet, 
consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. 
Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. 
Duis aute irure dolor in reprehenderit in 
voluptate velit esse cillum dolore eu 
fugiat nulla pariatur. Excepteur sint 
occaecat cupidatat non proident, sunt in 
culpa qui officia deserunt mollit anim id est laborum.'''

#obliczenia beda wykonane niezaleznie na zdaniach (rozdzielonych kropkami)
zdania = lorem_ipsum.split('.')

#wykonujemy zadanie policz_litery na poszczegolnych zdaniach (mapowanie)
pulaworkerow = multiprocessing.Pool()
policzone_zdaniami = pulaworkerow.map(policz_litery,zdania)

#redukujemy otrzymane wyniki czesciowe przy pomocy funkcji polacz_slowniki
zredukowane = reduce(polacz_slowniki,policzone_zdaniami)
print(zredukowane)

Brak komentarzy:

Prześlij komentarz