dareks_

  • Dokumenty2 821
  • Odsłony748 937
  • Obserwuję429
  • Rozmiar dokumentów32.8 GB
  • Ilość pobrań360 408

Conway D. - Uczenie maszynowe dla programistów

Dodano: 6 lata temu

Informacje o dokumencie

Dodano: 6 lata temu
Rozmiar :22.4 MB
Rozszerzenie:pdf

Conway D. - Uczenie maszynowe dla programistów.pdf

dareks_ EBooki Infornatyka
Użytkownik dareks_ wgrał ten materiał 6 lata temu.

Komentarze i opinie (0)

Transkrypt ( 25 z dostępnych 279 stron)

3 Spis treści Wstęp .............................................................................................................................7 1. Język R .......................................................................................................................... 13 Język R w uczeniu maszynowym 14 Pobieranie i instalowanie R 16 Edytory plików tekstowych i środowiska programistyczne 19 Ładowanie i instalowanie pakietów R 20 Podstawy R w uczeniu maszynowym 23 Dodatkowe materiały o R 36 2. Eksplorowanie danych ................................................................................................39 Analiza eksploracyjna i analiza potwierdzająca 39 Czym są dane? 40 Wnioskowanie o typach danych w kolumnach 43 Wnioskowanie o znaczeniu wartości 45 Podsumowania liczbowe 46 Średnie, mediany i dominanty 46 Kwantyle 48 Odchylenia standardowe i wariancje 49 Eksploracyjne wizualizacje danych 52 Wizualizowanie powiązań pomiędzy kolumnami 67 3. Klasyfikacja — odsiewanie spamu .............................................................................73 To czy nie to? Klasyfikacja binarna 73 Płynne przejście do prawdopodobieństwa warunkowego 77 Nasz pierwszy bayesowski klasyfikator spamu 78 Definiowanie i testowanie klasyfikatora na wątpliwych wiadomościach treściwych 84 Testowanie klasyfikatora na wiadomościach wszystkich typów 88 Polepszanie wyników klasyfikacji 91

4  Spis treści 4. Układanie rankingu — priorytetowa skrzynka pocztowa ........................................93 Jak uporządkować, nie znając kryterium? 93 Układanie wiadomości e-mail według ważności 94 Cechy istotności wiadomości e-mail 95 Implementacja skrzynki priorytetowej 99 Funkcje wyłuskujące wartości cech 99 Tworzenie mechanizmu nadawania wag 106 Nadawanie wag na podstawie aktywności w wątku 110 Uczenie i testowanie algorytmu układającego ranking 115 5. Regresja — przewidywanie odsłon stron ................................................................ 123 Wprowadzenie do regresji 123 Model wyjściowy 123 Regresja z użyciem zmiennych sztucznych 126 Podstawy regresji liniowej 128 Przewidywanie odwiedzin stron WWW 135 Definiowanie korelacji 145 6. Regularyzacja — regresja tekstu .............................................................................. 149 Nieliniowe zależności pomiędzy kolumnami — świat krzywych 149 Wstęp do regresji wielomianowej 152 Metody zapobiegania nadmiernemu dopasowaniu 158 Zapobieganie nadmiernemu dopasowaniu przez regularyzację 162 Regresja tekstu 166 Pociecha w regresji logistycznej 170 7. Optymalizacja — łamanie szyfrów ...........................................................................175 Wprowadzenie do optymalizacji 175 Regresja grzbietowa 181 Łamanie szyfrów jako problem optymalizacji 185 8. Analiza głównych składowych — budowanie indeksu rynku ................................ 195 Uczenie nienadzorowane 195 9. Skalowanie wielowymiarowe — uwidocznianie podobieństwa polityków .........203 Grupowanie na podstawie podobieństwa 203 Wprowadzenie do miar odległości i skalowania wielowymiarowego 204 Jak się grupują amerykańscy senatorzy? 209 Analiza rejestrów głosowań w Senacie (kongresy 101. – 111.) 210

Spis treści  5 10. kNN — systemy rekomendacyjne.............................................................................. 219 Algorytm kNN 219 Dane o instalacjach pakietów języka R 224 11. Analiza grafów społecznych .....................................................................................229 Analiza sieci społecznych 229 Myślenie grafowe 231 Pozyskiwanie danych do grafu społecznego Twittera 233 Praca z API usługi SocialGraph 236 Analiza sieci Twittera 241 Lokalna struktura społeczna 242 Wizualizacja pogrupowanej sieci społecznej Twittera w programie Gephi 246 Własny mechanizm rekomendacji wartościowych twitterowiczów 251 12. Porównanie modeli ...................................................................................................259 SVM — maszyna wektorów nośnych 259 Porównanie algorytmów 269 Bibliografia ................................................................................................................274 Skorowidz ..................................................................................................................276

6  Spis treści

7 Wstęp Aby dobrze przedstawić perspektywę, z jakiej książka ta została napisana, najlepiej będzie zdefiniować nasze rozumienie uczenia maszynowego i nasze rozumienie programisty. Czym jest uczenie maszynowe? Na najwyższym poziomie abstrakcji uczenie maszynowe może- my traktować jako zestaw narzędzi i metod, których celem jest określenie wzorców i wyłuskanie istotnych elementów z zarejestrowanych aspektów obserwowalnego świata. Jeśli na przykład próbujemy nauczyć komputer rozpoznawać kody pocztowe na kopertach, możemy użyć da- nych składających się z fotografii kopert wraz z listą kodów pocztowych, które na tych kopertach widnieją. W obrębie pewnego kontekstu możemy więc zarejestrować zdarzenia z przed- miotowej dziedziny, uczyć się z tego rejestru, a potem utworzyć model, który zorientuje nasze zrozumienie kontekstu. W praktyce wymaga to danych, co we współczesnych zastosowaniach może oznaczać ich mnóstwo (liczone choćby i w terabajtach). Większość technik uczenia ma- szynowego zakłada dostępność owych danych, a w obliczu ilości danych będących niejako produktem ubocznym działalności współczesnych firm wachlarz zastosowań uczenia maszy- nowego wciąż się poszerza. A kim jest nasz programista? W naszym rozumieniu to ktoś, kto lubi rozwiązywać problemy i eksperymentować z nowymi technologiami. Każdy, kto złapał się kiedyś na dulczeniu nad najnowszą książką o nowym języku programowania, maltretując kod dopóty, dopóki nie wyszedł dalece poza obowiązkowe „Hello World”, może nazwać siebie programistą. Każdy, kto ślęczał nad czyimś oprogramowaniem, aby je ulepszyć lub wykorzystać w nieprzewidziany sposób, może się nazywać programistą. Owe pościgi są najczęściej podejmowane wyłącznie na zasadzie wyzwania oraz dla zyskania wiedzy o działaniu nieznanej wcześniej technologii. Obok wrodzonej dociekliwości i żądzy tworzenia programista ma też doświadczenie w pro- jektowaniu i pisaniu oprogramowania. Dla nas jest to ktoś, kto pisał już programy, zapewne w wielu różnych językach programowania. Dla programisty Unix nie jest li tylko czterolitero- wym słowem, a posługiwanie się konsolą tekstową i skryptami powłoki przychodzi mu rów- nie łatwo (albo łatwiej), jak klikanie w GUI. Nieobce mu są wyrażenia regularne, a klasyczne narzędzia, takie jak sed, awk czy grep, to jego pierwsza linia wsparcia przy pracy z danymi tekstowymi. W poszczególnych rozdziałach książki będziemy więc zakładać stosunkowo wysoki poziom tego rodzaju umiejętności.

