Jiskra Pod Kapotou: randomSplit() a vzorku() Vnitřní Fungování

Jiskra Provádění randomSplit()

podpis funkce randomSplit() zahrnuje hmotnost seznamu a semínko specifikace. V hmotnostním seznamu je uveden počet rozdělení a procento (přibližné) v každém a semeno je reprodukovatelné. Poměr je přibližný vzhledem k povaze jeho výpočtu.

například, následující kód na Obrázku 3 by rozdělení df do dvou datových rámců, train_df 80% a test_df že 20% z původní datový rámec. Při použití stejné hodnoty pro náhodné semeno očekáváme, že stejné datové body jsou ve stejném rozdělení, pokud bychom měli znovu spustit skript nebo Spark interně přestaví rozdělení.

obrázek 3: randomSplit() podpis funkce příklad

Pod Kapotou

následující proces se opakuje pro generování každé rozdělení dat rám: dělení, třídění do oddílů, a Bernoulliho vzorků. Pokud původní datový rámec není uložen do mezipaměti, budou data znovu načtena, znovu rozdělena a znovu tříděna pro každý výpočet rozdělení. To je zdroj potenciálních anomálií. V souhrnu, randomSplit () je ekvivalentní provedení vzorku () pro každý split s procentuální podíl na vzorku měnící se rozdělení provádí. To je zřejmé, pokud budete zkoumat zdrojový kód pro randomSplit () v PySpark3. Tento blog⁴ také poskytuje některé další informace a vizuální informace o tom, jak je randomSplit() implementován.

projděme si příklad. Obrázek 4 je schéma vzorku () pro každé rozdělení, počínaje rozdělením 0,80.

Obrázek 4: Proces vytváření 0.8 rozdělit. Identické s implementací vzorku ().

Spark využívá Bernoulliho vzorků, které lze shrnout jako generování náhodných čísel pro položky (datový bod) a přijetí do splitu, pokud vygenerované číslo spadá do určitého rozmezí, určuje dělicí poměr. Pro 0, 8 rozdělený datový rámec by byl rozsah přijetí pro vzorkovač Bernoulliho buněk .

stejný proces vzorkování je následován pro rozdělení 0.20 na obrázku 5, přičemž pouze hranice přijetí se mění na .

Obrázek 5: Proces generování 0,2 rozdělit. Identické se vzorkem (). provádění. Obsah oddílu zůstává konstantní a pořadí řazení je zachováno, což zajišťuje platné rozdělení.

datový rámec je znovu načten, rozdělen a znovu seřazen v oddílech. V příkladu můžete vidět, že oddíly RDD jsou idempotentní. Což znamená, že datové body v každém oddílu na obrázku 4, zůstávají ve stejném oddílu na obrázku 5. Například body b A c jsou v oddílu 1 na obrázku 4 I 5. Navíc semeno spojené s každým oddílem zůstává vždy konstantní a pořadí v oddílech je totožné. Všechny tři z těchto bodů jsou zásadní pro oba sample () a randomSplit (). Zajišťuje, že stejný vzorek se vyrábí se stejným osiva v bývalé, a zaručit, žádné duplikáty nebo mizí datových bodů v druhé.

řešení, jak se vyhnout nesrovnalostem

Oprava těchto problémů spočívá v zajištění idempotentních oddílů RDD a pořadí třídění. Některý z následujících tří metod zajistit to a může být použita: 1) ukládání dat snímek před operací 2) změny tím, že sloupec nebo sada sloupců, a 3) pomocí souhrnných functions⁵. Příklad každé metody je znázorněn na obrázku 6.

obrázek 6: Tři různé metody, aby se zabránilo nesrovnalosti v randomSplit() a vzorku()

ukládání do Mezipaměti původní datový rámec vede k rozdělení obsahu držen v paměti. Takže místo opětovného načítání dat, rozdělení a třídění Spark pokračuje v operacích pomocí rozdělených dat v paměti. Všimněte si, že cache () je alias pro persist(pyspark.StorageLevel.memory_only) což nemusí být ideální, pokud máte omezení paměti. Místo toho můžete zvážit použití persist(pyspark.StorageLevel.memory_and_disk_only). Pokud není k dispozici žádné místo na paměti nebo na disku, Spark znovu načte a rozdělí data od nuly,takže může být moudré sledovat to z webového uživatelského rozhraní Spark. Ukládání do mezipaměti je řešení, které jsem zvolil v mém případě.

shrnutí a klíčové Takeaways

ponaučení z příběhu je: pokud neočekávané chování se děje v Spark, stačí kopat trochu hlouběji! Zde je shrnutí všech klíčových bodů tohoto článku:

  • randomSplit() je ekvivalentní aplikaci vzorku (s) na datový rámec vícekrát, přičemž každý vzorek znovu-načítání, rozdělení a třídění dat rámem do příček.
  • rozdělení dat mezi oddíly a pořadí řazení je důležité jak pro randomSplit (), tak pro sample (). Pokud se při opětovném načtení dat změní, mohou existovat duplikáty nebo chybějící hodnoty napříč rozděleními a stejný vzorek s použitím stejného semene může přinést různé výsledky.
  • Tyto nesrovnalosti nemusí stát na každý běh, ale odstranit je úplně, stále přetrvávají (aka cache) data frame, rozdělení na sloupce(y), nebo aplikovat agregační funkce, jako jsou seskupení.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *