Jeśli ktoś jeszcze nie zauważył to na edx.org rozpoczął się właśnie kurs : "BerkeleyX: CS100.1x Introduction to Big Data with Apache Spark". W kursie używają głównie pythona a ja tutaj postaram się opisać jak można chociaż część ćwiczeń zrobić w scali.
W trakcie pierwszego tygodnia poza ćwiczeniami było trochę o profilach osób mieniących się "Data Scientist" jak i "Data Engineer" i cóż ci ludzie robią. Część praktyczna na razie polegała na instalacji virtualboxa i vagranta - a następnie odpaleniu kilku prostych przykładów sparka na gotowym obrazie. Na forum 90% pytań to problemy posiadaczy windowsa z instalacją obydwu wspomnianych narzędzi. Pomyślałem sobie, że to fajnie iż robię te ćwiczenia na linuxie - potem zdałem sobie sprawę, że 40 godzin w tygodniu pracuję na windowsie, usiadłem i zacząłem płakać...choć nie, nie zacząłem bo od razu przeszedłem do robienia ćwiczeń.
Najpierw teoria - Lekcja 1
Opisywanie tego co się usłyszało w celu zrelacjonowania tego dalej to dobry sposób by informacje zwyczajnie nie przeleciały przez głowę i upadły po drugiej stronie na podłogę.
Najpierw było kilka ciekawych rzeczy odnośnie interpretacji danych a konkretniej błędów przy tejże czynności popełnianych - i jest jedna fajna życiowa rzecz, która doczekała się nawet swojej strony na wiki - http://en.wikipedia.org/wiki/Correlation_does_not_imply_causation
To jest tak zabawny efekt, ze jeszcze jeden obrazek z netu : I Dilbert - a jak jest dilbert to wiadomo, ze zaraz będzie coś o korpo :Na kursie był wspomniany przykład badania Seven Countries Study - które zrodziło mit o powiązaniu ilość spożywanego tłuszczu z prawdopodobieństwem ataku serca. W linku można sobie poczytać o badaniu i krytyce oraz zapamiętać by ograniczyć spożycie cukrów prostych.
Są dwa zabawne przypadki o których słyszałem w kontekście tego efektu - pierwszy to pozorna zależność pomiędzy zamieszkaniem w okolicy linii wysokiego napięcia a śmiertelnością. Generalnie to działa na wyobraźnię bo prąd, magnetyzm i ciało ludzkie itd, no i liczby nie kłamią przecież - liczby nie kłamią ale ludzi ich nie rozumieją - bo co się okazało. Po dalszych badaniach wyszło na jaw, ze generalnie ludzie nie chcą mieszkać w okolicy linii wysokiego napięcia i działki są tam tańsze, i kupują je biedniejsi ludzie, którzy żyją mniej zdrowiej niż średnia populacji, i większe jest wśród nich umieralność...
Zaś drugi przykład jest związany z czymś coś co się nazywa "regresja do średniej" i tutaj dwa linki
- http://en.wikipedia.org/wiki/Regression_toward_the_mean - pierwszy ogólno-matematyczny
- http://en.wikipedia.org/wiki/Regression_fallacy - drugi ciekawie-psychologiczny
To był dosyć ciekawy przykład z książki Thinking fast and slow albo z Black Swan. Był tam opisany przypadek Kapitana lotnictwa, który zauważył, ze zawsze gdy skuteczność pilotów spada i dostaną opierdol to się poprawia. Natomiast gdy jest dobrze i dostaną pochwałę to się pogarsza. No to przestał ich chwalić i tylko opierdalał. I coś w dłuższym okresie czasu morale siadło.
Kahneman próbował im wytłumaczyć, że skuteczność po doskonałych dniach by się pogarszała tak czy inaczej nawet bez pochwał a poprawiała bo bardzo słabych dniach nawet bez opierdolu. Nie dochodziło to do kapitana, więc zrobili pewien eksperyment. Narysowali kółko i kazali rzucać kapitanowi monetami doń tak by wycelować najbliżej środka. Zrobili dwa warianty - jeden z opierdalaniem a drugi bez - dużej różnicy nie było. To w sumie tak jakby opierdolić generator Radom.nextInt jak wygeneruje mała liczbę i pokazywać palcem, że podziałało jak wygeneruje za chwilę dużą liczbę.
Niebezpieczeństwo
Jeszcze gorsze od olewania liczb jest fanatyczna w nie wiara bez uwzględniania kontekstu ludzkiego - tzw technokracja. Kolega kolegi opowiadał o przypadkach, gdzie ludzie wydawali osądy wyssanez palca na podstawie liczenia średniej ważonej z burndown charta - programiści szybko się do tego dostosowują i potrafią kosztem produktywności (i co gorsza kosztem kultury pragmatyzmu) wygenerować odpowiedni wykres dla managerów. Ci którzy starają się kulturalnie zwrócić uwagę, ze to bez sensu i ogólnie firma na tym traci a zyskuje jedynie manager dostają etykiete kłótliwych -, że tak podobno jest powiedział mi kolega kolegi od strony stryjka.
Hippo
Czyli “HiPPO”—the highest-paid person’s opinion", a "highest-paid person’s" to ta osoba od której wymagane jest zgadywanie odnośnie przyszłości - tak twierdzą autorzy kursu jakkolwiek nie używają słowa "dupy" ani "stzrelanie".
Google jako wyrocznia
Naukowcy z Princeton dokonali analizy zapytań z google i stwierdzili, ze do 2020 nikt nie będzie używał już facebooka gdyż podobny trend zdążył się w przypadku myspace. Naukowcy z facebooka dokonali analizy danych z googla i stwierdzili, ze do 2020 nie będzie Princeton - ale to nie jest najstraszniejsze. Według tej samej procedury badawczej do 2060 nie będzie na ziemi powietrza!!
I fajny link jeszcze :Fajny Link
lesson 2
Było o tym, ze dane trzeba przygotować, przefiltrować, że rzeczywistość dookoła nam nie będzie ładnie podawać informacji ale trzeba będzie je oszlifować i bez odpowiedniej technologii się zer.. nie uda się.
Było o Data Science i, że ludzie się ogólnie do tego nie nadają - "It is human nature to make assumptions ", "Humans have biases based on prior observations"
Dobra pogadali a teraz konkrety LPROGRAMOWANIE
Generalnie polecam "Spark in action" nawet jak to jest Meap na razie bo tam jest konkretna praktyka z instalacją i komendami na linuxie. A jak fajnie, że ja mam linuxa...chociaż zaraz...
Najpierw byłą instalacja VirtualBoxa i Vagranta - zajebisty zestaw na prowadzenie warsztatów, trzeba będzie wypadać przy okazji. I od razu nauczka - na stronie downloadu są dwie opcje "i386" i "amd64" - i wcale nie jest tak, że ta pierwsza to intel a druga amd tylko pierwsza to 32bity a druga 64bity - czasem jednak warto czytać instrukcje bo jak odinstalowałem virtualboxa 32 bitowego to było późno i chyba za dużo komend ze strony przekleiłem bo przy okazji odinstalwoałem sobie Unity i zrobiło się jeszcze później.
W każdym razie po instalacji vagranta idzie "vagrant up" - zaciąga się obraz i możemy odpalić taki notebook, w którym można pisać w pythonie. Ale przecież chcielibyśmy też popisać w scali.
Popisać w scali
Wbijamy na spark REPL :vagrant ssh echo $SPARK_HOME // tak dowiemy sie gdzie jest spark ///usr/local/bin/spark-1.3.1-bin-hadoop2.6 cd /usr/local/bin/spark-1.3.1-bin-hadoop2.6 bin/spark-shell //i mamy scalę ! //Using Scala version 2.10.4 (OpenJDK Client VM, Java 1.7.0_79)
Dziś przyjmiemy inną taktykę i zamiast śmiać się z innego jezyka - zobaczymy też co ciekawego w Pythonie. Bo jakoś ponoć to język Data Scientistów.
Jest taki repl online - Python : http://www.tutorialspoint.com/ipython_terminal_online.php i tam można sobie poeksperymentować. Na razie nauczyłem się, że (xrange(10)) - to chyba to samo co (0 until 10) w scali.
Python jest bardzo podobny do scali ale nie ma tam val,var i ogólnie typów. W niektórych środowiskach pracy to może być zaleta bo programiści mogą powiedzieć "przynajmniej nasz kod się uruchamia" (to żart oczywiście (chociaż nie, znam miejsca gdzie to nie będzie żartem))
Porównanie przykładów : Python ex1# Check that Spark is working largeRange = sc.parallelize(xrange(100000)) reduceTest = largeRange.reduce(lambda a, b: a + b) filterReduceTest = largeRange.filter(lambda x: x % 7 == 0).sum() # If the Spark jobs don't work properly these will raise an AssertionError assert reduceTest == 4999950000 assert filterReduceTest == 714264285
val largeRange=sc.parallelize(0L until 100000L) // largeRange: org.apache.spark.rdd.RDD[Long] val reduceTest=largeRange.reduce(_+_) //reduceTest: Long = 4999950000 val filterReduceTest=largeRange.filter(_ % 7==0).sum() //filterReduceTest: Double = 7.14264285E8
# Check loading data with sc.textFile import os.path baseDir = os.path.join('data') inputPath = os.path.join('cs100', 'lab1', 'shakespeare.txt') fileName = os.path.join(baseDir, inputPath) rawData = sc.textFile(fileName) shakespeareCount = rawData.count() print shakespeareCount # If the text file didn't load properly an AssertionError will be raised assert shakespeareCount == 122395
val homeDir=System.getProperty("user.home") val path = (s"${homeDir}/data/cs100/lab1/shakespeare.txt") path: String = /home/vagrant/data/cs100/lab1/shakespeare.txt val rawData=sc.textFile(path) val shakespeareCount=rawData.count //shakespeareCount: Long = 122395
# TEST Compare lists (2b) # This should print '1 test passed.' unsortedList = [(5, 'b'), (5, 'a'), (4, 'c'), (3, 'a')] Test.assertEquals(sorted(unsortedList), [(3, 'a'), (4, 'c'), (5, 'a'), (5, 'b')], 'unsortedList does not sort properly')
val lista=List((5,'b'),(5,'a'),(4,'c'),(3,'a')) lista.sorted == List((3,'a'),(4,'c'),(5,'a'),(5,'b')) res3: Boolean = true
To tyle na pierwszy tydzień odnośnie wyżej wspomnianego kursu.
BONUS
Widać, że spark jest an topie bo hortonworks rzucił też wstęp do tutoriala "Data Science i Spark". Artykuł tutaj : http://hortonworks.com/blog/introduction-to-data-science-with-apache-spark/.
Jedyne ale to to, ze kurs jest przeznaczony dla platformy hortonworks, a że jej nie ma to poniżej dostosowanie ćwiczeń do już posiadanego obrazu vagranta ze sparkiem.
Najpierw jest tam instalacja ciekawej konsolki - https://github.com/apache/incubator-zeppelin ale to an kiedy indziej. Na razie trzeba wtgenerować sobie plik z logami do analizy.
W /usr/local/bin/spark-1.3.1-bin-hadoop2.6 wbijamy do katalogu conf
sudo mv conf/log4j.properties.template conf/log4j.properties #wrzucić to do log4j.properties #file log4j.rootCategory=INFO, console, file log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.err log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n # Settings to quiet third party logs that are too verbose log4j.logger.org.eclipse.jetty=WARN log4j.logger.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO #file log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=/var/log/spark.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n sudo touch /var/log/spark.log sudo chown vagrant /var/log/spark.log
Odpalić konsolę sparka ze scalą i jedziemy :
val sparkLogs=sc.textFile("/var/log/spark.log") import sqlContext.implicits._ import java.text.SimpleDateFormat import java.sql.Date case class Log(level:String,date:Date,content:String) val df=new SimpleDateFormat("yy/mm/dd HH:mm:dd") val sparkFrame=sparkLogs.map {line => val s=line.split(" ") val date=df.parse(s(0) + " " + s(1)) val logLevel=s(2) val logContent=s(3) Log(logLevel,new Date(date.getTime()),logContent)}.toDF() sparkFrame.registerTempTable("spark")
I tutaj przyda się trochę znajomości REPLa jednak. Do tej pory to olewałem bo były worksheety w IDE. Są dwie dobre strony :
MOTYWACJA: - jednak jak coś jest potrzebne to się tego można nauczyć - tutaj najciekawsze polecenia to : :paste, :paste -raw, :history + :editI wio i błąd a na błędach się uczymy:
Caused by: ERROR XBM0H: Directory /usr/local/bin/spark-1.3.1-bin-hadoop2.6/metastore_db cannot be created.Nie wiem czy poniższe rozwiązanie jest najlepsze bo nie jestem pełnoetatowym adminem :
vagrant@sparkvm:/usr/local/bin/spark-1.3.1-bin-hadoop2.6$ cd .. vagrant@sparkvm:/usr/local/bin$ sudo chmod 775 spark-1.3.1-bin-hadoop2.6/ sudo chown vagrant spark-1.3.1-bin-hadoop2.6/
Jak już tu jesteśmy to zobaczmy co tam w tym metastore jest :
vagrant@sparkvm:/usr/local/bin/spark-1.3.1-bin-hadoop2.6/metastore_db$ ls -l total 28 -rw-rw-r-- 1 vagrant vagrant 608 Jun 4 13:55 README_DO_NOT_TOUCH_FILES.txt -rw-rw-r-- 1 vagrant vagrant 38 Jun 4 13:59 db.lck -rw-rw-r-- 1 vagrant vagrant 4 Jun 4 13:59 dbex.lck drwxrwxr-x 2 vagrant vagrant 4096 Jun 4 13:55 log drwxrwxr-x 2 vagrant vagrant 4096 Jun 4 13:55 seg0 -rw-rw-r-- 1 vagrant vagrant 932 Jun 4 13:55 service.properties drwxrwxr-x 2 vagrant vagrant 4096 Jun 4 13:59 tmp vagrant@sparkvm:/usr/local/bin/spark-1.3.1-bin-hadoop2.6/metastore_db$ cat README_DO_NOT_TOUCH_FILES.txt # ************************************************************************* # *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** # *** FILES IN THIS DIRECTORY AND SUBDIRECTORIES CONSTITUTE A DERBY *** # *** DATABASE, WHICH INCLUDES THE DATA (USER AND SYSTEM) AND THE *** # *** FILES NECESSARY FOR DATABASE RECOVERY. *** # *** EDITING, ADDING, OR DELETING ANY OF THESE FILES MAY CAUSE DATA *** # *** CORRUPTION AND LEAVE THE DATABASE IN A NON-RECOVERABLE STATE. *** # *************************************************************************
Nooo dobra to tyle. Kończymy zabawę w scali.
//TO jest tak lazy , ze dopiero po "show()" się wywala ! sparkFrame.groupBy("level").count().show() /* level count WARN 6 INFO 64 */ sqlContext.sql("SELECT level, count(1) from spark group by level") //res6: org.apache.spark.sql.DataFrame = [level: string, _c1: bigint] sqlContext.sql("SELECT level, count(1) from spark group by level").show /*level _c1 WARN 6 INFO 64 */ import org.apache.spark.sql.Row val result = sqlContext.sql("SELECT level, count(1) from spark group by level").map { case Row(level: String, count: Long) => { level + "\t" + count } }.collect() println("%table Log Level\tCount\n" + result.mkString("\n")) /* %table Log Level Count WARN 6 INFO 64*/
To jest ciekawe bo DataFrame mówi do programisty "mów mi co trzeba zrobić nie mów jak i nie kontroluj" i wychodzi to lepiej. Czasem też warto zrobić sobie przerwę bo w ferworze pisania zacząłem zmieniać konfigurację log4j tutaj w tekście na blogu i dziwiłem się, że spark nie łyka tej konfiguracji... Czasem można spojrzeć na zieleń w celu uwolnienia umysłu. W poprzedniej pracy mieliśmy kalendarz ze zdjęciem fitneski - takiej miłej i uśmiechniętej, która promowała zdrowy tryb życia. I zawsze to podnosiło kreatywność zespołu ale przyszły korpo służby i kazały zdjąć kalendarz redukując naszą efektywność o 17,3%. Generalnie pomału mam wrażenie, że niektórzy mylnie używają słowa "profesjonalista" do opisu smutnego pana w wyprasowanej smutnej koszuli siedzącego w smutnym koncie smutnego piętra z gołymi i smutnymi ścianami. Ale zresztą ja się tam nie znam.
Za tydzień - lekcje 3 i 4 - ma już się zacząć jakieś datascience to powinno być ciekawie.
Brak komentarzy:
Prześlij komentarz