8  Wstęp Organizacja materiału Uczenie maszynowe łączy pomysły i techniki z wielu różnych tradycyjnych dyscyplin, takich jak matematyka, statystyka i informatyka. Skoro tak, to zagadnienia uczenia maszynowego można poznawać z różnych stron. Z uwagi na osadzenie uczenia maszynowego w matematyce i statystyce warto na wstępie zapoznać się w jakimś stopniu z formalnymi specyfikacjami podstawowych technik uczenia maszynowego. Można do tego wykorzystać jedną z wielu świet- nych książek poświęconych podstawom tej dziedziny, klasyczną pracę Hastiego, Tibshiraniego i Friedmana The Elements of Statistical Learning ([HTF09]; komplet odniesień do literatury znajduje się w dodatku „Bibliografia”)1 . Ale programista praktyk uczy się przede wszystkim przez ćwiczenie. Wielu programistów woli traktować problemy pod kątem procesu prowadzącego do rozwiązania, a nie ślęczeć nad teoretycznymi podstawami problemu i jego rozwiązania. Z tej perspektywy alternatywnym podejściem do uczenia maszynowego byłoby przećwiczenie „recept” programistycznych dla przykładowych problemów. Aby na przykład przybliżyć działa- nie systemów rekomendacyjnych, moglibyśmy dostarczyć próbkę danych zbioru uczącego oraz wersję modelu, a potem pokazać, jak model korzysta z danych. To podejście również jest dobrze reprezentowane w literaturze, choćby w postaci niedawnej publikacji Programming Collective Intelligence [Seg07] Toby’ego Segarana. W ten sposób wyczerpalibyśmy tematykę „jak”, ale nieko- niecznie tematykę „dlaczego”. Poza przyswojeniem sobie samej mechaniki danej metody warto dowiedzieć się, dlaczego właśnie ona została użyta w kontekście danego problemu. Aby wyposażyć programistów praktyków w lepszą wiedzę o uczeniu maszynowym, musimy znaleźć kompromis pomiędzy głęboką analizą podstaw teoretycznych tej dyscypliny a szerokim przeglądem stosowania jej w zadaniach praktycznych. Dlatego postanowiliśmy pokazywać uczenie maszynowe w kontekście konkretnego proble- mu, owszem, ale z prezentacją i wyjaśnieniem działania narzędzi wykorzystywanych typowo w jego rozwiązaniach. Na tej zasadzie działają nasze studia przypadków, z tym że unikamy wałkowania problemów, dla których być może nie istnieje znane nauce rozwiązanie — kon- centrujemy się na tych problemach uczenia maszynowego, które zostały dobrze rozpoznane, i prezentujemy konkretne przykłady przypadków, w których niektóre rozwiązania sprawdziły się znakomicie, a inne widowiskowo zawiodły. Każdy rozdział tej książki jest więc zamkniętym studium przypadku, ukierunkowanym na jeden konkretny problem uczenia maszynowego. Pierwsze przypadki to przejście od klasyfi- kacji do regresji, a niektóre studia przypadków będą ujmować (jawnie albo mniej jawnie) ele- menty obu. Potem omawiamy grupowanie (ang. clustering), redukcję wymiarowości i opty- malizację. Trzeba zaznaczyć, że nie wszystkie problemy są czyste, to znaczy nie wszystkie pasują idealnie do klasy problemów regresji czy klasyfikacji. Niektóre przypadki analizowane w książce zawierają więc elementy obu klas (niekiedy jawnie, a niekiedy w subtelnych aspek- tach omawianych dodatkowo). Oto krótki spis wszystkich studiów przypadków z tej książki, w kolejności występowania: Klasyfikacja tekstu — wykrywanie spamu W tym rozdziale wprowadzamy koncepcję klasyfikacji binarnej na przykładzie wykorzy- stującym dane tekstowe z wiadomości e-mail. Podejmujemy tam klasyczny problem 1 Tekst książki The Elements of Statistical Learning można obecnie pobrać nieodpłatnie ze strony http://www- stat.stanford.edu/~tibs/ElemStatLearn/.

Organizacja materiału  9 uczenia maszynowego w postaci klasyfikowania pewnych danych wejściowych do jed- nego z dwóch typów (w tym przypadku są to wiadomości wartościowe oraz wiadomości niechciane). Układanie rankingu — priorytetowa skrzynka pocztowa Na podstawie tych samych danych tekstowych z wiadomości e-mail przechodzimy od kla- syfikacji binarnej do predefiniowanych typów. Tym razem chcemy zidentyfikować te cechy wiadomości, które najlepiej świadczą o ich „ważności” względem innych wiadomości. Modele regresji — przewidywanie popularności stron WWW Tutaj wprowadzamy drugie podstawowe narzędzie uczenia maszynowego w postaci re- gresji liniowej. W rozdziale eksplorujemy dane, w których da się zauważyć zależność modelowana (mniej więcej) linią prostą. W ramach studium przypadku chcemy przewi- dzieć liczbę odwiedzin dla 1000 najpopularniejszych stron WWW w internecie (według danych z 2011 roku). Regularyzacja — regresja tekstowa Niekiedy zależności występujące w danych nie dają się dobrze opisać linią prostą. Aby jed- nak je ująć, musimy uciec się do innej, bardziej złożonej funkcji. Pułapką jest tutaj ryzyko nadmiernego dopasowania. W rozdziale wprowadzamy pojęcie regularyzacji jako środka zapobiegawczego do nadmiernego dopasowania modeli regresji i przekładamy to na studium przypadku, w którym próbujemy wykryć zależności pomiędzy słowami w opisach książek wydawnictwa a popularnością tych książek. Optymalizacja — łamanie szyfrów Wychodząc poza modele regresji, niemal każdy problem uczenia maszynowego można postrzegać jako problem optymalizacji, w którym próbujemy zminimalizować pewną miarę błędu predykcji. W tym rozdziale prezentujemy klasyczne algorytmy optymalizacji i próbujemy za ich pomocą złamać prosty szyfr literowy. Uczenie nienadzorowane — budowanie indeksu giełdowego Aż do tego momentu zajmowaliśmy się wyłącznie technikami uczenia maszynowego nadzorowanego. Tutaj omawiamy jego metodologiczne przeciwieństwo w postaci uczenia nienadzorowanego. Różnica sprowadza się do tego, że w uczeniu nadzorowanym chcemy użyć wykrytej struktury danych do stawiania prognoz (predykcji); w uczeniu nienadzoro- wanym celem jest samo wykrycie struktury danych. W ramach studium przypadku usi- łujemy na podstawie danych z rynku akcji utworzyć indeks, który opisuje ogólną „kondycję” rynku. Podobieństwo przestrzenne — grupowanie senatorów Kongresu USA na podstawie rejestrów głosowań Kolejny rozdział wprowadza pojęcie odległości pomiędzy obserwacjami. Definiujemy miary odległości i opisujemy metody grupowania obserwacji na podstawie odległości pomiędzy nimi. Dane z rejestrów głosowań w Kongresie USA wykorzystujemy do pogru- powania legislatorów według poglądów wyrażanych w głosowaniach. System rekomendacyjny — sugerowanie programistom języka R wartościowych bibliotek Kontynuując omawianie zagadnień podobieństwa przestrzennego, pokazujemy, jak zbudo- wać system rekomendacyjny oparty na bliskości obserwacji w przestrzeni. W rozdziale poja- wia się algorytm k-najbliższych sąsiadów (kNN), wykorzystany do sugerowania pakietów R programistom tego języka na podstawie tego, jakie pakiety mają już zainstalowane.

10  Wstęp Analiza sieci społecznych — kogo obserwować na Twitterze W tym rozdziale podejmujemy próbę połączenia wielu omawianych wcześniej (oraz kil- ku nowych) koncepcji, usiłując zaprojektować i zbudować system rekomendujący, „kogo obserwować” na podstawie danych z serwisu Twitter. Na potrzeby systemu budujemy mechanizm pobierania danych o sieci Twittera, wykrywamy lokalne społeczności w sieci społecznej i na bazie podstawowych technik analizy sieci społecznych rekomendujemy wartościowych użytkowników do obserwowania. Porównywanie modeli — typowanie najlepszego algorytmu do rozwiązania problemu W ostatnim rozdziale omawiamy techniki pozwalające na skuteczne wybieranie algorytmów uczenia maszynowego odpowiednich do rozwiązania postawionego problemu. Omawiamy też ostatni z algorytmów uczenia maszynowego, SVM (ang. support vector machine), a następ- nie porównujemy jego sprawność ze sprawnością wcześniej omawianych modeli, po- nownie posługując się danymi o wiadomościach e-mail z rozdziału trzeciego. Najważniejszym narzędziem eksploracji tych przypadków będzie język programowania R (http://www.r-project.org/). Język R szczególnie dobrze nadaje się do przypadków uczenia maszy- nowego, ponieważ jest wysokopoziomowym, funkcyjnym językiem skryptowym zaprojektowa- nym właśnie pod kątem analizy danych. Większość potrzebnych nam algorytmów statystyczno- analitycznych mamy już do dyspozycji w samym języku, a mnóstwo innych jest dostępnych w tysiącach gotowych pakietów R, gromadzonych w repozytorium CRAN (Comprehensive R Archive Network)2 . Konwencje typograficzne W książce wykorzystano następujące konwencje typograficzne: Czcionka pochylona Adresy URL, adresy e-mail, nazwy plików i rozszerzenia nazw plików. Czcionka pogrubiona Nowe pojęcia. Czcionka o stałej szerokości znaków Kod źródłowy programów przykładowych, a także tekst w obrębie akapitów odnoszący się do elementów programu, takich jak zmienne czy nazwy funkcji, nazwy baz danych, typów danych, zmiennych środowiskowych, instrukcji i słów kluczowych języka C#. Pogrubiona czcionka o stałej szerokości znaków Oznaczenie tekstu, który należy wprowadzić dosłownie, zgodnie z wykonywaną krok po kroku procedurą. Pochylona czcionka o stałej szerokości znaków Oznaczenie kodu, który należy zastąpić odpowiednią wartością wynikającą z kontekstu omówienia. 2 Pozwoli to nam skoncentrować się na analitycznym podejściu do rozwiązywania stawianych problemów, bez konieczności własnoręcznego implementowania podstawowych algorytmów.

Podziękowania  11 Ikona oznaczająca wskazówkę bądź sugestię. Ikona ostrzeżenia, uwaga o szczególnym znaczeniu. Korzystanie z programów przykładowych Niniejsza książka ma przede wszystkim być skuteczna i pomóc Czytelnikom wykonać ich zadania. Zasadniczo więc kod przykładów prezentowanych w książce można swobodnie wykorzystywać we własnych programach i ich dokumentacji. Nie wymaga to zgody autorów, chyba że w grę wchodzi zreprodukowanie znaczącej ilości kodu programów przykładowych. A więc program, który zawiera pojedyncze fragmenty kodu przykładowego, nie wymaga ubiegania się o osobną zgodę od autorów książki. Natomiast na przykład sprzedaż czy dys- trybucja płyt CD-ROM zawierających komplet przykładów zaczerpniętych z książek O’Reilly wymaga uzyskania zgody. Umieszczenie w dokumentacji odpowiedzi na jakieś pytanie na zasadzie odniesienia do książki wraz z cytatem z kodu przykładowego nie wymaga osobnej zgody, natomiast włączenie do dokumentacji programu znaczącej liczby przykładów z niniej- szej książki wymaga uzyskania zgody. We wszystkich przypadkach użycia kodu przykładów będziemy wdzięczni za podanie nazwisk autorów, tytułu książki, wydawcy i ISBN-u, na przykład: „Uczenie maszynowe dla programi- stów, Helion 2015, copyright © 2012 Drew Conway, John Myles White, 978-83-246-9816-5”. Każdy, kto uzna, że planowany przez niego sposób wykorzystania kodu programów przykła- dowych wykracza poza zakres dozwolonego użytku albo poza wyrażoną powyżej zgodę, po- winien skontaktować się z wydawcą w celu uzyskania właściwych pozwoleń. Podziękowania Od obu autorów Przede wszystkim chcemy podziękować naszej redaktor Julie Steele za przeprowadzenie nas przez całość procesu publikacji książki. Chcielibyśmy również podziękować Melanie Yarbrough i Genevieve d’Entremont za ich niezwykle staranną pracę przy oczyszczaniu tekstu przed publikacją. Podziękowania należą się też innym pracownikom O’Reilly, którzy pomogli w ulepszeniu książki, choć ich praca nie przebijała się na pierwszy plan. Poza miłą ekipą z O’Reilly na podziękowania zasłużyli również nasi recenzenci techniczni: Mike Dewar, Max Shron, Matt Canning, Paul Dix i Maxim Khesin. Ich uwagi pozwoliły zdecydowanie udoskonalić książkę; wszelkie jej słabości, jeśli pozostały, są już naszą wy- łączną winą.

12  Wstęp Dziękujemy również członkom NYC Data Brunch za zainspirowanie nas do napisania książki i za oferowanie miejsca, w którym mogliśmy szlifować swoje pomysły na uczenie uczenia maszynowego. W szczególności dziękujemy Hilary Mason za przedstawienie nas kilku osobom w wydawnictwie O’Reilly. Na koniec dziękujemy licznym przyjaciołom w społeczności praktyków analizy danych, którzy wspierali nas w pracy nad książką. Wiedząc, że ktoś czeka na naszą publikację, potra- filiśmy utrzymać tempo w tym maratonie, jakim niewątpliwie jest pisanie „pełnowymiaro- wej” książki. Od Drew Conwaya Chciałbym podziękować naszej redaktor Julie Steele za docenienie naszego zapału i umożli- wienie nam wydania tej książki. Chciałbym też podziękować tym wszystkim, którzy zgłaszali swoje uwagi i spostrzeżenia zarówno wtedy, gdy pracowaliśmy nad książką, jak i wów- czas, gdy już została wydana, ale w szczególności dziękuję Mike’owi Dewarowi, Makso- wi Shronowi i Maksowi Khesinowi. Dziękuję też mojej Żonie, Kristen, która zawsze mnie inspirowała i towarzyszyła mi stale podczas pracy nad publikacją. A na koniec dziękuję Współautorowi, Johnowi — za sam pomysł na napisanie książki tego rodzaju i za wizję jego udanej realizacji. Od Johna Mylesa White’a Przede wszystkim chciałbym podziękować Współautorowi, Drew, za wspólne pisanie książki. Towarzystwo w wielkim wysiłku pisania całej książki sprawiło, że był to znój znośny, a nawet przyjemny. Dodatkowo chciałbym podziękować moim Rodzicom — za nieustawanie w zachęcaniu mnie do zgłębiania wszystkiego, co tylko mnie interesowało. Dziękuję też Jennifer Mitchel i Jeffreyowi Achterowi — za ukierunkowanie mnie na stu- dia matematyczne. Moje lata studenckie ukształtowały mój ogląd świata i jestem tej dwójce bardzo wdzięczny za ich rolę w tym okresie. Podziękowania chciałbym też skierować do mojego przyjaciela Hareka — za stałe inspirowanie mnie do przekraczania swoich granic i zwiększania wysiłków. Dziękuję zespołowi La Dispute za ich soundtrack, przy którym pracowałem nad książką. A na koniec chciałbym podziękować wielu ludziom, którzy dali mi miejsce do pracy — przyjaciołom, u których wysiadywałem kanapy, i właści- cielom Boutique Hotel Steinerwirt 1493 i Linger Cafe, gdzie szlifowałem pierwsze i póź- niejsze wersje tekstu książki.

ROZDZIAŁ 1. Język R Uczenie maszynowe to dziedzina z pogranicza tradycyjnej matematyki i statystyki z jednej strony, a informatyki i inżynierii oprogramowania z drugiej. W niniejszej książce będziemy więc między innymi poznawać klasyczne narzędzia statystyczne po�alające opisywać (i poj­ mować) świat. Statystyka od zawsze polegała na wyłuskiwaniu ���ych danych czegoś, co można zinterpretować. Uczenie maszynowe to zamienianie s ych danych na coś, co da się użyć w praktyce. To porównanie pozwala na lepsze ��i�i pojęcia uczenia maszy­ nowego- uczenie maszynowe to uczenie komputerów cze . gA_��szym świecie; ma to im po­ zwolić wykonywać rozmaite zadania. Tymczasem staty��dyscyplina zajmująca się raczej opracowywaniem narzędzi, które pozwalają uczyć�� .; �aszym świecie ludzi. Ludzie dzię­ ki statystyce mogą lepiej pojmować świat oraz jego�vści i podejmować lepsze decyzje. W uczeniu maszynowym proces uczenia pole R Q.Jyodrębnianiu z danych możliwie dużej ilości informacji za pomocą algorytmów prze�zających podstawowe struktury dostępnych danych i oddzielających w nich sygnał u�ny od szumu. Po wyłuskaniu sygnału (albo ina­ czej po rozpoznaniu wzorca) algorytm�Momijać resztę danych właśnie jako nieznaczący szum. Nieprzypadkowo więc al�or tm}-tdn szące się do zbioru danych wykorzystywanych w procesie uczenia maszynoweg�rwowanie danych, uczenie się z nich i potem wykorzystanie po­ zyskanej wiedzy do automatyzowania elementów procesu poznawczego jest też osią niniejszej książki. Skoncentrujemy się przy tym na dwóch istotnych problemach i wzorcach, a równo­ cześnie narzędziach uczenia maszynowego: problemie klasyfikacji i problemie regresji. Na potrzeby omówienia zakładamy, że Czytelnik dysponuje stosunkowo zaawansowaną wiedzą o technikach programowania i algorytmach. Trzeba zaznaczyć, że wykorzystywany w książce językR jest językiem poniekąd niszowym i często obcym nawet dla doświadczonych programistów. Aby więc zacząć z równego poziomu, skupimy się na podstawach stosowania językaR; dopiero w dalszej części rozdziału zajmiemy się rozszerzonym omówieniem pracy z danymi w tym języku. 13

Niniejszy rozdział nie stanowi wcale kompletnego wprowadzenia do programowa­ nia w języku R. Łatwo się domyśli( że takie wprowadzenie zajęłoby więcej miejsca niż jeden rozdział. Chodzi raczej o przygotowanie Czytelnika do wykonywania zadań związanych z uczeniem maszynowym w R ze szczególnym uwzględnieniem ładowa- nią czyszczenia i analizowania danych. O samym języku, jego podstawach, typach danych, koncepcjach arytmetycznych i zalecanych technikach programistycznych można przeczytać w innych wydawnictwach. Tu będziemy poznawać aspekty R tylko w takim stopniu, w jakim będą konieczne do analizowania poszczególnych studiów przypadków. Czytelników zainteresowanych pełniejszym omówieniem R odsyłamy do materiałów wymienionych w tabeli 1.3. Tym, którzy nigdy jeszcze nie mieli styczności z językiem R i jego składnią, gorąco polecamy lekturę tego wprowadzenia. W przeciwieństwie do innych wysokopoziomowych języków skryptowych, jak Python czy Ruby, język R cechuje się unikatową składnią, przez co jego opa­ nowanie bywa trudniejsze niż w przypadku bardziej klasycznych języków. Z kolei tych, którzy już stosowali język R, ale nie w kontekście uczenia maszynowego, i tak zachęcamy do zapo­ znania się z treścią niniejszego rozdziału w ramach przypomnienia i�pu. Ję���ję��ś�:�:�:�����o O ;�n:��anffi obliczeń sffio/- stycznych. Język R udostępnia szeroki wachlarz tec�Vatystycznych (modelowanie liniowe i nieliniowe, klasyczne testy statystycz���zia klasyfikacji i klastrowania) oraz technik obrazowania, z dużymi możliw��rozbudowy. Pierwszym wyborem wśród badaczy metod statystycznych jest za�zaj język S, natomiast R świetnie się sprawdza jako otwarte narzędzie do ucz�zenia w podobnych badaniach. -za TheR Project f�istical Computing (http://www.r-project.org/) Najsilniejszą stronąR jest to, ż�k'st�ciem sffityso/ków. A najsłabsze w R jest to, że... jest dziełem statystyków. � • � -Bo Cowgill, Google R to niezwykle efektyw,k\,zyk manipulowania danymi i ich analizowania. Jego gwałtownie rosnąca popularność wWspołeczności analityków danych i badaczy uczenia maszynowe­ go sprawiła, że pełni de facto funkcję lingua franca analityków. Sukces językaR w społeczności osób parających się analizą danych wynika z dwóch czynników opisanych w powyższych mottach: R daje statystykom większość znanych im narzędzi w postaci gotowych rozwiązań, a do tego ma silne wsparcie ze strony społeczności tych statystyków, którzy są równocześnie zapalonymi działaczami ruchu otwartego oprogramowania. Jako język przeznaczony typowo do obliczeń statystycznych ma R w tym zakresie liczne prze­ wagi nad innymi środowiskami programistycznymi. Zgodnie z powyższym fragmentem opi­ su R ze strony projektu macierzystego język ten stanowi pomost do specjalistycznego języka S, wyposażonego w liczne wbudowane wysokopoziomowe funkcje statystyczne. Na przykład przeprowadzenie podstawowej regresji liniowej w R sprowadza się do przekazania danych do funkcji lm, która zwraca obiekt zawierający szczegółowe informacje o wynikach regresji (ze współczynnikami, wartościami błędów standardowych, reszt itd.). Dane te mogą potem zostać łatwo zobrazowane poprzez przekazanie tego obiektu do funkcji wizualizacji pl ot. 14 Rozdział 1. Język R

W innych językach, również popularnych w środowiskach naukowych, jak chocby Python, przeprowadzenie analogicznej operacji wymaga korzystania z licznych bibliotek zewnętrznych do reprezentacji danych (NumPy), wykonywania analizy (SciPy) i wreszcie do obrazowania wyników analizy (matplotlib). Jak się wkrótce przekonamy, w języku R taka (wcale przecież zaawansowana) analiza zawiera się w pojedynczym wierszu kodu. Ponadto, podobnie jak w innych środowiskach przeznaczonych do naukowych obliczeń kom­ puterowych, podstawowym typem danych wR jest wektor. Wektory mogą być agregowane i na różne sposoby organizowane, ale tak czy inaczej, elementarną jednostką danych w języku R zawsze jest wektor. To dość silne ograniczenie dostępnych struktur danych wydaje się nazbyt ostre, ale jest przecież logiczną konsekwencją specjalizacji języka do zastosowań statystycznych. Najczęściej wykorzystywaną strukturą danych w R jest ramka danych (ang. data frame), którą można porównać do macierzy uzupełnionej atrybutami - swego rodzaju wewnętrznego "arkusza kalkulacyjnego" albo struktury relacyjnej na wzór relacyjnych baz danych, ale osa­ dzonej w samym rdzeniu języka.Ramka danych jest co do zasady kolumnowym agregatem wektorów z rozbudowanymi funkcjami i świetnie sprawdza się przy pracy z różnymi zbio- rami danych analitycznych. �Przy całej swej efektywności język R ma również wady. ae wszystkim obliczenia w R nie skalują się dobrze do dużych zbiorów�n hh���ć podejmowano liczne wysiłki w celu polepszenia skalowalności wydajno�i�roblem pozostaje poważny. Nie będzie to przeszkodą przy analizowanyc�e· Cliach przypadków, a wszystkie budowane przez nas systemy będą miały r j arakter prototypowy. To rozróż­ nienie jest o tyle istotne, że jeśli ktoś pr�a ię do budowania systemów operują­ cych w skali danych posiadanych przez gigantów jak Facebook czy Google, R nie będzie właściwym rozwiązanie� awet wymienione firmy stosują często R właśnie jako narzędzie prototyp�"" eksperymentowaniu z nowymi metodami uczenia maszynowego na ��ych, testowych zbiorach danych. Jeśli któryś z takich eksperymentów �d obiecująco, inżynierowie stają wtedy przed zada- niem odwzorowania wyk w R obliczeń w innych technologiach (w skrajnych przypadkach chocby jęz C). • o na danych w znacznej mierze uformował społeczność używającą języka R, a także orzystującą doświadczenie swoich członków do jego rozbu­ dowywania i rozwijan*·a. a auważył Bo Cowgill, R narodził się z potrzeby statystyków, aby posiadali środowi bliczeniowe odpowiadające ich specyficznym potrzebom. Wielu użytkowników języka R o eksperci w różnych dziedzinach analizy, od matematyki, przez statystykę, biologię, chemię, fizykę, psychologię i ekonomię, do nauk politycznych i socjologii. Tak zróżnicowane grono ekspertów zdołało z czasem zbudować olbrzymią kolekcję pakietów uzupełniających podstawowe funkcje R. W czasie przygotowywania tego wydania repozyto­ rium pakietów języka R CRAN zawierało już ponad 5700 pakietów. Niewielką część z nich będziemy mieli okazję zastosować w studiach przypadków, ale będziemy bardzo daleko od wyczerpania możliwości języka i środowiskaR. Druga, sarkastyczna część recenzji języka R Cowgilla wydaje się niepokojąca, ale w istocie jest podkreśleniem siły społeczności R. Jak się przekonamy, język R posiada szczególnie dzi­ waczną składnię i kryje w sobie liczne pułapki, które odstręczają nawet doświadczonych programistów. Ale wszelkie składniowe i gramatyczne zawiłości języka dają się w końcu opa­ nować przy odpowiedniej dawce uporu. Znacznie trudniejsze od samego języka, zwłaszcza dla osób spoza kręgu nauk statystycznych, jest to, że zakłada się szerokie obeznanie użytkownika z metodami matematycznymi i statystycznymi wbudowanymi wR. Przytoczmy chocby przykład Język R w uczeniu maszynowym 15

funkcji regresji liniowej lm -jeśli ktoś nie przeprowadzał wcześniej regresji liniowej, nie wie nawet, jak poszukać współczynników, wartości błędów standardowych i reszt w zwróconych wynikach. Ba, nie wie też, jak te wartości zinterpretować, i językR mu w tym nie pomaga.Ale je­ go otwarte źródła pozwalają zawsze zajrzeć do kodu funkcji i zobaczyć, jak ona działa. W ni­ niejszej książce podejmiemy próbę przedstawienia możliwie licznej grupy funkcji używanych w uczeniu maszynowym, ale mimo wszystko będzie to tylko niewielki ułamek środowiska obliczeniowego R. Na szczęście społeczność użytkowników języka jest pełna uczynnych osób, które chętnie pomagają zrozumieć nie tylko sam język, ale też implementowane w nim metody obliczeniowe. Miejsca grupujące aktywną społeczność wymienia tabela 1.1 -od tych miejsc najlepiej zacząć. Tabela 1.1. Zasoby spolecznościowe języka R Rodzaj RSeek Oficjalna lista mailingowaR StackOverflow #rstarts na Twitterze R-Bioggers Adres http:jjrseek.orgj http:jjwww.r-project. orgjmail.html http:jjstackoverflow. comjquestionsjtaggedjr https:jjtwitter.coml hashtagjrstats Opis Kiedy zespół programistyczny postanowił utworzyć otwartą wersję języka S pod nazwąR, nie przewidział, jak jednoliterowanazwajęzykabędzieutrudniać szukanie w sieci WWN dokumentacji i informacji. Powstała więc specjalizowana wyszukiwarka, skutecznie kierująca do dokum�w, artykułów i informacji oR. JęzykowiR poświęconych jest kilka osob�>mailingowych, dotyczących samego języka, ogłoszeń z rozw�oje��ystemu pakietów, procesu rozwojowego i- rzecz jasna ���Nielu współtwórcówR to stali bywalcy tych list, dzięki czem�. �ne tu pytania często doczekują się odpowiedzi szybkiej i ko�e�tf' Programiści ceni$o ·e �verflow.com jako jedno z najbardziej wartościowych zr powiedzi dla programistów wszelakich języków;R nie jest wyjątki�z i wysiłkom szeregu ważnych członków społeczności R StackOv��iada również imponującą kolekcję pytań i odpowiedzi dotyczącyt9 Uż�yR udzielają się też na Twitterze, publikując pod specjalnym �Vstats.Można tu znaleźć odnośniki do użytecznych materiałów, o�ać ekspertów od językaR i zadawać im pytania- byle tylko zmieścić 4....\. s� w 140 znakach! http:jjwww. �� Setki osób blagują o tym, jak używająR w swoich pracach badawczych r-bloggers.comJ. i praktycznych, a także z zamiłowania.R-bloggers.com to agregator takich blogów, gromadzący w jednym miejscu wszystko, co pisze się oR w blogosferze; to świetne źródło przykładów dydaktycznych. W pozostałej części rozdziału pobierzemy oprogramowanie, zainstalujemy je wraz z dodatko­ wymi pakietami i rozpoczniemy korzystanie z językaR. Zakończymy króciutkim studium przy­ padku w ramach wprowadzenia do niektórych idiomów językaR, z których będziemy korzystać w następnym rozdziale, a które dotyczą ładowania, oczyszczania, porządkowania i analizowania danych. Pobieranie i instalowanie R Nie inaczej niż w innych projektach open source,R jest rozprowadzany za pośrednictwem ze­ stawu regionalnych serwerów-mirrorów. Jeśli na komputerze nie ma jeszcze zainstalowanego językaR, pierwsze zadanie polega na pobraniu oprogramowania. W tym celu należy przejść na stronę http://cran.r-project.org/mirrors.html i wybrać z listy serwer lustrzany znajdujący się możliwie blisko naszego regionu. Następnie trzeba wybrać i pobrać dystrybucjęR odpowiednią dla posiadanego systemu operacyjnego. 16 Rozdział 1. Język R

R jest zależny od szeregu bibliotek kompilowanych z języków C i Fortran. Wobec tego, za­ leżnie od posiadanego systemu operacyjnego i zaznajomienia z kompilacją i budowaniem oprogramowania z pakietów źródłowych, możemy zdecydować się na instalację z kompletnej dystrybucji binarnej albo z paczki z kodem źródłowym. Poniżej prezentujemy instrukcje in­ stalacji R w systemach Windows, Mac OS X i Linux ze wskazówkami dotyczącymi wyboru dystrybucji. Parniętajmy też, żeR jest dostępny w wersjach 32- i 64-bitowych, co również trzeba uwzględnić przy pobieraniu i instalowaniu tego środowiska. Windows W przypadku systemu operacyjnego Windows przy instalacji R mamy do wyboru dwa pod­ katalogi dystrybucji języka R: base i contrib. Ten ostatni zawiera binarną, skompilowaną dla Windows wersję języka wraz z kompletem pakietów z CRAN; wersja base to wersja podstawowa. Wybieramy wersję bazową i pobieramy najnowszą kompilację. Doinstalowywanie pakietów dodatkowych można później łatwo przeprowadzić z poziomu samegoR, nie trzeba więc in­ stalować wszystkiego naraz. W toku instalacji należy wykonywać instrukcje wyświetlane przez instalator. ' Po zakończeniu instalacji aplikacja R pojawi się w menu Start. ��ku jej uruchomienia otworzy się okno RGui i R Console (jak na rysunku 1.1). .� R version 2.12.1 (2010-12-16) � Copyright (C) 2010 The R Foundat��� . o Statistical Computing ISBN 3-900051-07-0 Platform: i386-pc-ming1J32�i3 (3� - lt) R is free soft1Jare and c th ABSOLUTELY NO WARRANTY. You are 1Jelcome to r��t\� ibu e it under certain conditions. Type 'l�cense()' or �ce()' for d�str�but�on deta�ls. Natura! langua�upport but runn�ng �n an Engl�sh locale R �s a collabor�pro]ect 1J�th many contr�butors. Type 'contributors()' for more information and 'citation()' on ho1J to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or ' help.start()' for an HTML bro1Jser interface to help. Type 'q()' to quit R. > l Rysunek 1.1. RGui i R Console w systemie Windows Język R w uczeniu maszynowym 17

18  Rozdział 1. Język R W większości standardowych instalacji systemu Windows instalacja R powinna przebiegać bezproblemowo. W przypadku posiadania systemu specjalistycznie skrojonego i wystąpienia związanych z tym trudności najlepiej zapoznać się z dokumentem R for Windows FAQ, również publikowanym na serwerze dystrybucyjnym. Mac OS X Użytkownicy systemu Mac OS X mają to szczęście, że R jest instalowany domyślnie. Można to sprawdzić, uruchamiając aplikację terminalu Terminal.app i zwyczajnie wpisując R w konsoli poleceń — można już programować w R! Niektórzy użytkownicy preferują jednak korzystanie z wersji wyposażonej w graficzny interfejs użytkownika, wspomagającej pracę z konsolą R. Wymaga to zainstalowania osobnego pakietu oprogramowania. W systemie Mac OS X można to zrobić na dwa sposoby — z gotowego pakietu binarnego albo poprzez kompilację z pakietu źródłowego. Instalacja z pakietu binarnego — polecana użytkownikom bez doświadczenia w ko- rzystaniu z konsoli poleceń — sprowadza się do pobrania najnowszej kompilacji z lokalnego serwera dystrybucyjnego z listy http://cran.r-project.org/mirrors.html i postępowania zgodnie z wyświetlanymi instrukcjami. Gdy instalacja się zakończy, w systemie będzie zainstalowana zarówno aplikacja R.app (wersja 32-bitowa), jak i R64.app (wersja 64-bitowa) — można z nich korzystać zależnie od posiadanej wersji systemu Mac OS X i procesora; obie będą widoczne w folderze Applications. Podobnie jak w systemie Windows, w przypadku instalowania z pakietu binarnego nie spo- dziewamy się żadnych trudności. Po uruchomieniu nowo zainstalowanej aplikacji R zobaczy- my konsolę podobną do tej z rysunku 1.2. Rysunek 1.2. Konsola R Console w 64-bitowej wersji systemu Mac OS X

Język R w uczeniu maszynowym  19 Posiadacze zmodyfikowanej instalacji Mac OS X i ci, którzy chcą sobie inaczej skonfigu- rować samo środowisko R, powinni skorzystać z opcji instalacji z kodu źródłowego. Instalowanie R z pakietu kodu źródłowego w systemie Mac OS X wymaga zainsta- lowania w systemie kompilatorów języków C i Fortran, nieobecnych w standardowej in- stalacji systemu operacyjnego. Można je zainstalować samodzielnie z pakietem Mac OS X Developers Tools (często są dostępne na płytach DVD dołączanych do oryginalnego pakietu instalacyjnego) albo zainstalować niezbędne komponenty z podkatalogu tools serwera lustrzanego dystrybucji R. Gdy zaopatrzymy się w kompilatory potrzebne do przeprowadzenia instalacji z pakietów źródłowych, sama kompilacja i instalacja środowiska R sprowadza się do typowej procedury configure, make i install, właściwej dla większości oprogramowania dystrybuowanego w po- staci źródłowej — w terminalu poleceń Terminal.app należy przejść do folderu zawierającego kod źródłowy R i wykonać następujące polecenia: $ ./configure $ make $ make install W zależności od ustawień uprawnień wykonanie tych poleceń może wymagać poprzedzenia polecenia poleceniem sudo i podania hasła systemowego. W przypadku jakichkolwiek trudności podczas instalacji pakietów binarnych czy źródłowych należy skorzystać ze wskazówek za- wartych w dokumencie R for Mac OS X FAQ publikowanym na serwerach lustrzanych dys- trybucji R. Linux Podobnie jak w przypadku systemu Mac OS X, środowisko języka R w systemie Linux jest dostępne w postaci gotowych pakietów w wielu popularnych dystrybucjach. W większości typowych instalacji wystarczy więc wpisać w konsoli polecenie R, uruchamiające konsolę ję- zyka R — i już można programować! Serwery lustrzane CRAN zawierają też instrukcje in- stalacji uwzględniające najpopularniejsze dystrybucje systemu Linux: Debian, Red Hat, SUSE i Ubuntu. W przypadku tych systemów najlepiej trzymać się pakietów i dokumentacji do- starczonych z systemem, aby zapobiec ewentualnej niezgodności konfiguracji. Edytory plików tekstowych i środowiska programistyczne R to język skryptowy, co oznacza, że większość ćwiczeń w ramach analiz przypadków będziemy wykonywać w środowisku programistycznym albo po prostu w edytorze plików tekstowych. Raczej nie będziemy korzystać bezpośrednio z konsoli R w trybie interaktywnym. Jak się niebawem okaże, są co prawda czynności, dla których konsola R jest zupełnie wystarczająca (jak instalacja nowych pakietów R), ale typowe programowanie odbywa się poza trybem in- teraktywnym, przy użyciu dowolnego edytora plików tekstowych albo zintegrowanego śro- dowiska programistycznego (IDE). Dla użytkowników, którzy korzystają z graficznej wersji konsoli R (w systemach Windows i Mac OS X), konsola ta zawiera prosty edytor plików tekstowych, wywoływany poleceniem File/New Document albo przez kliknięcie ikony pustego dokumentu na pasku narzędziowym (ikona ta jest wyróżniona na rysunku 1.3). Ale większość programistów ma silne preferencje dotyczące środowisk programistycznych i (lub) edytorów kodu. Nie ma sensu na siłę zmieniać

20  Rozdział 1. Język R Rysunek 1.3. Ikona edytora tekstowego w graficznej wersji konsoli R przyzwyczajeń i warto używać znanych sobie narzędzi. Nie będziemy tu wymieniać najpopular- niejszych IDE i edytorów kodu czy edytorów plików tekstowych, żeby przypadkiem nie znaleźć się na linii ognia w wiecznej wojnie zwolenników Emacsa i Vima. Ładowanie i instalowanie pakietów R Zagadnienie uczenia maszynowego jest wspomagane liczną biblioteką porządnie przygoto- wanych i starannie utrzymywanych pakietów R. Na potrzeby przyszłych studiów przypad- ków będziemy korzystać między innymi z pakietów do analizy tekstu, obsługi danych geo- graficznych, struktur sieciowych, a także z pakietów obsługujących interfejsy popularnych usług WWW. Pakietów będziemy więc używać dość intensywnie. Ładowanie pakietów do skryptu R jest naprawdę nieskomplikowane. Służą do tego dwie funkcje: library i require. Są między nimi pewne drobne różnice, ale na potrzeby tego omówienia wy- starczy wiedzieć, że require zwraca wartość logiczną (TRUE lub FALSE) sygnalizującą dostęp- ność wskazanego pakietu. Na przykład w rozdziale 6. będziemy stosować pakiet tm z funkcjami do tokenizacji tekstu. Aby załadować potrzebne pakiety, możemy użyć funkcji library albo require. W poniższym przykładzie ładujemy pakiet tm za pomocą funkcji library, a pakiet XML z użyciem funkcji require. Wykorzystując funkcję print, możemy się przekonać, że pakiet XML jest zainstalowany w środowisku R, bo funkcja require po załadowaniu pakietu zwraca wartość TRUE: library(tm) print(require(XML)) #[1] TRUE Jeśli pakiet XML nie jest zainstalowany — to znaczy jeśli funkcja require zwróciła wartość FALSE — to przed kontynuowaniem przykładów powinniśmy pakiet XML zainstalować samodzielnie. W przypadku świeżej instalacji R przeprowadzenie ćwiczeń ze studiów przypadków będzie wymagało zainstalowania całego szeregu pakietów. Pakiety R instaluje się na dwa sposoby — z poziomu interfejsu graficznego lub za pomocą funkcji install.packages z konsoli języka R. Zakładamy, że Czytelnikom wygodniej będzie wykony- wać większość ćwiczeń z językiem R z poziomu konsoli, warto jednak choćby wskazać na możliwość instalowania pakietów R z poziomu interfejsu graficznego. Służy do tego polecenie menu Packages & Data/Package Installer, wywołujące okno podobne do tego z rysunku 1.4. W oknie tym należy wybrać z listy Package Repository pozycję CRAN (binaries) albo CRAN (sources) i załadować listę pakietów dostępnych do instalacji (przycisk Get List). Najnowsze wersje pakietów są publikowane w repozytorium kodu źródłowego pakietów CRAN (sources) i — jeśli tylko w systemie zainstalowane są wymagane kompilatory — zalecamy korzystanie właśnie z tego źródła pakietów. Po wybraniu pożądanych pakietów właściwą instalację inicjuje się kliknięciem przycisku Install Selected.

Język R w uczeniu maszynowym  21 Rysunek 1.4. Instalowanie pakietów R w konsoli R w wersji GUI Funkcja install.packages jest preferowanym sposobem instalowania pakietów, ponieważ daje większą elastyczność w wyborze sposobu i miejsca ich instalacji. Zasadniczą zaletą stosowania funkcji install.packages jest możliwość instalowania pakietów z paczek źródłowych pobra- nych już na komputer lokalny albo z repozytoriów zdalnych CRAN. Czasami zdarza się in- stalować pakiet, który nie jest jeszcze dostępny w repozytoriach CRAN — choćby w przypadku testowych i eksperymentalnych wersji pakietów. Instalacja z lokalnych paczek źródłowych jest wówczas jedynym sposobem: install.packages("tm", dependencies=TRUE) setwd("~/Downloads/") install.packages("RCurl_1.5-0.tar.gz", repos=NULL, type="source") W pierwszym wierszu stosujemy domyślny tryb instalacji pakietów z repozytorium CRAN. Pakiet tm zawiera funkcję używaną w rozdziale 3. do analizy tekstu i klasyfikowania wiadomości e-mail na bazie treści. Przydatnym parametrem funkcji install.packages jest mający domyślną wartość FALSE parametr dependencies, który nakazuje pobieranie i instalowanie wszelkich pa- kietów pomocniczych instalowanego pakietu. Warto zawsze ustawiać ten parametr na TRUE, zwłaszcza w przypadku świeżego środowiska R. Alternatywą jest instalowanie pakietu w postaci archiwum kodu źródłowego. W poprzednim przykładzie drugi instalowany pakiet, RCurl, był dostępny w paczce kodu źródłowego na stronie WWW autora. Za pomocą funkcji setwd zmieniamy bieżący katalog roboczy R na katalog za- wierający pobrane stamtąd archiwum, a następnie wywołujemy funkcję install.packages ze wskazaniem pliku archiwum pakietu. Tym razem do funkcji przekazaliśmy dwa dodatkowe parametry. Pierwszy z nich blokował próbę pobrania pakietu z repozytorium CRAN (repos=NULL), drugi określał typ lokalnego pakietu na pakiet źródłowy (type="source").

22  Rozdział 1. Język R Zapowiadaliśmy już, że w toku analiz w ramach studiów przypadków będziemy stosować szereg pakietów dodatkowych. Pakiety te są wymienione w tabeli 1.2 wraz z ich miejscem publi- kacji, autorami i przeznaczeniem. Zważywszy na liczbę potrzebnych pakietów, przygotowa- liśmy krótki skrypt upraszczający instalację kompletu pakietów wykorzystywanych w toku omówienia. Aby go uruchomić, należy w konsoli R skorzystać z funkcji setwd do ustawienia katalogu roboczego na folder zawierający kod dołączony do książki i wykonać polecenie: source("package_installer.R") Tabela 1.2. Pakiety używane w książce Pakiet Położenie Autor Opis i zakres użycia arm http://cran.r-project.org/ web/packages/arm/ Andrew Gelman i inni Pakiet do wielopoziomowych (hierarchicznych) modeli regresyjnych. ggplot http://cran.r-project.org/web/ packages/glmnet/index.html Hadley Wickham Implementacja gramatyki grafiki w R. Świetny pakiet do tworzenia grafik o wysokiej jakości. glmnet http://had.co.nz/ggplot2/ Jerome Friedman, Trevor Hastie i Rob Tibshirani Uogólnione modele liniowe Lasso i Elastic-net. igraph http://igraph.sourceforge.net/ Gabor Csardi Procedury do prostej wizualizacji i analizy sieciowej, stosowane do reprezentowania sieci społecznościowych. lme4 http://cran.r-project.org/web/ packages/lme4/ Douglas Bates, Martin Maechler i Ben Bolker Zestaw funkcji do tworzenia modeli liniowych i mieszanych. lubridate https://github.com/hadley/lubridate Hadley Wickham Funkcje pomocnicze do obsługi dat w języku R. RCurl http://www.omegahat.org/RCurl/ Duncan Temple Lang Interfejs R do biblioteki libcurl, obsługującej protokół HTTP; stosuje się ją do importowania danych źródłowych z sieci WWW. reshape http://had.co.nz/plyr/ Hadley Wickham Zestaw narzędzi do manipulowania danymi w R, agregowania ich i zarządzania nimi. RJSONIO http://www.omegahat.org/RJSONIO/ Duncan Temple Lang Funkcje do wczytywania i wypisywania danych w notacji JavaScript Object Notation (JSON), stosowane do ładowania danych z interfejsów programistycznych aplikacji WWW. tm http://www.spatstat.org/spatstat/ Ingo Feinerer Funkcje do analizy tekstu w języku R, stosowane do pracy z danymi tekstowymi pozbawionymi ścisłej struktury. XML http://www.omegahat.org/RSXML/ Duncan Temple Lang Mechanizmy do parsowania dokumentów XML i HTML, stosowane do wyodrębniania danych z dokumentów publikowanych w sieci WWW. Zostaniemy poproszeni o wybranie lokalizacji serwerów lustrzanych repozytorium CRAN, jeśli wcześniej tego nie zrobiliśmy. Gdy ją wskażemy, skrypt instalacyjny rozpocznie instala- cję pakietów. Jej przebieg będzie sygnalizowany serią komunikatów o postępie instalacji nie- obecnych jeszcze pakietów. Potem będzie można już zacząć wstęp do uczenia maszynowego z R! Ale zanim przejdziemy do właściwych studiów przypadków, przyjrzymy się wybranym funkcjom i operacjom języka R, które później będą w częstym użyciu.

Język R w uczeniu maszynowym  23 Podstawy R w uczeniu maszynowym Powiedziano już, że naszym zdaniem najlepszym sposobem nabycia nowej umiejętności tech- nicznej jest rozpoczęcie od choćby niewielkiego, ale faktycznego problemu oczekującego na roz- wiązanie albo od znalezienia odpowiedzi na jakieś pytanie. Wykorzystywanie zyskiwanego doświadczenia w budowaniu ogólniejszej wizji sposobu rozwiązywania problemów jest bardzo skuteczną formą dydaktyki. W niniejszym wstępie do języka R nie będziemy jeszcze przy- mierzać się do problemów uczenia maszynowego, ale rozpatrzmy kilka zagadnień typowych dla pracy z danymi. Później, przy analizach studiów przypadków, większość czasu często będzie nam zajmować właśnie uzdatnienie posiadanych danych do właściwej analizy. Sama analiza zajmuje zazwyczaj już znacznie mniej wysiłku programistycznego. W ramach rozgrzewki zajmiemy się zagadnieniem z aspektem, można rzec, rozrywkowym. Ostatnio serwis Infochimps.com udostępnił zbiór danych z ponad 60 000 dokumentów (raportów) o obserwacjach niezidentyfikowanych obiektów latających (UFO). Dane obejmują setki lat i pochodzą z całego świata. Większość z nich pochodzi z terytorium Stanów Zjednoczonych (choć sam raport nie był ograniczony terytorialnie). Mając określony czasowy i przestrzenny wymiar danych, możemy zadać pytanie o sezonowość trendów obserwacji zjawiska UFO i jakie są wariacje (jeśli występują) pomiędzy obserwacjami zgłaszanymi w różnych częściach Stanów Zjednoczonych. To świetny zbiór danych na początek przygody analitycznej, ponieważ jest bogaty, posiada nieźle uporządkowaną strukturę, a same dane bywają zabawne. Do tego ma postać dużego pli- ku tekstowego, co jest istotne, ponieważ taka forma danych będzie później dominująca w stu- diach przypadków. W plikach tekstowych występują często miejsca odstające od struktury, więc będziemy mogli użyć podstawowych funkcji R i pakietów dodatkowych do oczyszczenia i usystematyzowania surowych danych. Przy okazji krok po kroku przeprowadzimy całą (prostą) analizę w ramach próby odpowiedzi na postawione pytania. Kod ćwiczenia znajduje się w folde- rze materiałów do tego rozdziału książki, w pliku ufo_sightings.R. Zaczniemy od załadowania danych i bibliotek wymaganych do przeprowadzenia analizy. Ładowanie bibliotek i danych Na początek załadujemy pakiet ggplot2, którego użyjemy potem w ostatnich krokach analizy wizualnej: library(ggplot2) Przy ładowaniu pakietu ggplot2 zauważymy, że przy okazji załadowane zostaną dwa inne pa- kiety wymagane: plyr i reshape. Oba są stosowane do manipulowania danymi w R. W przykładzie użyjemy wprost funkcji pakietu plyr do zagregowania i uporządkowania danych źródłowych. Kolejny etap to wczytanie do R danych z pliku tekstowego ufo_awesome.tsv, umieszczonego w podkatalogu data/ufo/ wśród materiałów do tego rozdziału. Zauważmy, że plik zawiera dane rozdzielane znakami tabulacji (stąd rozszerzenie .tsv — od ang. tab separated values). Oznacza to, że przy ich wczytywaniu powinniśmy określić symbol separatora wartości za pomocą funkcji read.delim. Ponieważ w R w powszechnym użyciu są wartości domyślne, trzeba szczególnie uważać na ustawienia domyślne parametrów wywoływanych funkcji. Aby przy okazji rozpoznać zagadnienie parametrów w R, załóżmy, że nigdy nie stosowaliśmy jeszcze funkcji read.delim i chcemy skorzystać z plików pomocy. Możemy nawet założyć, że nie wiemy wręcz o istnieniu

24  Rozdział 1. Język R takiej funkcji i szukamy funkcji do wczytywania serii wartości do ramki danych R. Szukanie informacji w systemie pomocy R może odbywać się na kilka sposobów: ?read.delim # wywołanie pliku pomocy funkcji read.delim ??base::delim # wyszukanie łańcucha 'delim' we wszystkich # plikach pomocy funkcji wbudowanych help.search("delimited") # wyszukanie łańcucha 'delimited' we wszystkich # dostępnych plikach pomocy RSiteSearch("parsing text") # wyszukanie terminu 'parsing text' na stronie # projektu R W pierwszym przykładzie poprzedzamy nazwę funkcji znakiem zapytania. Spowoduje to otwarcie pliku pomocy dla danej funkcji. To bardzo przydatny skrót R. Wykorzystując kombi- nację symboli ?? i ::, możemy wyszukać konkretne frazy w zawartości pakietów. W tym przy- kładzie szukamy wystąpień słowa „delim” we wszystkich funkcjach bazowych (wbudo- wanych). R pozwala też na przeprowadzanie mniej dookreślonych poszukiwań z użyciem funkcji help.search i RSiteSearch. Ta pierwsza szuka przekazanego ciągu znaków w plikach pomocy z zainstalowanych w środowisku pakietów (tu szukamy dokumentacji zawierającej słowo „delimited”); druga szuka podanego słowa na stronie WWW projektu R, a więc nie tylko w plikach pomocy, ale także w archiwum list dystrybucyjnych poczty elektronicznej. Należy pamiętać, że nie zamierzamy tu wyczerpująco przedstawiać R i jego funkcji, za to szczerze pole- camy korzystanie z mechanizmu pomocy i samodzielne poznawanie dostępnych w R funkcji bazowych i ich możliwości. Poprawne wczytanie danych o UFO wymaga ustawienia kilku parametrów funkcji read.delim. Przede wszystkim należy jej podać sposób oddzielania wartości danych. Wiemy, że w pliku dane są oddzielane znakami tabulacji, więc parametr sep ustawiamy na znak tabulacji. Kiedy funkcja read.delim wczytuje dane, próbuje na podstawie zestawu heurystyk zamienić wczyty- wane wartości na dane typu właściwego dla języka R. W naszym przypadku wszystkie ko- lumny zawierają dane tekstowe, a domyślnie wszystkie funkcje read.* próbują konwertować łańcuchy znaków na wartości typu factor, przeznaczonego do reprezentowania zmiennych „skategoryzowanych”, których tu nie potrzebujemy. Skoro tak, ustawiamy parametr stringsAs- Factors=FALSE blokujący niechcianą konwersję. Akurat tę wartość domyślną najczęściej warto wyłączyć, zwłaszcza przy wczytywaniu nierozpoznanych jeszcze danych. Nasze dane nie za- wierają nagłówka, więc wyłączamy również rozpoznawanie struktury na podstawie pierwsze- go wiersza danych. Wreszcie dla pustych wartości (a takich w pliku jest mnóstwo) określamy specjalną wartość NA. W tym celu jawnie definiujemy odwzorowanie pustych łańcuchów znaków na na.string: ufo<-read.delim("data/ufo/ufo_awesome.tsv", sep="\t", stringsAsFactors=FALSE, header=FALSE, na.strings="") Pojęcie „zmiennych skategoryzowanych” odnosi się do typu danych, które zaliczają obserwacje do znanych kategorii. W statystyce zmienne skategoryzowane są bardzo ważne, ponieważ możemy dowiadywać się, co sprawia, że określona obserwacja jest danego typu. W R zmienne kategoryczne reprezentujemy wartościami typu factor, który wewnętrznie odwzorowuje etykiety tekstowe na odniesienia liczbowe. W tym przypadku niektóre z łańcuchów znakowych (dane o miejscu obserwacji) skonwertu- jemy za pomocą wywołania as.factor na zmienne skategoryzowane, kojarzące skróty nazw poszczególnych stanów z identyfikatorami liczbowymi. Proces ten będziemy wykonywać jeszcze wielokrotnie.

Język R w uczeniu maszynowym  25 Mamy już ramkę danych zawierającą komplet danych o obserwacjach UFO! Przy pracy z ram- kami danych, zwłaszcza jeśli ich źródłem są dane zewnętrzne, należy zawsze, nawet ręcznie zweryfikować import. Świetnie sprawdza się tu para funkcji head i tail, które wypisują (od- powiednio) pierwsze i ostatnie sześć pozycji danych w ramce danych: head(ufo) V1 V2 V3 V4 V5 V6 1 19951009 19951009 Iowa City, IA Man repts. witnessing "flash.. 2 19951010 19951011 Milwaukee, WI 2 min. Man on Hwy 43 SW of Milwauk.. 3 19950101 19950103 Shelton, WA Telephoned Report:CA woman v.. 4 19950510 19950510 Columbia, MO 2 min. Man repts. son's bizarre sig.. 5 19950611 19950614 Seattle, WA Anonymous caller repts. sigh.. 6 19951025 19951024 Brunswick County, ND 30 min. Sheriff's office calls to re.. Od razu widać pierwszą niedogodność: etykiety kolumn zostały dobrane automatycznie. Analizując dokumentację dla tego zbioru danych, możemy ustawić bardziej opisowe etykiety kolumn. Znaczące nazwy kolumn w ramkach danych to jedno z istotnych zaleceń dla pro- gramistów R — dzięki nim kod i wyniki analiz są czytelniejsze zarówno dla samego programi- sty, jak i ewentualnych odbiorców wyników. Możemy zatem użyć funkcji names, która potrafi zarówno odczytywać nazwy kolumn, jak i je ustawiać. Tak więc na podstawie dokumentacji utworzymy wektor znaków odpowiadający nazwie kolumny i przekażemy tak utworzoną etykietę do funkcji names: names(ufo)<-c("DateOccurred","DateReported","Location", "ShortDescription","Duration","LongDescription") Z polecenia head, a także z dokumentacji danych źródłowych wiemy, że pierwsze dwie ko- lumny danych są datami. Podobnie jak w innych językach programowania, dla dat w R wy- dzielono specjalny typ danych. Warto więc skonwertować daty z ciągów znaków na wartości odpowiedniego typu. Wykorzystamy do tego funkcję as.Date, która przyjmuje datę zapisaną w ciągu znaków i zwraca odpowiednio zainicjalizowany obiekt typu Date. W naszych danych źródłowych format zapisu daty jest cokolwiek nietypowy: „RRRRMMDD”. Niestandardowy format wymaga przekazania do funkcji konwertującej ciągu opisującego format wejściowy. Zaczniemy od skonwertowania wartości w kolumnie DateOccurred: ufo$DateOccurred<-as.Date(ufo$DateOccurred, format="%Y%m%d") Error in strptime(x, format, tz = "GMT") : input string is too long No proszę, doczekaliśmy się pierwszego komunikatu o błędzie! Co prawda jest nieco lakoniczny, ale zawiera przynajmniej ciąg „input string too long”, oznaczający, że niektóre z wartości w ko- lumnie DateOccurred były ciągami wykraczającymi poza podany format wejściowy. Co może być tego przyczyną? Cóż, operujemy na sporym pliku tekstowym, więc może źródłowy zbiór danych zawiera jakieś nieprawidłowości struktury albo nieoczekiwane znaki. Jeśli tak jest, wartości te nie będą poprawnie sparsowane przez funkcję wczytującą read.delim. Praca na danych niesyntetycznych często wiąże się z koniecznością ręcznego oczyszczania danych źródłowych. Konwertowanie ciągów dat i obsługa źle sformatowanych danych Na początek powinniśmy zlokalizować w danych wejściowych problematyczne wiersze, a po- tem zdecydować o sposobie ich obsługi. W tym przypadku mamy wskazówkę, że niektóre z re- kordów danych wejściowych są „za długie”. Prawidłowo zapisane ciągi dat będą zawsze miały osiem znaków (zgodnie z formatem „RRRRMMDD”). Aby odszukać problematyczny wiersz, musimy po prostu znaleźć w kolumnie wartości o długości większej niż osiem znaków. Zgodnie

26  Rozdział 1. Język R z uznaną praktyką najpierw oceniamy charakter nieprawidłowości w danych źródłowych — dzięki temu będziemy wiedzieli, jaki jest charakter nieprawidłowości. W naszym przypadku posłużymy się znów funkcją head do wypisania danych zwracanych przez wyrażenie logiczne filtrujące nieprawidłowości. Później, aby problematyczne wiersze usunąć, użyjemy funkcji ifelse konstruującej wektor wartości TRUE i FALSE, identyfikujących wpisy danych źródłowych z datami o długości ośmiu znaków (TRUE) i o innej długości (FALSE). Jest to wektorowa wersja typowej instrukcji warunkowej if-else operującej na wyrażeniu logicznym. Podobnych przykładów wektoryzacji operacji w ję- zyku R zobaczymy jeszcze sporo. Wektoryzacja jest tu preferowana przed iterowaniem po zbio- rach danych, bo jawne iterowanie po zbiorach okazuje się często mniej efektywne1 : head(ufo[which(nchar(ufo$DateOccurred)!=8 | nchar(ufo$DateReported)!=8),1]) [1] "ler@gnv.ifas.ufl.edu" [2] "0000" [3] "Callers report sighting a number of soft white balls of lights headingin an easterly directing then changing direction to the west beforespeeding off to the north west." [4] "0000" [5] "0000" [6] "0000" good.rows<-ifelse( nchar(ufo$DateOccurred)>!=8 | nchar(ufo$DateReported)!=8,FALSE,TRUE) length(which(!good.rows)) [1] 371 ufo<-ufo[good.rows,] Filtrowanie poprawnych danych odbywa się tu przy użyciu kilku przydatnych funkcji R. Do określania długości zapisu wartości w kolumnach DateOccurred i DateReported używamy funkcji nchar. Jeśli zwrócony rozmiar jest inny niż osiem, zwracamy FALSE. Po zbudowaniu w ten sposób wektora wartości logicznych chcemy sprawdzić, ile wpisów ramki danych zawiera nieprawidło- we wartości kolumn dat. W tym celu używamy funkcji which, zwracającej wektor indeksów wektora wartości logicznych równych FALSE. Obliczany potem rozmiar tego wektora jest równy liczbie niepoprawnych wpisów w danych źródłowych. Skoro nieprawidłowości dotyczą zaledwie 371 wpisów, najlepiej je zignorować i usunąć ze zbioru źródłowego. Zdawałoby się, że utrata aż 371 elementów danych jest istotna, ale wszystkich wierszy danych jest ponad 60 000, więc po pominięciu nieprawidłowości kontynuujemy konwersję z wykorzystaniem funkcji as.Date: ufo$DateOccurred<-as.Date(ufo$DateOccurred, format="%Y%m%d") ufo$DateReported<-as.Date(ufo$DateReported, format="%Y%m%d") Przejdziemy teraz do uporządkowania i ustrukturyzowania danych o miejscu obserwacji. Z po- przedniego wywołania funkcji head pamiętamy, że obserwacje z terenu Stanów Zjednoczonych są oznaczane lokalizacją „miasto, kod stanu”. Za pomocą mechanizmów wyrażeń regularnych wbudowanych w R możemy podzielić te pary na osobne kolumny i przy okazji odsiać wpisy, które nie pasują do schematu oznaczania lokalizacji. Ta druga część, czyli odszukanie i wyelimi- nowanie zgłoszeń niepasujących do formatu, jest ważna, ponieważ jako wynik ćwiczenia in- teresuje nas wariacja obserwacji UFO na terenie Stanów Zjednoczonych, więc przy okazji zawę- zimy zbiór danych do właściwego zakresu lokalizacji. 1 Wprowadzenie do operacji wektorowych w języku R można znaleźć w dokumencie R help desk [LF08] pod hasłem How can I avoid this loop or makeit faster?