Analiza dużych zbiorów danych - krótki przewodnik
Ilość danych, z którymi trzeba się zmierzyć, eksplodowała w ostatniej dekadzie do niewyobrażalnych poziomów, a jednocześnie cena ich przechowywania systematycznie spada. Prywatne firmy i instytucje badawcze przechwytują terabajty danych o interakcjach ich użytkowników, biznesie, mediach społecznościowych, a także czujniki z takich urządzeń, jak telefony komórkowe i samochody. Wyzwaniem tej epoki jest zrozumienie tego morza danych. To jest gdziebig data analytics pojawia się obraz.
Big Data Analytics w dużej mierze polega na zbieraniu danych z różnych źródeł, gromadzeniu ich w taki sposób, aby były dostępne do wykorzystania przez analityków, a na końcu dostarczaniu produktów danych przydatnych w działalności organizacji.
Proces przekształcania dużych ilości nieustrukturyzowanych nieprzetworzonych danych, pobranych z różnych źródeł w produkt danych przydatny dla organizacji, stanowi rdzeń Big Data Analytics.
Cykl życia tradycyjnego wyszukiwania danych
Aby zapewnić ramy do organizowania pracy potrzebnej organizacji i dostarczania jasnych spostrzeżeń z Big Data, warto myśleć o tym jako o cyklu o różnych etapach. W żadnym wypadku nie jest liniowy, co oznacza, że wszystkie etapy są ze sobą powiązane. Ten cykl ma powierzchowne podobieństwa z bardziej tradycyjnym cyklem eksploracji danych, jak opisano wCRISP methodology.
Metodologia CRISP-DM
Plik CRISP-DM methodologyto skrót od Cross Industry Standard Process for Data Mining, to cykl opisujący powszechnie stosowane podejścia, które eksperci od eksploracji danych stosują do rozwiązywania problemów w tradycyjnym eksploracji danych BI. Nadal jest używany w tradycyjnych zespołach eksploracji danych BI.
Spójrz na poniższą ilustrację. Pokazuje główne etapy cyklu opisane w metodologii CRISP-DM i ich wzajemne powiązania.
CRISP-DM powstał w 1996 roku, a rok później został uruchomiony jako projekt Unii Europejskiej w ramach inicjatywy finansowania ESPRIT. Projekt był prowadzony przez pięć firm: SPSS, Teradata, Daimler AG, NCR Corporation i OHRA (firma ubezpieczeniowa). Projekt został ostatecznie włączony do SPSS. Metodologia jest bardzo szczegółowa, jeśli chodzi o sposób określenia projektu eksploracji danych.
Nauczmy się teraz trochę więcej na każdym z etapów cyklu życia CRISP-DM -
Business Understanding- Ta początkowa faza koncentruje się na zrozumieniu celów projektu i wymagań z perspektywy biznesowej, a następnie przekształceniu tej wiedzy w definicję problemu eksploracji danych. Wstępny plan ma na celu osiągnięcie celów. Można zastosować model decyzyjny, zwłaszcza zbudowany przy użyciu modelu decyzyjnego i standardu notacji.
Data Understanding - Faza zrozumienia danych rozpoczyna się od wstępnego zebrania danych i przechodzi do działań mających na celu zapoznanie się z danymi, zidentyfikowanie problemów z jakością danych, odkrycie pierwszych spostrzeżeń w danych lub wykrycie interesujących podzbiorów w celu sformułowania hipotez dotyczących ukrytych informacji.
Data Preparation- Faza przygotowania danych obejmuje wszystkie działania mające na celu skonstruowanie ostatecznego zbioru danych (dane, które zostaną wprowadzone do narzędzia (narzędzi) do modelowania) z początkowych surowych danych. Zadania związane z przygotowaniem danych będą prawdopodobnie wykonywane wielokrotnie, a nie w określonej kolejności. Zadania obejmują wybór tabeli, rekordów i atrybutów, a także transformację i czyszczenie danych na potrzeby narzędzi do modelowania.
Modeling- Na tym etapie wybierane i stosowane są różne techniki modelowania, a ich parametry są kalibrowane do optymalnych wartości. Zwykle istnieje kilka technik dla tego samego typu problemu eksploracji danych. Niektóre techniki mają określone wymagania dotyczące formy danych. Dlatego często trzeba cofnąć się do fazy przygotowania danych.
Evaluation- Na tym etapie projektu zbudowałeś model (lub modele), który wydaje się być wysokiej jakości z punktu widzenia analizy danych. Przed przystąpieniem do ostatecznego wdrożenia modelu ważne jest, aby dokładnie ocenić model i przejrzeć kroki wykonane w celu zbudowania modelu, aby mieć pewność, że prawidłowo realizuje cele biznesowe.
Kluczowym celem jest ustalenie, czy istnieje jakaś ważna kwestia biznesowa, która nie została dostatecznie rozważona. Pod koniec tej fazy powinna zostać podjęta decyzja o wykorzystaniu wyników eksploracji danych.
Deployment- Tworzenie modelu to generalnie nie koniec projektu. Nawet jeśli celem modelu jest poszerzenie wiedzy o danych, zdobytą wiedzę trzeba będzie uporządkować i przedstawić w sposób przydatny dla klienta.
W zależności od wymagań faza wdrożeniowa może być tak prosta, jak wygenerowanie raportu lub złożona, jak wdrożenie powtarzalnej oceny danych (np. Alokacja segmentu) lub proces eksploracji danych.
W wielu przypadkach to klient, a nie analityk danych, będzie wykonywał etapy wdrożenia. Nawet jeśli analityk wdroży model, ważne jest, aby klient z góry zrozumiał działania, które będzie musiał wykonać, aby faktycznie skorzystać z utworzonych modeli.
Metodologia SEMMA
SEMMA to kolejna metodologia opracowana przez SAS do modelowania eksploracji danych. To znaczySobszerny, Explore, Modify, Model i Asses. Oto krótki opis jego etapów -
Sample- Proces rozpoczyna się od próbkowania danych, np. Wyboru zbioru danych do modelowania. Zbiór danych powinien być wystarczająco duży, aby zawierał wystarczającą ilość informacji do pobrania, ale wystarczająco mały, aby można go było efektywnie wykorzystać. Ta faza dotyczy również partycjonowania danych.
Explore - Faza ta obejmuje zrozumienie danych poprzez wykrycie przewidywanych i nieoczekiwanych relacji między zmiennymi, a także nieprawidłowości, za pomocą wizualizacji danych.
Modify - Faza modyfikacji obejmuje metody wybierania, tworzenia i transformowania zmiennych w ramach przygotowań do modelowania danych.
Model - W fazie Modelu nacisk kładziony jest na zastosowanie różnych technik modelowania (eksploracji danych) na przygotowanych zmiennych w celu stworzenia modeli, które mogą zapewnić pożądany wynik.
Assess - Ocena wyników modelowania wskazuje na rzetelność i użyteczność utworzonych modeli.
Główna różnica między CRISM-DM i SEMMA polega na tym, że SEMMA skupia się na aspekcie modelowania, podczas gdy CRISP-DM przywiązuje większą wagę do etapów cyklu poprzedzających modelowanie, takich jak zrozumienie problemu biznesowego do rozwiązania, zrozumienie i wstępne przetwarzanie danych, które mają być używane jako dane wejściowe, na przykład algorytmy uczenia maszynowego.
Cykl życia Big Data
W dzisiejszym kontekście dużych zbiorów danych poprzednie podejścia są albo niekompletne, albo nieoptymalne. Na przykład metodologia SEMMA całkowicie pomija gromadzenie i wstępne przetwarzanie danych z różnych źródeł. Te etapy zwykle stanowią większość pracy w udanym projekcie Big Data.
Cykl analizy danych big data można opisać następującym etapem -
- Definicja problemu biznesowego
- Research
- Ocena zasobów ludzkich
- Pozyskiwanie danych
- Bezpowrotnie zniszczenie lub zmiana danych
- Przechowywanie danych
- Analiza danych rozpoznawczych
- Przygotowanie danych do modelowania i oceny
- Modeling
- Implementation
W tej sekcji rzucimy trochę światła na każdy z tych etapów cyklu życia dużych zbiorów danych.
Definicja problemu biznesowego
Jest to punkt wspólny w tradycyjnym cyklu życia BI i analizy dużych zbiorów danych. Zwykle nietrywialnym etapem projektu big data jest zdefiniowanie problemu i poprawna ocena, jakie potencjalne korzyści może przynieść organizacji. Wspomnienie o tym wydaje się oczywiste, ale należy ocenić, jakie są spodziewane zyski i koszty projektu.
Badania
Przeanalizuj, co inne firmy zrobiły w tej samej sytuacji. Wiąże się to z poszukiwaniem rozwiązań rozsądnych dla Twojej firmy, nawet jeśli wiąże się to z dostosowaniem innych rozwiązań do jej zasobów i wymagań. Na tym etapie należy określić metodologię dla przyszłych etapów.
Ocena zasobów ludzkich
Po zdefiniowaniu problemu rozsądne jest kontynuowanie analizy, czy obecny personel jest w stanie pomyślnie zakończyć projekt. Tradycyjne zespoły BI mogą nie być w stanie zapewnić optymalnego rozwiązania na wszystkich etapach, dlatego przed rozpoczęciem projektu należy rozważyć, czy istnieje potrzeba outsourcingu części projektu lub zatrudnienia większej liczby osób.
Pozyskiwanie danych
Ta sekcja jest kluczowa w cyklu życia dużych zbiorów danych; określa, jaki rodzaj profili byłby potrzebny do dostarczenia wynikowego produktu danych. Gromadzenie danych jest nietrywialnym etapem procesu; zwykle obejmuje gromadzenie nieustrukturyzowanych danych z różnych źródeł. Na przykład może to obejmować napisanie robota indeksującego do pobierania recenzji z witryny internetowej. Obejmuje to zajmowanie się tekstem, być może w różnych językach, które zwykle wymaga dużo czasu na ukończenie.
Bezpowrotnie zniszczenie lub zmiana danych
Po pobraniu danych, na przykład z Internetu, należy je przechowywać w łatwym w użyciu formacie. Aby kontynuować przykłady recenzji, załóżmy, że dane są pobierane z różnych witryn, z których każda ma inny sposób wyświetlania danych.
Załóżmy, że jedno źródło danych podaje recenzje w postaci ocen w gwiazdkach, dlatego można to odczytać jako mapowanie dla zmiennej odpowiedzi y ∈ {1, 2, 3, 4, 5}. Inne źródło danych podaje recenzje za pomocą systemu dwóch strzałek, jednej do głosowania w górę, a drugiej do głosowania w dół. Oznaczałoby to zmienną odpowiedzi w postaciy ∈ {positive, negative}.
Aby połączyć oba źródła danych, należy podjąć decyzję, aby te dwie reprezentacje odpowiedzi były równoważne. Może to obejmować konwersję pierwszej reprezentacji odpowiedzi źródła danych do drugiej postaci, uznając jedną gwiazdę za ujemną, a pięć za pozytywną. Proces ten często wymaga dużej ilości czasu, aby uzyskać dobrą jakość.
Przechowywanie danych
Po przetworzeniu danych czasami trzeba je przechowywać w bazie danych. Technologie Big Data oferują wiele alternatyw w tym zakresie. Najpopularniejszą alternatywą jest użycie systemu plików Hadoop do przechowywania, który zapewnia użytkownikom ograniczoną wersję języka SQL, znaną jako język zapytań HIVE. Pozwala to na wykonanie większości zadań analitycznych w podobny sposób, jak w przypadku tradycyjnych hurtowni danych BI, z perspektywy użytkownika. Inne opcje przechowywania, które należy wziąć pod uwagę, to MongoDB, Redis i SPARK.
Ten etap cyklu związany jest ze znajomością zasobów ludzkich w zakresie ich umiejętności implementacji różnych architektur. Zmodyfikowane wersje tradycyjnych hurtowni danych są nadal używane w aplikacjach na dużą skalę. Na przykład teradata i IBM oferują bazy danych SQL, które mogą obsługiwać terabajty danych; Rozwiązania open source, takie jak postgreSQL i MySQL, są nadal używane w aplikacjach na dużą skalę.
Chociaż istnieją różnice w sposobie działania różnych magazynów w tle, po stronie klienta większość rozwiązań udostępnia interfejs API SQL. Dlatego dobra znajomość języka SQL jest nadal kluczową umiejętnością do analizy dużych zbiorów danych.
Ten etap a priori wydaje się być tematem najważniejszym, w praktyce nie jest to prawdą. Nie jest to nawet istotny etap. Możliwe jest zaimplementowanie rozwiązania big data, które działałoby na danych czasu rzeczywistego, więc w tym przypadku wystarczy zebrać dane, aby opracować model, a następnie wdrożyć go w czasie rzeczywistym. Nie byłoby więc potrzeby formalnego przechowywania danych w ogóle.
Analiza danych rozpoznawczych
Po wyczyszczeniu i zapisaniu danych w sposób umożliwiający uzyskanie z nich informacji, faza eksploracji danych jest obowiązkowa. Celem tego etapu jest zrozumienie danych, zwykle odbywa się to za pomocą technik statystycznych, a także wykreślanie danych. Jest to dobry etap do oceny, czy definicja problemu ma sens lub jest wykonalna.
Przygotowanie danych do modelowania i oceny
Ten etap obejmuje przekształcenie oczyszczonych danych pobranych wcześniej i wykorzystanie wstępnego przetwarzania statystycznego do imputacji brakujących wartości, wykrywania wartości odstających, normalizacji, ekstrakcji cech i wyboru cech.
Modelowanie
Na wcześniejszym etapie powinno powstać kilka zbiorów danych do szkolenia i testowania, na przykład model predykcyjny. Ten etap polega na wypróbowaniu różnych modeli i oczekiwaniu na rozwiązanie problemu biznesowego. W praktyce normalnie pożądane jest, aby model dawał pewien wgląd w biznes. Na koniec wybiera się najlepszy model lub kombinację modeli, oceniając jego wydajność na pominiętym zbiorze danych.
Realizacja
Na tym etapie opracowany produkt danych jest wdrażany w rurociągu danych firmy. Obejmuje to skonfigurowanie schematu walidacji podczas działania produktu danych w celu śledzenia jego wydajności. Na przykład, w przypadku wdrażania modelu predykcyjnego, etap ten obejmowałby zastosowanie modelu do nowych danych i po uzyskaniu odpowiedzi dokonanie oceny modelu.
Pod względem metodologicznym analiza dużych zbiorów danych znacznie różni się od tradycyjnego podejścia statystycznego do projektowania eksperymentów. Analiza zaczyna się od danych. Zwykle modelujemy dane w sposób wyjaśniający odpowiedź. Celem tego podejścia jest przewidywanie zachowania w odpowiedzi lub zrozumienie, w jaki sposób zmienne wejściowe odnoszą się do odpowiedzi. Zwykle w statystycznych projektach eksperymentalnych eksperyment jest opracowywany, a w rezultacie pobierane są dane. Pozwala to na generowanie danych w sposób, który może być wykorzystany przez model statystyczny, w którym obowiązują pewne założenia, takie jak niezależność, normalność i randomizacja.
W analizie dużych zbiorów danych przedstawiane są dane. Nie możemy zaprojektować eksperymentu, który spełniałby nasz ulubiony model statystyczny. W zastosowaniach analitycznych na dużą skalę, duża ilość pracy (zwykle 80% wysiłku) jest potrzebna tylko do wyczyszczenia danych, więc może być wykorzystana przez model uczenia maszynowego.
Nie mamy unikalnej metodologii do naśladowania w rzeczywistych zastosowaniach na dużą skalę. Zwykle po zdefiniowaniu problemu biznesowego potrzebny jest etap badań w celu zaprojektowania metodologii, która ma zostać zastosowana. Jednak istotne są ogólne wytyczne, o których należy wspomnieć i które mają zastosowanie do prawie wszystkich problemów.
Jednym z najważniejszych zadań w analizie dużych zbiorów danych jest statistical modeling, czyli nadzorowane i nienadzorowane problemy klasyfikacyjne lub regresyjne. Po wyczyszczeniu i wstępnym przetworzeniu danych, dostępnych do modelowania, należy dołożyć starań, aby ocenić różne modele z rozsądnymi miernikami strat, a następnie, po wdrożeniu modelu, należy przedstawić dalszą ocenę i wyniki. Częstą pułapką w modelowaniu predykcyjnym jest po prostu wdrożenie modelu i nigdy nie mierzenie jego wydajności.
Jak wspomniano w cyklu życia dużych zbiorów danych, produkty danych, które wynikają z opracowania produktu Big Data, to w większości przypadków niektóre z następujących:
Machine learning implementation - Może to być algorytm klasyfikacyjny, model regresji lub model segmentacji.
Recommender system - Celem jest opracowanie systemu, który rekomenduje wybory w oparciu o zachowanie użytkownika. Netflix jest charakterystycznym przykładem tego produktu danych, w którym na podstawie ocen użytkowników zalecane są inne filmy.
Dashboard- Biznes zwykle potrzebuje narzędzi do wizualizacji zagregowanych danych. Pulpit nawigacyjny to graficzny mechanizm udostępniania tych danych.
Ad-Hoc analysis - Zwykle obszary biznesowe mają pytania, hipotezy lub mity, na które można odpowiedzieć, wykonując analizę danych ad hoc.
W dużych organizacjach, aby z powodzeniem opracować projekt Big Data, konieczne jest, aby kierownictwo wykonało kopię zapasową projektu. Zwykle wymaga to znalezienia sposobu na pokazanie zalet biznesowych projektu. Nie mamy unikalnego rozwiązania problemu ze znalezieniem sponsorów dla projektu, ale poniżej kilka wskazówek -
Sprawdź, kim i gdzie są sponsorzy innych projektów podobnych do tego, który Cię interesuje.
Posiadanie osobistych kontaktów na kluczowych stanowiskach kierowniczych pomaga, więc każdy kontakt może zostać zainicjowany, jeśli projekt jest obiecujący.
Kto skorzystałby na Twoim projekcie? Kto byłby Twoim klientem, gdy projekt będzie już realizowany?
Opracuj prostą, przejrzystą i ekscytującą propozycję i udostępnij ją kluczowym graczom w Twojej organizacji.
Najlepszym sposobem na znalezienie sponsorów projektu jest zrozumienie problemu i tego, jaki będzie wynikowy produkt danych po jego wdrożeniu. Zrozumienie to da przewagę w przekonywaniu kadry zarządzającej o znaczeniu projektu big data.
Analityk danych ma profil zorientowany na raportowanie, ma doświadczenie w wyodrębnianiu i analizowaniu danych z tradycyjnych hurtowni danych za pomocą SQL. Ich zadania zwykle dotyczą przechowywania danych lub raportowania ogólnych wyników biznesowych. Hurtownia danych nie jest bynajmniej prosta, różni się po prostu od tego, co robi naukowiec.
Wiele organizacji ma trudności ze znalezieniem na rynku kompetentnych analityków danych. Dobrym pomysłem jest jednak wybranie potencjalnych analityków danych i nauczenie ich odpowiednich umiejętności, aby zostać naukowcem danych. Nie jest to bynajmniej trywialne zadanie i normalnie wymagałoby to osoby, która zdobyłaby tytuł magistra w dziedzinie ilościowej, ale jest to zdecydowanie realna opcja. Poniżej wymieniono podstawowe umiejętności, które musi posiadać kompetentny analityk danych -
- Zrozumienie biznesu
- Programowanie w języku SQL
- Projektowanie i wdrażanie raportów
- Rozwój dashboardu
Rola analityka danych jest zwykle związana z zadaniami takimi jak modelowanie predykcyjne, opracowywanie algorytmów segmentacji, systemy rekomendujące, ramy testów A / B i często praca z nieprzetworzonymi danymi nieustrukturyzowanymi.
Charakter ich pracy wymaga głębokiego zrozumienia matematyki, statystyki stosowanej i programowania. Istnieje kilka umiejętności wspólnych między analitykiem danych a naukowcem zajmującym się danymi, na przykład umiejętność przeszukiwania baz danych. Obaj analizują dane, ale decyzja naukowca danych może mieć większy wpływ na organizację.
Oto zestaw umiejętności, które analityk danych normalnie musi posiadać -
- Programowanie w pakiecie statystycznym takim jak: R, Python, SAS, SPSS czy Julia
- Potrafi czyścić, wyodrębniać i eksplorować dane z różnych źródeł
- Badania, projektowanie i wdrażanie modeli statystycznych
- Głęboka wiedza statystyczna, matematyczna i informatyczna
W analizie dużych zbiorów danych ludzie zwykle mylą rolę naukowca zajmującego się danymi z rolą architekta danych. W rzeczywistości różnica jest dość prosta. Architekt danych określa narzędzia i architekturę, w której dane będą przechowywane, podczas gdy naukowiec danych używa tej architektury. Oczywiście analityk danych powinien mieć możliwość konfigurowania nowych narzędzi w razie potrzeby do projektów ad-hoc, ale definiowanie i projektowanie infrastruktury nie powinno być częścią jego zadań.
W tym samouczku opracujemy projekt. Każdy kolejny rozdział tego samouczka dotyczy części większego projektu w sekcji mini-projekt. Uważa się, że jest to zastosowana sekcja samouczka, która zapewni ekspozycję na rzeczywisty problem. W tym przypadku zaczęlibyśmy od zdefiniowania problemu projektu.
Opis Projektu
Celem tego projektu byłoby opracowanie modelu uczenia maszynowego do przewidywania godzinowej pensji osób korzystających z tekstu z życiorysu (CV) jako danych wejściowych.
Korzystając z ram zdefiniowanych powyżej, można łatwo zdefiniować problem. Możemy zdefiniować X = {x 1 , x 2 ,…, x n } jako CV użytkowników, gdzie każda cecha może być w najprostszy możliwy sposób, ile razy pojawia się to słowo. Wtedy reakcja jest realnie wyceniona, staramy się przewidzieć godzinowe wynagrodzenie osób w dolarach.
Te dwa rozważania wystarczą, aby stwierdzić, że przedstawiony problem można rozwiązać za pomocą nadzorowanego algorytmu regresji.
Definicja problemu
Problem Definitionjest prawdopodobnie jednym z najbardziej złożonych i mocno zaniedbanych etapów w potoku analizy dużych zbiorów danych. Aby zdefiniować problem, który rozwiązałby produkt danych, wymagane jest doświadczenie. Większość aspirantów do nauki danych ma niewielkie lub żadne doświadczenie na tym etapie.
Większość problemów związanych z dużymi zbiorami danych można podzielić na następujące kategorie:
- Nadzorowana klasyfikacja
- Nadzorowana regresja
- Uczenie się bez nadzoru
- Nauka rangi
Dowiedzmy się teraz więcej o tych czterech koncepcjach.
Nadzorowana klasyfikacja
Mając macierz cech X = {x 1 , x 2 , ..., x n } opracowujemy model M do przewidywania różnych klas zdefiniowanych jako y = {c 1 , c 2 , ..., c n } . Na przykład: Biorąc pod uwagę dane transakcyjne klientów w firmie ubezpieczeniowej, można opracować model, który będzie przewidywał, czy klient odejdzie, czy nie. Ten ostatni jest problemem klasyfikacji binarnej, w którym istnieją dwie klasy lub zmienne docelowe: odejście i brak odejścia.
Inne problemy obejmują przewidywanie więcej niż jednej klasy, moglibyśmy być zainteresowani rozpoznaniem cyfr, dlatego wektor odpowiedzi byłby zdefiniowany jako: y = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} najnowocześniejszym modelem byłaby konwolucyjna sieć neuronowa, a macierz cech byłaby zdefiniowana jako piksele obrazu.
Nadzorowana regresja
W tym przypadku definicja problemu jest raczej podobna do poprzedniego przykładu; różnica zależy od odpowiedzi. W przypadku problemu regresji odpowiedź y ∈ ℜ oznacza, że odpowiedź ma wartość rzeczywistą. Na przykład, możemy opracować model przewidujący wynagrodzenie godzinowe osób, które mają zbiór ich CV.
Uczenie się bez nadzoru
Kierownictwo jest często spragnione nowych spostrzeżeń. Modele segmentacji mogą zapewnić ten wgląd, aby dział marketingu mógł opracowywać produkty dla różnych segmentów. Dobrym podejściem do opracowania modelu segmentacji, zamiast myślenia o algorytmach, jest wybranie cech, które są istotne dla pożądanej segmentacji.
Na przykład w firmie telekomunikacyjnej interesujące jest segmentowanie klientów według korzystania z telefonów komórkowych. Wymagałoby to pominięcia cech, które nie mają nic wspólnego z celem segmentacji i uwzględnienia tylko tych, które to robią. W tym przypadku byłby to wybór funkcji, takich jak liczba wykorzystanych wiadomości SMS w miesiącu, liczba minut przychodzących i wychodzących itp.
Nauka rangi
Problem ten można uznać za problem regresji, ale ma on szczególne cechy i zasługuje na osobne potraktowanie. Problem polega na tym, że dany zbiór dokumentów staramy się znaleźć najbardziej trafne zamówienie na dane zapytanie. Aby opracować algorytm uczenia nadzorowanego, konieczne jest określenie, jak istotne jest uporządkowanie, na podstawie zapytania.
Należy zauważyć, że aby opracować algorytm uczenia nadzorowanego, konieczne jest oznaczenie danych uczących. Oznacza to, że aby wytrenować model, który będzie na przykład rozpoznawał cyfry z obrazu, musimy ręcznie opisać znaczną liczbę przykładów. Istnieją usługi internetowe, które mogą przyspieszyć ten proces i są powszechnie używane do tego zadania, takie jak amazon Mechanical Turk. Udowodniono, że algorytmy uczące się poprawiają swoją wydajność, gdy otrzymują więcej danych, więc etykietowanie przyzwoitej liczby przykładów jest praktycznie obowiązkowe w uczeniu nadzorowanym.
Gromadzenie danych odgrywa najważniejszą rolę w cyklu Big Data. Internet zapewnia prawie nieograniczone źródła danych na różne tematy. Znaczenie tego obszaru zależy od rodzaju prowadzonej działalności, ale tradycyjne branże mogą pozyskiwać różnorodne źródła danych zewnętrznych i łączyć je z danymi transakcyjnymi.
Na przykład załóżmy, że chcielibyśmy zbudować system polecający restauracje. Pierwszym krokiem byłoby zebranie danych, w tym przypadku recenzji restauracji z różnych stron internetowych i przechowywanie ich w bazie danych. Ponieważ interesuje nas surowy tekst i użyjemy go do analizy, nie jest tak istotne, gdzie byłyby przechowywane dane do opracowania modelu. Może się to wydawać sprzeczne z głównymi technologiami Big Data, ale aby zaimplementować aplikację Big Data, musimy po prostu sprawić, by działała w czasie rzeczywistym.
Mini projekt na Twitterze
Po zdefiniowaniu problemu kolejnym etapem jest zebranie danych. Następujący pomysł na miniprojekt polega na pracy nad zbieraniem danych z sieci i ustrukturyzowaniu ich do wykorzystania w modelu uczenia maszynowego. Zbierzemy kilka tweetów z API reszty twittera przy użyciu języka programowania R.
Przede wszystkim utwórz konto na Twitterze, a następnie postępuj zgodnie z instrukcjami w twitteRpakiet winiety, aby utworzyć konto programisty na Twitterze. To jest podsumowanie tych instrukcji -
Iść do https://twitter.com/apps/new i zaloguj się.
Po wypełnieniu podstawowych informacji przejdź do zakładki „Ustawienia” i wybierz „Czytaj, pisz i miej dostęp do bezpośrednich wiadomości”.
Po wykonaniu tej czynności kliknij przycisk Zapisz
Na karcie „Szczegóły” zanotuj swój klucz klienta i tajny klucz klienta
W sesji R będziesz używać klucza API i wartości tajnych interfejsu API
Na koniec uruchom następujący skrypt. Spowoduje to zainstalowanietwitteR pakiet z repozytorium na github.
install.packages(c("devtools", "rjson", "bit64", "httr"))
# Make sure to restart your R session at this point
library(devtools)
install_github("geoffjentry/twitteR")
Jesteśmy zainteresowani uzyskaniem danych, w których znajduje się ciąg „big mac”, i ustaleniem, które tematy się w tym wyróżniają. Aby to zrobić, pierwszym krokiem jest zebranie danych z Twittera. Poniżej znajduje się nasz skrypt R do zbierania wymaganych danych z Twittera. Ten kod jest również dostępny w pliku bda / part1 / collect_data / collect_data_twitter.R.
rm(list = ls(all = TRUE)); gc() # Clears the global environment
library(twitteR)
Sys.setlocale(category = "LC_ALL", locale = "C")
### Replace the xxx’s with the values you got from the previous instructions
# consumer_key = "xxxxxxxxxxxxxxxxxxxx"
# consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# access_token = "xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# access_token_secret= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Connect to twitter rest API
setup_twitter_oauth(consumer_key, consumer_secret, access_token, access_token_secret)
# Get tweets related to big mac
tweets <- searchTwitter(’big mac’, n = 200, lang = ’en’)
df <- twListToDF(tweets)
# Take a look at the data
head(df)
# Check which device is most used
sources <- sapply(tweets, function(x) x$getStatusSource())
sources <- gsub("</a>", "", sources)
sources <- strsplit(sources, ">")
sources <- sapply(sources, function(x) ifelse(length(x) > 1, x[2], x[1]))
source_table = table(sources)
source_table = source_table[source_table > 1]
freq = source_table[order(source_table, decreasing = T)]
as.data.frame(freq)
# Frequency
# Twitter for iPhone 71
# Twitter for Android 29
# Twitter Web Client 25
# recognia 20
Po zebraniu danych zwykle mamy różne źródła danych o różnych cechach. Najpilniejszym krokiem byłoby ujednolicenie tych źródeł danych i dalsze rozwijanie naszego produktu danych. Zależy to jednak od rodzaju danych. Powinniśmy zadać sobie pytanie, czy homogenizacja danych jest praktyczna.
Może źródła danych są zupełnie inne, a utrata informacji będzie duża, jeśli źródła zostaną ujednolicone. W takim przypadku możemy pomyśleć o alternatywach. Czy jedno źródło danych może pomóc mi zbudować model regresji, a drugie model klasyfikacyjny? Czy można pracować z niejednorodnością na naszą korzyść, zamiast po prostu tracić informacje? Podejmowanie tych decyzji sprawia, że analizy są interesujące i stanowią wyzwanie.
W przypadku recenzji można mieć język dla każdego źródła danych. Ponownie mamy dwie możliwości -
Homogenization- Polega na tłumaczeniu różnych języków na język, w którym mamy więcej danych. Jakość usług tłumaczeniowych jest akceptowalna, ale gdybyśmy chcieli tłumaczyć ogromne ilości danych za pomocą API, koszt byłby znaczny. Dostępne są narzędzia programowe do tego zadania, ale byłoby to również kosztowne.
Heterogenization- Czy byłoby możliwe opracowanie rozwiązania dla każdego języka? Ponieważ łatwo jest wykryć język korpusu, moglibyśmy opracować zalecenia dla każdego języka. Wymagałoby to więcej pracy w zakresie dostosowywania każdego polecającego w zależności od liczby dostępnych języków, ale jest to zdecydowanie opłacalna opcja, jeśli mamy dostępnych kilka języków.
Mini projekt na Twitterze
W tym przypadku musimy najpierw wyczyścić nieustrukturyzowane dane, a następnie przekształcić je w macierz danych, aby zastosować na niej tematy modelujące. Generalnie przy pobieraniu danych z Twittera jest kilka postaci, których nie jesteśmy zainteresowani, przynajmniej na pierwszym etapie procesu czyszczenia danych.
Na przykład po pobraniu tweetów otrzymujemy te dziwne znaki: „<ed> <U + 00A0> <U + 00BD> <ed> <U + 00B8> <U + 008B>”. Są to prawdopodobnie emotikony, więc aby wyczyścić dane, po prostu usuniemy je za pomocą poniższego skryptu. Ten kod jest również dostępny w pliku bda / part1 / collect_data / cleaning_data.R.
rm(list = ls(all = TRUE)); gc() # Clears the global environment
source('collect_data_twitter.R')
# Some tweets
head(df$text)
[1] "I’m not a big fan of turkey but baked Mac &
cheese <ed><U+00A0><U+00BD><ed><U+00B8><U+008B>"
[2] "@Jayoh30 Like no special sauce on a big mac. HOW"
### We are interested in the text - Let’s clean it!
# We first convert the encoding of the text from latin1 to ASCII
df$text <- sapply(df$text,function(row) iconv(row, "latin1", "ASCII", sub = ""))
# Create a function to clean tweets
clean.text <- function(tx) {
tx <- gsub("htt.{1,20}", " ", tx, ignore.case = TRUE)
tx = gsub("[^#[:^punct:]]|@|RT", " ", tx, perl = TRUE, ignore.case = TRUE)
tx = gsub("[[:digit:]]", " ", tx, ignore.case = TRUE)
tx = gsub(" {1,}", " ", tx, ignore.case = TRUE)
tx = gsub("^\\s+|\\s+$", " ", tx, ignore.case = TRUE) return(tx) } clean_tweets <- lapply(df$text, clean.text)
# Cleaned tweets
head(clean_tweets)
[1] " WeNeedFeminlsm MAC s new make up line features men woc and big girls "
[1] " TravelsPhoto What Happens To Your Body One Hour After A Big Mac "
Ostatnim krokiem mini projektu czyszczenia danych jest wyczyszczenie tekstu, który możemy przekształcić w macierz i zastosować algorytm. Z tekstu przechowywanego wclean_tweets wektor możemy łatwo przekształcić go w zbiór macierzy słów i zastosować algorytm uczenia się bez nadzoru.
Raportowanie jest bardzo ważne w analizie dużych zbiorów danych. Każda organizacja musi mieć regularne dostarczanie informacji wspierających proces podejmowania decyzji. To zadanie jest zwykle wykonywane przez analityków danych z doświadczeniem w SQL i ETL (wyodrębnianie, przesyłanie i ładowanie).
Zespół odpowiedzialny za to zadanie jest odpowiedzialny za rozpowszechnianie informacji wytworzonych w dziale analityki dużych zbiorów danych w różnych obszarach organizacji.
Poniższy przykład ilustruje, co oznacza podsumowanie danych. Przejdź do folderubda/part1/summarize_data aw folderze otwórz plik summarize_data.Rprojplik, klikając go dwukrotnie. Następnie otwórz pliksummarize_data.R script, przyjrzyj się kodowi i postępuj zgodnie z przedstawionymi wyjaśnieniami.
# Install the following packages by running the following code in R.
pkgs = c('data.table', 'ggplot2', 'nycflights13', 'reshape2')
install.packages(pkgs)
Plik ggplot2Pakiet świetnie nadaje się do wizualizacji danych. Plikdata.table pakiet jest świetną opcją do szybkiego i wydajnego podsumowania w R. Niedawny test porównawczy pokazuje, że jest jeszcze szybszy niżpandas, biblioteka Pythona używana do podobnych zadań.
Spójrz na dane za pomocą poniższego kodu. Ten kod jest również dostępny wbda/part1/summarize_data/summarize_data.Rproj plik.
library(nycflights13)
library(ggplot2)
library(data.table)
library(reshape2)
# Convert the flights data.frame to a data.table object and call it DT
DT <- as.data.table(flights)
# The data has 336776 rows and 16 columns
dim(DT)
# Take a look at the first rows
head(DT)
# year month day dep_time dep_delay arr_time arr_delay carrier
# 1: 2013 1 1 517 2 830 11 UA
# 2: 2013 1 1 533 4 850 20 UA
# 3: 2013 1 1 542 2 923 33 AA
# 4: 2013 1 1 544 -1 1004 -18 B6
# 5: 2013 1 1 554 -6 812 -25 DL
# 6: 2013 1 1 554 -4 740 12 UA
# tailnum flight origin dest air_time distance hour minute
# 1: N14228 1545 EWR IAH 227 1400 5 17
# 2: N24211 1714 LGA IAH 227 1416 5 33
# 3: N619AA 1141 JFK MIA 160 1089 5 42
# 4: N804JB 725 JFK BQN 183 1576 5 44
# 5: N668DN 461 LGA ATL 116 762 5 54
# 6: N39463 1696 EWR ORD 150 719 5 54
Poniższy kod zawiera przykład podsumowania danych.
### Data Summarization
# Compute the mean arrival delay
DT[, list(mean_arrival_delay = mean(arr_delay, na.rm = TRUE))]
# mean_arrival_delay
# 1: 6.895377
# Now, we compute the same value but for each carrier
mean1 = DT[, list(mean_arrival_delay = mean(arr_delay, na.rm = TRUE)),
by = carrier]
print(mean1)
# carrier mean_arrival_delay
# 1: UA 3.5580111
# 2: AA 0.3642909
# 3: B6 9.4579733
# 4: DL 1.6443409
# 5: EV 15.7964311
# 6: MQ 10.7747334
# 7: US 2.1295951
# 8: WN 9.6491199
# 9: VX 1.7644644
# 10: FL 20.1159055
# 11: AS -9.9308886
# 12: 9E 7.3796692
# 13: F9 21.9207048
# 14: HA -6.9152047
# 15: YV 15.5569853
# 16: OO 11.9310345
# Now let’s compute to means in the same line of code
mean2 = DT[, list(mean_departure_delay = mean(dep_delay, na.rm = TRUE),
mean_arrival_delay = mean(arr_delay, na.rm = TRUE)),
by = carrier]
print(mean2)
# carrier mean_departure_delay mean_arrival_delay
# 1: UA 12.106073 3.5580111
# 2: AA 8.586016 0.3642909
# 3: B6 13.022522 9.4579733
# 4: DL 9.264505 1.6443409
# 5: EV 19.955390 15.7964311
# 6: MQ 10.552041 10.7747334
# 7: US 3.782418 2.1295951
# 8: WN 17.711744 9.6491199
# 9: VX 12.869421 1.7644644
# 10: FL 18.726075 20.1159055
# 11: AS 5.804775 -9.9308886
# 12: 9E 16.725769 7.3796692
# 13: F9 20.215543 21.9207048
# 14: HA 4.900585 -6.9152047
# 15: YV 18.996330 15.5569853
# 16: OO 12.586207 11.9310345
### Create a new variable called gain
# this is the difference between arrival delay and departure delay
DT[, gain:= arr_delay - dep_delay]
# Compute the median gain per carrier
median_gain = DT[, median(gain, na.rm = TRUE), by = carrier]
print(median_gain)
Exploratory data analysisto koncepcja opracowana przez Johna Tuckeya (1977), która polega na nowej perspektywie statystyki. Pomysł Tuckey polegał na tym, że w tradycyjnych statystykach dane nie były analizowane graficznie, a były po prostu wykorzystywane do testowania hipotez. Pierwsza próba opracowania narzędzia miała miejsce w Stanford, projekt nazwano prim9 . Narzędzie było w stanie wizualizować dane w dziewięciu wymiarach, dzięki czemu było w stanie zapewnić wielowymiarową perspektywę danych.
W ostatnich dniach eksploracyjna analiza danych jest koniecznością i została uwzględniona w cyklu życia analityki dużych zbiorów danych. Zdolność do znajdowania wglądu i skutecznego przekazywania go w organizacji jest napędzana silnymi zdolnościami EDA.
Opierając się na pomysłach Tuckey, Bell Labs opracował S programming languagew celu zapewnienia interaktywnego interfejsu do tworzenia statystyk. Ideą S było zapewnienie szerokich możliwości graficznych z łatwym w użyciu językiem. W dzisiejszym świecie, w kontekście Big Data,R to jest oparte na S język programowania to najpopularniejsze oprogramowanie do analityki.
Poniższy program demonstruje użycie eksploracyjnej analizy danych.
Poniżej znajduje się przykład eksploracyjnej analizy danych. Ten kod jest również dostępny wpart1/eda/exploratory_data_analysis.R plik.
library(nycflights13)
library(ggplot2)
library(data.table)
library(reshape2)
# Using the code from the previous section
# This computes the mean arrival and departure delays by carrier.
DT <- as.data.table(flights)
mean2 = DT[, list(mean_departure_delay = mean(dep_delay, na.rm = TRUE),
mean_arrival_delay = mean(arr_delay, na.rm = TRUE)),
by = carrier]
# In order to plot data in R usign ggplot, it is normally needed to reshape the data
# We want to have the data in long format for plotting with ggplot
dt = melt(mean2, id.vars = ’carrier’)
# Take a look at the first rows
print(head(dt))
# Take a look at the help for ?geom_point and geom_line to find similar examples
# Here we take the carrier code as the x axis
# the value from the dt data.table goes in the y axis
# The variable column represents the color
p = ggplot(dt, aes(x = carrier, y = value, color = variable, group = variable)) +
geom_point() + # Plots points
geom_line() + # Plots lines
theme_bw() + # Uses a white background
labs(list(title = 'Mean arrival and departure delay by carrier',
x = 'Carrier', y = 'Mean delay'))
print(p)
# Save the plot to disk
ggsave('mean_delay_by_carrier.png', p,
width = 10.4, height = 5.07)
Kod powinien generować obraz taki jak następujący -
Aby zrozumieć dane, często warto je zwizualizować. Zwykle w aplikacjach Big Data zainteresowanie polega na znalezieniu wglądu, a nie tylko na tworzeniu pięknych wykresów. Poniżej przedstawiono przykłady różnych podejść do zrozumienia danych za pomocą wykresów.
Aby rozpocząć analizę danych dotyczących lotów, możemy zacząć od sprawdzenia, czy istnieją korelacje między zmiennymi numerycznymi. Ten kod jest również dostępny wbda/part1/data_visualization/data_visualization.R plik.
# Install the package corrplot by running
install.packages('corrplot')
# then load the library
library(corrplot)
# Load the following libraries
library(nycflights13)
library(ggplot2)
library(data.table)
library(reshape2)
# We will continue working with the flights data
DT <- as.data.table(flights)
head(DT) # take a look
# We select the numeric variables after inspecting the first rows.
numeric_variables = c('dep_time', 'dep_delay',
'arr_time', 'arr_delay', 'air_time', 'distance')
# Select numeric variables from the DT data.table
dt_num = DT[, numeric_variables, with = FALSE]
# Compute the correlation matrix of dt_num
cor_mat = cor(dt_num, use = "complete.obs")
print(cor_mat)
### Here is the correlation matrix
# dep_time dep_delay arr_time arr_delay air_time distance
# dep_time 1.00000000 0.25961272 0.66250900 0.23230573 -0.01461948 -0.01413373
# dep_delay 0.25961272 1.00000000 0.02942101 0.91480276 -0.02240508 -0.02168090
# arr_time 0.66250900 0.02942101 1.00000000 0.02448214 0.05429603 0.04718917
# arr_delay 0.23230573 0.91480276 0.02448214 1.00000000 -0.03529709 -0.06186776
# air_time -0.01461948 -0.02240508 0.05429603 -0.03529709 1.00000000 0.99064965
# distance -0.01413373 -0.02168090 0.04718917 -0.06186776 0.99064965 1.00000000
# We can display it visually to get a better understanding of the data
corrplot.mixed(cor_mat, lower = "circle", upper = "ellipse")
# save it to disk
png('corrplot.png')
print(corrplot.mixed(cor_mat, lower = "circle", upper = "ellipse"))
dev.off()
Ten kod generuje następującą wizualizację macierzy korelacji -
Na wykresie widać, że istnieje silna korelacja między niektórymi zmiennymi w zbiorze danych. Na przykład wydaje się, że opóźnienie przylotów i odlotów jest silnie skorelowane. Widzimy to, ponieważ elipsa pokazuje prawie liniową zależność między obiema zmiennymi, jednak nie jest łatwo znaleźć związek przyczynowy na podstawie tego wyniku.
Nie możemy powiedzieć, że skoro dwie zmienne są skorelowane, to jedna ma wpływ na drugą. Na wykresie znajdujemy również silną korelację między czasem antenowym a odległością, co jest dość rozsądne, ponieważ przy większej odległości czas lotu powinien się wydłużyć.
Możemy również przeprowadzić analizę danych na jednej zmiennej. Prostym i skutecznym sposobem wizualizacji dystrybucji sąbox-plots. Poniższy kod ilustruje sposób tworzenia wykresów pudełkowych i kratowych przy użyciu biblioteki ggplot2. Ten kod jest również dostępny wbda/part1/data_visualization/boxplots.R plik.
source('data_visualization.R')
### Analyzing Distributions using box-plots
# The following shows the distance as a function of the carrier
p = ggplot(DT, aes(x = carrier, y = distance, fill = carrier)) + # Define the carrier
in the x axis and distance in the y axis
geom_box-plot() + # Use the box-plot geom
theme_bw() + # Leave a white background - More in line with tufte's
principles than the default
guides(fill = FALSE) + # Remove legend
labs(list(title = 'Distance as a function of carrier', # Add labels
x = 'Carrier', y = 'Distance'))
p
# Save to disk
png(‘boxplot_carrier.png’)
print(p)
dev.off()
# Let's add now another variable, the month of each flight
# We will be using facet_wrap for this
p = ggplot(DT, aes(carrier, distance, fill = carrier)) +
geom_box-plot() +
theme_bw() +
guides(fill = FALSE) +
facet_wrap(~month) + # This creates the trellis plot with the by month variable
labs(list(title = 'Distance as a function of carrier by month',
x = 'Carrier', y = 'Distance'))
p
# The plot shows there aren't clear differences between distance in different months
# Save to disk
png('boxplot_carrier_by_month.png')
print(p)
dev.off()
Ta sekcja jest poświęcona wprowadzeniu użytkowników w język programowania R. R można pobrać ze strony internetowej Cran . Dla użytkowników Windows przydatne jest zainstalowanie rtools i rstudio IDE .
Ogólna koncepcja R ma służyć jako interfejs do innych programów opracowanych w językach kompilowanych, takich jak C, C ++ i Fortran, oraz zapewnić użytkownikowi interaktywne narzędzie do analizy danych.
Przejdź do folderu pliku zip książki bda/part2/R_introduction i otwórz R_introduction.Rprojplik. Otworzy się sesja RStudio. Następnie otwórz plik 01_vectors.R. Uruchom skrypt wiersz po wierszu i postępuj zgodnie z komentarzami w kodzie. Inną przydatną opcją do nauki jest po prostu wpisanie kodu, co pomoże ci przyzwyczaić się do składni języka R. W R komentarze są zapisane symbolem #.
W celu wyświetlenia wyników działania kodu R w książce, po ocenie kodu, wyniki zwracane przez R są komentowane. W ten sposób możesz skopiować, wkleić kod do książki i wypróbować bezpośrednio jego sekcje w R.
# Create a vector of numbers
numbers = c(1, 2, 3, 4, 5)
print(numbers)
# [1] 1 2 3 4 5
# Create a vector of letters
ltrs = c('a', 'b', 'c', 'd', 'e')
# [1] "a" "b" "c" "d" "e"
# Concatenate both
mixed_vec = c(numbers, ltrs)
print(mixed_vec)
# [1] "1" "2" "3" "4" "5" "a" "b" "c" "d" "e"
Przeanalizujmy, co się stało w poprzednim kodzie. Widzimy, że można tworzyć wektory z liczbami i literami. Nie musieliśmy wcześniej mówić R, jakiego typu danych potrzebowaliśmy. Wreszcie udało nam się stworzyć wektor zawierający zarówno cyfry, jak i litery. Wektor mixed_vec zmusił liczby do znaku, możemy to zobaczyć, wizualizując, jak wartości są drukowane w cudzysłowach.
Poniższy kod przedstawia typ danych różnych wektorów zwracanych przez klasę funkcji. Często używa się funkcji klasy do „przesłuchania” obiektu, pytając go, jaka jest jego klasa.
### Evaluate the data types using class
### One dimensional objects
# Integer vector
num = 1:10
class(num)
# [1] "integer"
# Numeric vector, it has a float, 10.5
num = c(1:10, 10.5)
class(num)
# [1] "numeric"
# Character vector
ltrs = letters[1:10]
class(ltrs)
# [1] "character"
# Factor vector
fac = as.factor(ltrs)
class(fac)
# [1] "factor"
R obsługuje również obiekty dwuwymiarowe. W poniższym kodzie znajdują się przykłady dwóch najpopularniejszych struktur danych używanych w R: macierz i data.frame.
# Matrix
M = matrix(1:12, ncol = 4)
# [,1] [,2] [,3] [,4]
# [1,] 1 4 7 10
# [2,] 2 5 8 11
# [3,] 3 6 9 12
lM = matrix(letters[1:12], ncol = 4)
# [,1] [,2] [,3] [,4]
# [1,] "a" "d" "g" "j"
# [2,] "b" "e" "h" "k"
# [3,] "c" "f" "i" "l"
# Coerces the numbers to character
# cbind concatenates two matrices (or vectors) in one matrix
cbind(M, lM)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] "1" "4" "7" "10" "a" "d" "g" "j"
# [2,] "2" "5" "8" "11" "b" "e" "h" "k"
# [3,] "3" "6" "9" "12" "c" "f" "i" "l"
class(M)
# [1] "matrix"
class(lM)
# [1] "matrix"
# data.frame
# One of the main objects of R, handles different data types in the same object.
# It is possible to have numeric, character and factor vectors in the same data.frame
df = data.frame(n = 1:5, l = letters[1:5])
df
# n l
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
# 5 5 e
Jak pokazano w poprzednim przykładzie, możliwe jest użycie różnych typów danych w tym samym obiekcie. Ogólnie rzecz biorąc, w ten sposób dane są prezentowane w bazach danych, API częścią danych jest tekst lub wektory znakowe i inne wartości liczbowe. Zadaniem analityka jest określenie, który typ danych statystycznych należy przypisać, a następnie użycie do tego odpowiedniego typu danych R. W statystykach zwykle uważamy, że zmienne są następujących typów -
- Numeric
- Nominalne lub kategorialne
- Ordinal
W R wektor może należeć do następujących klas -
- Liczbowo - liczba całkowita
- Factor
- Zamówiony współczynnik
R zapewnia typ danych dla każdego statystycznego typu zmiennej. Uporządkowany współczynnik jest jednak rzadko używany, ale może zostać utworzony przez współczynnik funkcji lub uporządkowany.
W poniższej sekcji omówiono pojęcie indeksowania. Jest to dość powszechna operacja i dotyczy problemu wybierania sekcji obiektu i dokonywania w nich transformacji.
# Let's create a data.frame
df = data.frame(numbers = 1:26, letters)
head(df)
# numbers letters
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
# 5 5 e
# 6 6 f
# str gives the structure of a data.frame, it’s a good summary to inspect an object
str(df)
# 'data.frame': 26 obs. of 2 variables:
# $ numbers: int 1 2 3 4 5 6 7 8 9 10 ... # $ letters: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ...
# The latter shows the letters character vector was coerced as a factor.
# This can be explained by the stringsAsFactors = TRUE argumnet in data.frame
# read ?data.frame for more information
class(df)
# [1] "data.frame"
### Indexing
# Get the first row
df[1, ]
# numbers letters
# 1 1 a
# Used for programming normally - returns the output as a list
df[1, , drop = TRUE]
# $numbers # [1] 1 # # $letters
# [1] a
# Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z
# Get several rows of the data.frame
df[5:7, ]
# numbers letters
# 5 5 e
# 6 6 f
# 7 7 g
### Add one column that mixes the numeric column with the factor column
df$mixed = paste(df$numbers, df$letters, sep = ’’) str(df) # 'data.frame': 26 obs. of 3 variables: # $ numbers: int 1 2 3 4 5 6 7 8 9 10 ...
# $ letters: Factor w/ 26 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ... # $ mixed : chr "1a" "2b" "3c" "4d" ...
### Get columns
# Get the first column
df[, 1]
# It returns a one dimensional vector with that column
# Get two columns
df2 = df[, 1:2]
head(df2)
# numbers letters
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
# 5 5 e
# 6 6 f
# Get the first and third columns
df3 = df[, c(1, 3)]
df3[1:3, ]
# numbers mixed
# 1 1 1a
# 2 2 2b
# 3 3 3c
### Index columns from their names
names(df)
# [1] "numbers" "letters" "mixed"
# This is the best practice in programming, as many times indeces change, but
variable names don’t
# We create a variable with the names we want to subset
keep_vars = c("numbers", "mixed")
df4 = df[, keep_vars]
head(df4)
# numbers mixed
# 1 1 1a
# 2 2 2b
# 3 3 3c
# 4 4 4d
# 5 5 5e
# 6 6 6f
### subset rows and columns
# Keep the first five rows
df5 = df[1:5, keep_vars]
df5
# numbers mixed
# 1 1 1a
# 2 2 2b
# 3 3 3c
# 4 4 4d
# 5 5 5e
# subset rows using a logical condition
df6 = df[df$numbers < 10, keep_vars]
df6
# numbers mixed
# 1 1 1a
# 2 2 2b
# 3 3 3c
# 4 4 4d
# 5 5 5e
# 6 6 6f
# 7 7 7g
# 8 8 8h
# 9 9 9i
SQL oznacza ustrukturyzowany język zapytań. Jest to jeden z najczęściej używanych języków do wyodrębniania danych z baz danych w tradycyjnych hurtowniach danych i technologiach big data. Aby zademonstrować podstawy SQL, będziemy pracować z przykładami. Aby skupić się na samym języku, będziemy używać SQL wewnątrz R. Jeśli chodzi o pisanie kodu SQL, jest to dokładnie tak, jak byłoby to zrobione w bazie danych.
Rdzeniem SQL są trzy instrukcje: SELECT, FROM i WHERE. Poniższe przykłady wykorzystują najczęstsze przypadki użycia języka SQL. Przejdź do folderubda/part2/SQL_introduction i otwórz SQL_introduction.Rprojplik. Następnie otwórz skrypt 01_select.R. Aby napisać kod SQL w R, musimy zainstalowaćsqldf pakiet, jak pokazano w poniższym kodzie.
# Install the sqldf package
install.packages('sqldf')
# load the library
library('sqldf')
library(nycflights13)
# We will be working with the fligths dataset in order to introduce SQL
# Let’s take a look at the table
str(flights)
# Classes 'tbl_d', 'tbl' and 'data.frame': 336776 obs. of 16 variables:
# $ year : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
# $ month : int 1 1 1 1 1 1 1 1 1 1 ... # $ day : int 1 1 1 1 1 1 1 1 1 1 ...
# $ dep_time : int 517 533 542 544 554 554 555 557 557 558 ... # $ dep_delay: num 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
# $ arr_time : int 830 850 923 1004 812 740 913 709 838 753 ... # $ arr_delay: num 11 20 33 -18 -25 12 19 -14 -8 8 ...
# $ carrier : chr "UA" "UA" "AA" "B6" ... # $ tailnum : chr "N14228" "N24211" "N619AA" "N804JB" ...
# $ flight : int 1545 1714 1141 725 461 1696 507 5708 79 301 ... # $ origin : chr "EWR" "LGA" "JFK" "JFK" ...
# $ dest : chr "IAH" "IAH" "MIA" "BQN" ... # $ air_time : num 227 227 160 183 116 150 158 53 140 138 ...
# $ distance : num 1400 1416 1089 1576 762 ... # $ hour : num 5 5 5 5 5 5 5 5 5 5 ...
# $ minute : num 17 33 42 44 54 54 55 57 57 58 ...
Instrukcja select służy do pobierania kolumn z tabel i wykonywania na nich obliczeń. Najprostszą instrukcję SELECT przedstawiono wej1. Możemy również tworzyć nowe zmienne, jak pokazano wej2.
### SELECT statement
ej1 = sqldf("
SELECT
dep_time
,dep_delay
,arr_time
,carrier
,tailnum
FROM
flights
")
head(ej1)
# dep_time dep_delay arr_time carrier tailnum
# 1 517 2 830 UA N14228
# 2 533 4 850 UA N24211
# 3 542 2 923 AA N619AA
# 4 544 -1 1004 B6 N804JB
# 5 554 -6 812 DL N668DN
# 6 554 -4 740 UA N39463
# In R we can use SQL with the sqldf function. It works exactly the same as in
a database
# The data.frame (in this case flights) represents the table we are querying
and goes in the FROM statement
# We can also compute new variables in the select statement using the syntax:
# old_variables as new_variable
ej2 = sqldf("
SELECT
arr_delay - dep_delay as gain,
carrier
FROM
flights
")
ej2[1:5, ]
# gain carrier
# 1 9 UA
# 2 16 UA
# 3 31 AA
# 4 -17 B6
# 5 -19 DL
Jedną z najczęściej używanych funkcji SQL jest grupowanie według instrukcji. Pozwala to obliczyć wartość liczbową dla różnych grup innej zmiennej. Otwórz skrypt 02_group_by.R.
### GROUP BY
# Computing the average
ej3 = sqldf("
SELECT
avg(arr_delay) as mean_arr_delay,
avg(dep_delay) as mean_dep_delay,
carrier
FROM
flights
GROUP BY
carrier
")
# mean_arr_delay mean_dep_delay carrier
# 1 7.3796692 16.725769 9E
# 2 0.3642909 8.586016 AA
# 3 -9.9308886 5.804775 AS
# 4 9.4579733 13.022522 B6
# 5 1.6443409 9.264505 DL
# 6 15.7964311 19.955390 EV
# 7 21.9207048 20.215543 F9
# 8 20.1159055 18.726075 FL
# 9 -6.9152047 4.900585 HA
# 10 10.7747334 10.552041 MQ
# 11 11.9310345 12.586207 OO
# 12 3.5580111 12.106073 UA
# 13 2.1295951 3.782418 US
# 14 1.7644644 12.869421 VX
# 15 9.6491199 17.711744 WN
# 16 15.5569853 18.996330 YV
# Other aggregations
ej4 = sqldf("
SELECT
avg(arr_delay) as mean_arr_delay,
min(dep_delay) as min_dep_delay,
max(dep_delay) as max_dep_delay,
carrier
FROM
flights
GROUP BY
carrier
")
# We can compute the minimun, mean, and maximum values of a numeric value
ej4
# mean_arr_delay min_dep_delay max_dep_delay carrier
# 1 7.3796692 -24 747 9E
# 2 0.3642909 -24 1014 AA
# 3 -9.9308886 -21 225 AS
# 4 9.4579733 -43 502 B6
# 5 1.6443409 -33 960 DL
# 6 15.7964311 -32 548 EV
# 7 21.9207048 -27 853 F9
# 8 20.1159055 -22 602 FL
# 9 -6.9152047 -16 1301 HA
# 10 10.7747334 -26 1137 MQ
# 11 11.9310345 -14 154 OO
# 12 3.5580111 -20 483 UA
# 13 2.1295951 -19 500 US
# 14 1.7644644 -20 653 VX
# 15 9.6491199 -13 471 WN
# 16 15.5569853 -16 387 YV
### We could be also interested in knowing how many observations each carrier has
ej5 = sqldf("
SELECT
carrier, count(*) as count
FROM
flights
GROUP BY
carrier
")
ej5
# carrier count
# 1 9E 18460
# 2 AA 32729
# 3 AS 714
# 4 B6 54635
# 5 DL 48110
# 6 EV 54173
# 7 F9 685
# 8 FL 3260
# 9 HA 342
# 10 MQ 26397
# 11 OO 32
# 12 UA 58665
# 13 US 20536
# 14 VX 5162
# 15 WN 12275
# 16 YV 601
Najbardziej użyteczną funkcją SQL są łączenia. Łączenie oznacza, że chcemy połączyć tabelę A i tabelę B w jednej tabeli, używając jednej kolumny, aby dopasować wartości obu tabel. Istnieją różne typy sprzężeń, w praktyce, aby rozpocząć, z nich będą najbardziej przydatne: sprzężenie wewnętrzne i lewe sprzężenie zewnętrzne.
# Let’s create two tables: A and B to demonstrate joins.
A = data.frame(c1 = 1:4, c2 = letters[1:4])
B = data.frame(c1 = c(2,4,5,6), c2 = letters[c(2:5)])
A
# c1 c2
# 1 a
# 2 b
# 3 c
# 4 d
B
# c1 c2
# 2 b
# 4 c
# 5 d
# 6 e
### INNER JOIN
# This means to match the observations of the column we would join the tables by.
inner = sqldf("
SELECT
A.c1, B.c2
FROM
A INNER JOIN B
ON A.c1 = B.c1
")
# Only the rows that match c1 in both A and B are returned
inner
# c1 c2
# 2 b
# 4 c
### LEFT OUTER JOIN
# the left outer join, sometimes just called left join will return the
# first all the values of the column used from the A table
left = sqldf("
SELECT
A.c1, B.c2
FROM
A LEFT OUTER JOIN B
ON A.c1 = B.c1
")
# Only the rows that match c1 in both A and B are returned
left
# c1 c2
# 1 <NA>
# 2 b
# 3 <NA>
# 4 c
Pierwszym podejściem do analizy danych jest ich wizualna analiza. Celem tego jest zwykle znalezienie relacji między zmiennymi i jednowymiarowych opisów zmiennych. Możemy podzielić te strategie na -
- W analizie jednoczynnikowej
- Analiza wielowymiarowa
Jednowymiarowe metody graficzne
Univariateto termin statystyczny. W praktyce oznacza to, że chcemy analizować zmienną niezależnie od pozostałych danych. Działki, które pozwalają na to sprawnie to -
Wykresy pudełkowe
Wykresy pudełkowe są zwykle używane do porównywania rozkładów. To świetny sposób na wizualne sprawdzenie, czy istnieją różnice między dystrybucjami. Możemy zobaczyć, czy istnieją różnice w cenie diamentów o różnym szlifie.
# We will be using the ggplot2 library for plotting
library(ggplot2)
data("diamonds")
# We will be using the diamonds dataset to analyze distributions of numeric variables
head(diamonds)
# carat cut color clarity depth table price x y z
# 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
# 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
# 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
# 4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
# 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
# 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
### Box-Plots
p = ggplot(diamonds, aes(x = cut, y = price, fill = cut)) +
geom_box-plot() +
theme_bw()
print(p)
Na wykresie widać różnice w rozkładzie cen diamentów w różnych rodzajach szlifów.
Histogramy
source('01_box_plots.R')
# We can plot histograms for each level of the cut factor variable using
facet_grid
p = ggplot(diamonds, aes(x = price, fill = cut)) +
geom_histogram() +
facet_grid(cut ~ .) +
theme_bw()
p
# the previous plot doesn’t allow to visuallize correctly the data because of
the differences in scale
# we can turn this off using the scales argument of facet_grid
p = ggplot(diamonds, aes(x = price, fill = cut)) +
geom_histogram() +
facet_grid(cut ~ ., scales = 'free') +
theme_bw()
p
png('02_histogram_diamonds_cut.png')
print(p)
dev.off()
Wynik powyższego kodu będzie następujący -
Wielowymiarowe metody graficzne
Wielowymiarowe metody graficzne stosowane w eksploracyjnej analizie danych mają na celu znalezienie związków między różnymi zmiennymi. Istnieją dwa powszechnie używane sposoby osiągnięcia tego celu: wykreślenie macierzy korelacji zmiennych numerycznych lub po prostu wykreślenie surowych danych jako macierzy wykresów punktowych.
Aby to zademonstrować, użyjemy zestawu danych diamentów. Aby postępować zgodnie z kodem, otwórz skryptbda/part2/charts/03_multivariate_analysis.R.
library(ggplot2)
data(diamonds)
# Correlation matrix plots
keep_vars = c('carat', 'depth', 'price', 'table')
df = diamonds[, keep_vars]
# compute the correlation matrix
M_cor = cor(df)
# carat depth price table
# carat 1.00000000 0.02822431 0.9215913 0.1816175
# depth 0.02822431 1.00000000 -0.0106474 -0.2957785
# price 0.92159130 -0.01064740 1.0000000 0.1271339
# table 0.18161755 -0.29577852 0.1271339 1.0000000
# plots
heat-map(M_cor)
Kod wygeneruje następujący wynik -
To jest podsumowanie, mówi nam, że istnieje silna korelacja między ceną a karetką, a niewiele między innymi zmiennymi.
Macierz korelacji może być przydatna, gdy mamy dużą liczbę zmiennych, w którym to przypadku wykreślenie surowych danych nie byłoby praktyczne. Jak wspomniano, możliwe jest również pokazanie surowych danych -
library(GGally)
ggpairs(df)
Na wykresie widzimy, że wyniki wyświetlane na mapie cieplnej są potwierdzone, istnieje korelacja 0,922 między zmiennymi cenowymi i karatowymi.
Możliwe jest zwizualizowanie tej zależności na wykresie rozrzutu cena-karat znajdującym się w indeksie (3, 1) macierzy wykresu rozrzutu.
Istnieje wiele narzędzi, które pozwalają analitykowi danych na efektywną analizę danych. Zazwyczaj inżynierski aspekt analizy danych koncentruje się na bazach danych, a naukowcy zajmujący się danymi koncentrują się na narzędziach, które mogą wdrażać produkty danych. W poniższej sekcji omówiono zalety różnych narzędzi, ze szczególnym uwzględnieniem pakietów statystycznych, których naukowcy używają w praktyce najczęściej.
Język programowania R.
R to język programowania typu open source, który koncentruje się na analizie statystycznej. Pod względem możliwości statystycznych konkuruje z komercyjnymi narzędziami, takimi jak SAS, SPSS. Uważa się, że jest to interfejs do innych języków programowania, takich jak C, C ++ czy Fortran.
Kolejną zaletą języka R jest duża liczba dostępnych bibliotek typu open source. W CRAN jest ponad 6000 pakietów, które można pobrać bezpłatnie i w formacieGithub dostępna jest szeroka gama pakietów R.
Jeśli chodzi o wydajność, R jest powolny w przypadku intensywnych operacji, biorąc pod uwagę dużą liczbę dostępnych bibliotek, wolne sekcje kodu są napisane w językach kompilowanych. Ale jeśli zamierzasz wykonywać operacje, które wymagają pisania głębokich pętli for, to R nie byłby najlepszą alternatywą. Do celów analizy danych istnieją ładne biblioteki, takie jakdata.table, glmnet, ranger, xgboost, ggplot2, caret które pozwalają używać R jako interfejsu do szybszych języków programowania.
Python do analizy danych
Python jest językiem programowania ogólnego przeznaczenia i zawiera znaczną liczbę bibliotek poświęconych analizie danych, takich jak pandas, scikit-learn, theano, numpy i scipy.
Większość tego, co jest dostępne w R, można również zrobić w Pythonie, ale odkryliśmy, że R jest prostszy w użyciu. W przypadku pracy z dużymi zbiorami danych, zwykle Python jest lepszym wyborem niż R. Python może być używany dość skutecznie do czyszczenia i przetwarzania danych wiersz po wierszu. Jest to możliwe z poziomu R, ale nie jest tak wydajne jak Python do zadań związanych ze skryptami.
Do uczenia maszynowego, scikit-learnto przyjemne środowisko, które udostępnia dużą liczbę algorytmów, które bez problemu radzą sobie z średniej wielkości zbiorami danych. W porównaniu z równoważną biblioteką R (daszkiem),scikit-learn ma bardziej przejrzysty i spójny interfejs API.
Julia
Julia to wysokopoziomowy, dynamiczny język programowania o wysokiej wydajności do obliczeń technicznych. Jego składnia jest dość podobna do R lub Pythona, więc jeśli już pracujesz z R lub Pythonem, napisanie tego samego kodu w Julii powinno być dość proste. Język jest całkiem nowy i znacznie się rozwinął w ostatnich latach, więc w tej chwili jest to zdecydowanie opcja.
Zalecamy Julię do tworzenia prototypów algorytmów, które wymagają dużej mocy obliczeniowej, takich jak sieci neuronowe. To świetne narzędzie do badań. Jeśli chodzi o wdrażanie modelu do produkcji, prawdopodobnie Python ma lepsze alternatywy. Jednak staje się to mniejszym problemem, ponieważ istnieją usługi internetowe, które zajmują się inżynierią wdrażania modeli w językach R, Python i Julia.
SAS
SAS to język komercyjny, który jest nadal używany do analizy biznesowej. Posiada język bazowy, który pozwala użytkownikowi programować szeroką gamę aplikacji. Zawiera sporo produktów komercyjnych, które dają użytkownikom niebędącym ekspertami możliwość korzystania ze złożonych narzędzi, takich jak biblioteka sieci neuronowych, bez konieczności programowania.
Poza oczywistą wadą komercyjnych narzędzi, SAS nie skaluje się dobrze do dużych zbiorów danych. Nawet średni zbiór danych będzie miał problemy z SAS i spowoduje awarię serwera. Tylko jeśli pracujesz z małymi zbiorami danych, a użytkownicy nie są ekspertami w dziedzinie danych, zaleca się użycie SAS. Zaawansowanym użytkownikom R i Python zapewniają bardziej produktywne środowisko.
SPSS
SPSS, jest obecnie produktem IBM do analizy statystycznej. Służy głównie do analizy danych ankietowych, a dla użytkowników, którzy nie są w stanie programować, jest przyzwoitą alternatywą. Jest prawdopodobnie tak samo prosty w użyciu jak SAS, ale pod względem implementacji modelu jest prostszy, ponieważ zapewnia kod SQL do oceny modelu. Ten kod zwykle nie jest wydajny, ale to początek, podczas gdy SAS sprzedaje produkt, który ocenia modele dla każdej bazy danych osobno. W przypadku małych danych i niedoświadczonego zespołu SPSS jest opcją równie dobrą jak SAS.
Oprogramowanie jest jednak dość ograniczone, a doświadczeni użytkownicy będą o rząd wielkości bardziej produktywni, używając języka R lub Python.
Matlab, Octave
Dostępne są inne narzędzia, takie jak Matlab lub jego wersja open source (Octave). Te narzędzia są najczęściej używane do badań. Pod względem możliwości R lub Python może zrobić wszystko, co jest dostępne w Matlabie lub Octave. Zakup licencji na produkt ma sens tylko wtedy, gdy jesteś zainteresowany wsparciem, jakie zapewnia.
Analizując dane, można przyjąć podejście statystyczne. Podstawowe narzędzia potrzebne do wykonania podstawowej analizy to -
- Analiza korelacji
- Analiza wariancji
- Testowanie hipotez
Podczas pracy z dużymi zbiorami danych nie stanowi to problemu, ponieważ te metody nie wymagają intensywnych obliczeń, z wyjątkiem analizy korelacji. W takim przypadku zawsze można pobrać próbkę, a wyniki powinny być rzetelne.
Analiza korelacji
Analiza korelacji ma na celu znalezienie liniowych zależności między zmiennymi numerycznymi. Może to być przydatne w różnych okolicznościach. Jednym z powszechnych zastosowań jest eksploracyjna analiza danych, w sekcji 16.0.2 książki znajduje się podstawowy przykład tego podejścia. Przede wszystkim metryka korelacji zastosowana w tym przykładzie jest oparta naPearson coefficient. Istnieje jednak inna interesująca miara korelacji, na którą wartości odstające nie mają wpływu. Ta miara nazywa się korelacją włócznika.
Plik spearman correlation metryka jest bardziej odporna na obecność wartości odstających niż metoda Pearsona i daje lepsze oszacowania zależności liniowych między zmienną numeryczną, gdy dane nie mają rozkładu normalnego.
library(ggplot2)
# Select variables that are interesting to compare pearson and spearman
correlation methods.
x = diamonds[, c('x', 'y', 'z', 'price')]
# From the histograms we can expect differences in the correlations of both
metrics.
# In this case as the variables are clearly not normally distributed, the
spearman correlation
# is a better estimate of the linear relation among numeric variables.
par(mfrow = c(2,2))
colnm = names(x)
for(i in 1:4) {
hist(x[[i]], col = 'deepskyblue3', main = sprintf('Histogram of %s', colnm[i]))
}
par(mfrow = c(1,1))
Z histogramów na poniższym rysunku możemy spodziewać się różnic w korelacjach obu wskaźników. W tym przypadku, ponieważ zmienne wyraźnie nie mają rozkładu normalnego, korelacja Spearmana jest lepszym oszacowaniem liniowej zależności między zmiennymi numerycznymi.
Aby obliczyć korelację w R, otwórz plik bda/part2/statistical_methods/correlation/correlation.R który ma tę sekcję kodu.
## Correlation Matrix - Pearson and spearman
cor_pearson <- cor(x, method = 'pearson')
cor_spearman <- cor(x, method = 'spearman')
### Pearson Correlation
print(cor_pearson)
# x y z price
# x 1.0000000 0.9747015 0.9707718 0.8844352
# y 0.9747015 1.0000000 0.9520057 0.8654209
# z 0.9707718 0.9520057 1.0000000 0.8612494
# price 0.8844352 0.8654209 0.8612494 1.0000000
### Spearman Correlation
print(cor_spearman)
# x y z price
# x 1.0000000 0.9978949 0.9873553 0.9631961
# y 0.9978949 1.0000000 0.9870675 0.9627188
# z 0.9873553 0.9870675 1.0000000 0.9572323
# price 0.9631961 0.9627188 0.9572323 1.0000000
Test chi-kwadrat
Test chi kwadrat pozwala nam sprawdzić, czy dwie zmienne losowe są niezależne. Oznacza to, że rozkład prawdopodobieństwa każdej zmiennej nie wpływa na drugą. Aby ocenić test w R, musimy najpierw utworzyć tabelę kontyngencji, a następnie przekazać ją dochisq.test R funkcjonować.
Na przykład, sprawdźmy, czy istnieje powiązanie między zmiennymi: szlifem i kolorem z zestawu danych o diamentach. Test jest formalnie zdefiniowany jako -
- H0: Zmienne cięcie i diament są niezależne
- H1: Zmienna szlif i diament nie są niezależne
Zakładalibyśmy, że istnieje związek między tymi dwiema zmiennymi poprzez ich nazwy, ale test może dać obiektywną „regułę” mówiącą, jak istotny jest ten wynik, czy nie.
W poniższym fragmencie kodu stwierdziliśmy, że wartość p testu wynosi 2,2e-16, czyli praktycznie jest to prawie zero. Następnie po uruchomieniu testu wykonując plikMonte Carlo simulation, stwierdziliśmy, że wartość p wynosi 0,0004998, co jest nadal dość niższe niż próg 0,05. Ten wynik oznacza, że odrzucamy hipotezę zerową (H0), więc wierzymy w zmiennecut i color nie są niezależni.
library(ggplot2)
# Use the table function to compute the contingency table
tbl = table(diamonds$cut, diamonds$color)
tbl
# D E F G H I J
# Fair 163 224 312 314 303 175 119
# Good 662 933 909 871 702 522 307
# Very Good 1513 2400 2164 2299 1824 1204 678
# Premium 1603 2337 2331 2924 2360 1428 808
# Ideal 2834 3903 3826 4884 3115 2093 896
# In order to run the test we just use the chisq.test function.
chisq.test(tbl)
# Pearson’s Chi-squared test
# data: tbl
# X-squared = 310.32, df = 24, p-value < 2.2e-16
# It is also possible to compute the p-values using a monte-carlo simulation
# It's needed to add the simulate.p.value = TRUE flag and the amount of
simulations
chisq.test(tbl, simulate.p.value = TRUE, B = 2000)
# Pearson’s Chi-squared test with simulated p-value (based on 2000 replicates)
# data: tbl
# X-squared = 310.32, df = NA, p-value = 0.0004998
Test T.
Pomysł t-testpolega na ocenie, czy istnieją różnice w liczbowym rozkładzie zmiennych # między różnymi grupami zmiennej nominalnej. Aby to zademonstrować, wybiorę poziomy Dostatecznego i Idealnego cięcia zmiennej czynnikowej, a następnie porównamy wartości zmiennej numerycznej między tymi dwiema grupami.
data = diamonds[diamonds$cut %in% c('Fair', 'Ideal'), ]
data$cut = droplevels.factor(data$cut) # Drop levels that aren’t used from the
cut variable
df1 = data[, c('cut', 'price')]
# We can see the price means are different for each group
tapply(df1$price, df1$cut, mean)
# Fair Ideal
# 4358.758 3457.542
Testy t są implementowane w języku R z rozszerzeniem t.testfunkcjonować. Interfejs formuły do t.test jest najprostszym sposobem jego użycia, chodzi o to, że zmienna numeryczna jest wyjaśniana przez zmienną grupową.
Na przykład: t.test(numeric_variable ~ group_variable, data = data). W poprzednim przykładzienumeric_variable jest price i group_variable jest cut.
Z perspektywy statystycznej sprawdzamy, czy istnieją różnice w rozkładach zmiennej liczbowej między dwiema grupami. Formalnie test hipotezy jest opisany hipotezą zerową (H0) i hipotezą alternatywną (H1).
H0: Nie ma różnic w rozkładach zmiennej ceny między grupami Fair i Ideal
H1 Występują różnice w rozkładach zmiennej ceny między grupami Fair i Ideal
Poniższe można zaimplementować w języku R za pomocą następującego kodu -
t.test(price ~ cut, data = data)
# Welch Two Sample t-test
#
# data: price by cut
# t = 9.7484, df = 1894.8, p-value < 2.2e-16
# alternative hypothesis: true difference in means is not equal to 0
# 95 percent confidence interval:
# 719.9065 1082.5251
# sample estimates:
# mean in group Fair mean in group Ideal
# 4358.758 3457.542
# Another way to validate the previous results is to just plot the
distributions using a box-plot
plot(price ~ cut, data = data, ylim = c(0,12000),
col = 'deepskyblue3')
Możemy przeanalizować wynik testu, sprawdzając, czy wartość p jest niższa niż 0,05. W takim przypadku zachowujemy hipotezę alternatywną. Oznacza to, że znaleźliśmy różnice cen między dwoma poziomami współczynnika obniżki. Po nazwach poziomów spodziewalibyśmy się takiego wyniku, ale nie spodziewalibyśmy się, że średnia cena w grupie Fail będzie wyższa niż w grupie Ideal. Możemy to zobaczyć, porównując średnie każdego czynnika.
Plik plotpolecenie tworzy wykres, który pokazuje zależność między ceną a zmienną cięcia. To jest wykres pudełkowy; wykres ten omówiliśmy w sekcji 16.0.1, ale zasadniczo pokazuje on rozkład zmiennej ceny dla dwóch analizowanych poziomów cięcia.
Analiza wariancji
Analiza wariancji (ANOVA) to model statystyczny używany do analizy różnic między rozkładami grup poprzez porównanie średniej i wariancji w każdej grupie, model został opracowany przez Ronalda Fishera. ANOVA zapewnia test statystyczny określający, czy średnie z kilku grup są równe, a zatem uogólnia test t na więcej niż dwie grupy.
ANOVA są przydatne do porównywania trzech lub więcej grup pod kątem istotności statystycznej, ponieważ wykonanie wielu testów t dla dwóch prób skutkowałoby zwiększoną szansą popełnienia błędu statystycznego typu I.
Jeśli chodzi o wyjaśnienie matematyczne, do zrozumienia testu potrzebne są następujące informacje.
x ij = x + (x i - x) + (x ij - x)
Prowadzi to do następującego modelu -
x ij = μ + α i + ∈ ij
gdzie μ jest średnią wielką, a α i jest średnią i -tej grupy. Zakłada się, że składnik błędu ∈ ij jest iid z rozkładu normalnego. Hipoteza zerowa testu jest taka, że -
α 1 = α 2 =… = α k
Jeśli chodzi o obliczanie statystyki testowej, musimy obliczyć dwie wartości -
- Suma kwadratów różnicy między grupami -
$$SSD_B = \sum_{i}^{k} \sum_{j}^{n}(\bar{x_{\bar{i}}} - \bar{x})^2$$
- Sumy kwadratów w grupach
$$SSD_W = \sum_{i}^{k} \sum_{j}^{n}(\bar{x_{\bar{ij}}} - \bar{x_{\bar{i}}})^2$$
gdzie SSD B ma stopień swobody k − 1, a SSD W ma stopień swobody N − k. Następnie możemy zdefiniować średnie kwadratowe różnice dla każdej metryki.
MS B = SSD B / (k - 1)
MS w = SSD z / (N - k)
Wreszcie, statystyka testowa w ANOVA jest definiowana jako stosunek powyższych dwóch wielkości
F = MS B / MS w
który następuje po rozkładzie F z k-1 i N-k stopniami swobody. Jeśli hipoteza zerowa jest prawdziwa, F prawdopodobnie będzie bliskie 1. W przeciwnym razie średni kwadratowy MSB między grupami będzie prawdopodobnie duży, co skutkuje dużą wartością F.
Zasadniczo ANOVA bada dwa źródła całkowitej wariancji i widzi, która część ma większy wpływ. Dlatego nazywa się to analizą wariancji, chociaż celem jest porównanie średnich grupowych.
Jeśli chodzi o obliczanie statystyki, w rzeczywistości jest to raczej proste w R. Poniższy przykład pokaże, jak to się robi i wykreśli wyniki.
library(ggplot2)
# We will be using the mtcars dataset
head(mtcars)
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
# Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
# Let's see if there are differences between the groups of cyl in the mpg variable.
data = mtcars[, c('mpg', 'cyl')]
fit = lm(mpg ~ cyl, data = mtcars)
anova(fit)
# Analysis of Variance Table
# Response: mpg
# Df Sum Sq Mean Sq F value Pr(>F)
# cyl 1 817.71 817.71 79.561 6.113e-10 ***
# Residuals 30 308.33 10.28
# Signif. codes: 0 *** 0.001 ** 0.01 * 0.05 .
# Plot the distribution
plot(mpg ~ as.factor(cyl), data = mtcars, col = 'deepskyblue3')
Kod wygeneruje następujący wynik -
Wartość p, którą otrzymujemy w przykładzie, jest znacznie mniejsza niż 0,05, więc R zwraca symbol „***”, aby to oznaczyć. Oznacza to, że odrzucamy hipotezę zerową i znajdujemy różnice między średnimi mpg między różnymi grupamicyl zmienna.
Uczenie maszynowe to poddziedzina informatyki, która zajmuje się takimi zadaniami, jak rozpoznawanie wzorców, widzenie komputerowe, rozpoznawanie mowy, analiza tekstu i ma silne powiązanie ze statystyką i optymalizacją matematyczną. Aplikacje obejmują między innymi rozwój wyszukiwarek, filtrowanie spamu, optyczne rozpoznawanie znaków (OCR). Granice między eksploracją danych, rozpoznawaniem wzorców i dziedziną uczenia się statystyki nie są jasne i zasadniczo wszystkie odnoszą się do podobnych problemów.
Uczenie maszynowe można podzielić na dwa rodzaje zadań -
- Nadzorowana nauka
- Uczenie się bez nadzoru
Nadzorowana nauka
Uczenie nadzorowane odnosi się do rodzaju problemu, w którym istnieją dane wejściowe zdefiniowane jako macierz X, a my jesteśmy zainteresowani przewidywaniem odpowiedzi y . Gdzie X = {x 1 , x 2 ,…, x n } ma n predyktorów i ma dwie wartości y = {c 1 , c 2 } .
Przykładową aplikacją może być przewidywanie prawdopodobieństwa kliknięcia reklamy przez użytkownika przy użyciu funkcji demograficznych jako predyktorów. Jest to często wywoływane, aby przewidzieć współczynnik klikalności (CTR). Wtedy y = {klik, nie - klik}, a predyktorami mogą być użyty adres IP, dzień wejścia na stronę, miasto użytkownika, kraj oraz inne funkcje, które mogą być dostępne.
Uczenie się bez nadzoru
Uczenie się bez nadzoru dotyczy problemu znajdowania grup, które są do siebie podobne, bez konieczności posiadania klasy, z której można by się uczyć. Istnieje kilka podejść do zadania uczenia się mapowania od predyktorów do znajdowania grup, które mają podobne wystąpienia w każdej grupie i różnią się między sobą.
Przykładowym zastosowaniem uczenia się bez nadzoru jest segmentacja klientów. Na przykład w branży telekomunikacyjnej częstym zadaniem jest segmentacja użytkowników według sposobu korzystania z telefonu. Umożliwiłoby to działowi marketingu skierowanie do każdej grupy innego produktu.
Naiwny Bayes to probabilistyczna technika konstruowania klasyfikatorów. Charakterystycznym założeniem naiwnego klasyfikatora Bayesa jest uznanie, że wartość określonej cechy jest niezależna od wartości jakiejkolwiek innej cechy, biorąc pod uwagę zmienną klasy.
Pomimo nadmiernie uproszczonych założeń, o których wspomniano wcześniej, naiwne klasyfikatory Bayesa dają dobre wyniki w złożonych sytuacjach rzeczywistych. Zaletą naiwnego Bayesa jest to, że wymaga on tylko niewielkiej ilości danych szkoleniowych do oszacowania parametrów niezbędnych do klasyfikacji, a klasyfikator może być trenowany przyrostowo.
Naiwny Bayes to warunkowy model prawdopodobieństwa: dany problem do sklasyfikowania, reprezentowany przez wektor x= (x 1 ,…, x n ) reprezentujące jakieś n cech (zmienne niezależne), przypisuje tej instancji prawdopodobieństwa dla każdego z K możliwych wyników lub klas.
$$p(C_k|x_1,....., x_n)$$
Problem z powyższym sformułowaniem polega na tym, że jeśli liczba cech n jest duża lub cecha może przyjąć dużą liczbę wartości, to oparcie takiego modelu na tablicach prawdopodobieństwa jest niewykonalne. Dlatego przeformułowujemy model, aby był prostszy. Korzystając z twierdzenia Bayesa, prawdopodobieństwo warunkowe można rozłożyć na -
$$p(C_k|x) = \frac{p(C_k)p(x|C_k)}{p(x)}$$
Oznacza to, że przy powyższych założeniach niezależności rozkład warunkowy na zmienną klasy C wynosi -
$$p(C_k|x_1,....., x_n)\: = \: \frac{1}{Z}p(C_k)\prod_{i = 1}^{n}p(x_i|C_k)$$
gdzie dowód Z = p (x) jest współczynnikiem skalującym zależnym tylko od x 1 ,…, x n , czyli stałą, jeżeli znane są wartości zmiennych cech. Jedną z powszechnych zasad jest wybranie hipotezy, która jest najbardziej prawdopodobna; jest to znane jako maksymalna reguła decyzyjna a posteriori lub MAP. Odpowiedni klasyfikator, klasyfikator Bayesa, jest funkcją przypisującą etykietę klasy$\hat{y} = C_k$ dla niektórych k w następujący sposób -
$$\hat{y} = argmax\: p(C_k)\prod_{i = 1}^{n}p(x_i|C_k)$$
Implementacja algorytmu w R jest prostym procesem. Poniższy przykład pokazuje, jak wytrenować klasyfikator Naive Bayes i użyć go do przewidywania problemu z filtrowaniem spamu.
Poniższy skrypt jest dostępny w bda/part3/naive_bayes/naive_bayes.R plik.
# Install these packages
pkgs = c("klaR", "caret", "ElemStatLearn")
install.packages(pkgs)
library('ElemStatLearn')
library("klaR")
library("caret")
# Split the data in training and testing
inx = sample(nrow(spam), round(nrow(spam) * 0.9))
train = spam[inx,]
test = spam[-inx,]
# Define a matrix with features, X_train
# And a vector with class labels, y_train
X_train = train[,-58]
y_train = train$spam X_test = test[,-58] y_test = test$spam
# Train the model
nb_model = train(X_train, y_train, method = 'nb',
trControl = trainControl(method = 'cv', number = 3))
# Compute
preds = predict(nb_model$finalModel, X_test)$class
tbl = table(y_test, yhat = preds)
sum(diag(tbl)) / sum(tbl)
# 0.7217391
Jak widać z wyniku, dokładność modelu Naive Bayes wynosi 72%. Oznacza to, że model poprawnie klasyfikuje 72% instancji.
Klaster k-średnich ma na celu podzielenie n obserwacji na k skupień, w których każda obserwacja należy do klastra o najbliższej średniej, służąc jako prototyp klastra. Powoduje to podzielenie przestrzeni danych na komórki Woronoja.
Biorąc pod uwagę zbiór obserwacji (x 1 , x 2 ,…, x n ) , gdzie każda obserwacja jest d-wymiarowym wektorem rzeczywistym, grupowanie k-średnich ma na celu podzielenie n obserwacji na k grup G = {G 1 , G 2 ,…, G k } tak, aby zminimalizować sumę kwadratów wewnątrz klastra (WCSS) zdefiniowaną w następujący sposób -
$$argmin \: \sum_{i = 1}^{k} \sum_{x \in S_{i}}\parallel x - \mu_{i}\parallel ^2$$
Późniejszy wzór przedstawia zminimalizowaną funkcję celu w celu znalezienia optymalnych prototypów w klastrach k-średnich. Intuicja formuły jest taka, że chcielibyśmy znaleźć grupy różniące się od siebie i każdy członek każdej grupy powinien być podobny do innych członków każdego klastra.
Poniższy przykład demonstruje, jak uruchomić algorytm grupowania k-średnich w języku R.
library(ggplot2)
# Prepare Data
data = mtcars
# We need to scale the data to have zero mean and unit variance
data <- scale(data)
# Determine number of clusters
wss <- (nrow(data)-1)*sum(apply(data,2,var))
for (i in 2:dim(data)[2]) {
wss[i] <- sum(kmeans(data, centers = i)$withinss)
}
# Plot the clusters
plot(1:dim(data)[2], wss, type = "b", xlab = "Number of Clusters",
ylab = "Within groups sum of squares")
Aby znaleźć dobrą wartość K, możemy wykreślić sumę kwadratów wewnątrz grup dla różnych wartości K. Ta metryka zwykle maleje wraz z dodawaniem większej liczby grup, chcielibyśmy znaleźć punkt, w którym spadek sumy wewnątrz grup kwadratów zaczyna się powoli zmniejszać. Na wykresie wartość tę najlepiej reprezentuje K = 6.
Po zdefiniowaniu wartości K konieczne jest uruchomienie algorytmu z tą wartością.
# K-Means Cluster Analysis
fit <- kmeans(data, 5) # 5 cluster solution
# get cluster means
aggregate(data,by = list(fit$cluster),FUN = mean)
# append cluster assignment
data <- data.frame(data, fit$cluster)
Niech I = i 1 , i 2 , ..., i n będzie zbiorem n atrybutów binarnych zwanych przedmiotami. Niech D = t 1 , t 2 , ..., t m będzie zbiorem transakcji zwanych bazą danych. Każda transakcja w D ma unikalny identyfikator transakcji i zawiera podzbiór pozycji w I. Reguła jest zdefiniowana jako implikacja postaci X ⇒ Y, gdzie X, Y ⊆ I i X ∩ Y = ∅.
Zbiory elementów (dla krótkich zestawów elementów) X i Y nazywane są poprzednimi (lewostronnymi lub LHS) i następczymi (prawostronnymi lub prawostronnymi) reguły.
Aby zilustrować koncepcje, posłużymy się małym przykładem z domeny supermarketów. Zestaw elementów to I = {mleko, chleb, masło, piwo}, a mała baza danych zawierająca elementy jest pokazana w poniższej tabeli.
Identyfikator transakcji | Przedmiotów |
---|---|
1 | mleko, chleb |
2 | masło do chleba |
3 | piwo |
4 | mleko, chleb, masło |
5 | masło do chleba |
Przykładową regułą dla supermarketu może być {mleko, chleb} ⇒ {masło}, co oznacza, że jeśli kupuje się mleko i chleb, klienci kupują również masło. Aby wybrać interesujące reguły ze zbioru wszystkich możliwych reguł, można zastosować ograniczenia dotyczące różnych miar istotności i zainteresowania. Najbardziej znanymi ograniczeniami są minimalne progi wsparcia i zaufania.
Wsparcie (X) zestawu pozycji X jest zdefiniowane jako odsetek transakcji w zbiorze danych, który zawiera zestaw pozycji. W przykładowej bazie danych w tabeli 1 zestaw pozycji {mleko, chleb} ma wsparcie 2/5 = 0,4, ponieważ występuje w 40% wszystkich transakcji (2 z 5 transakcji). Znajdowanie częstych zestawów przedmiotów może być postrzegane jako uproszczenie problemu uczenia się bez nadzoru.
Pewność reguły jest określona conf (X ⇒ Y) = sup (X ∪ Y) / sup (X). Na przykład reguła {mleko, chleb} ⇒ {masło} ma w bazie danych w Tabeli 1 pewność 0,2 / 0,4 = 0,5, co oznacza, że dla 50% transakcji zawierających mleko i chleb reguła jest prawidłowa. Zaufanie można interpretować jako oszacowanie prawdopodobieństwa P (Y | X), prawdopodobieństwa znalezienia RHS reguły w transakcjach pod warunkiem, że transakcje te zawierają również LHS.
W skrypcie znajdującym się w bda/part3/apriori.R kod do implementacji apriori algorithm może być znaleziony.
# Load the library for doing association rules
# install.packages(’arules’)
library(arules)
# Data preprocessing
data("AdultUCI")
AdultUCI[1:2,]
AdultUCI[["fnlwgt"]] <- NULL
AdultUCI[["education-num"]] <- NULL
AdultUCI[[ "age"]] <- ordered(cut(AdultUCI[[ "age"]], c(15,25,45,65,100)),
labels = c("Young", "Middle-aged", "Senior", "Old"))
AdultUCI[[ "hours-per-week"]] <- ordered(cut(AdultUCI[[ "hours-per-week"]],
c(0,25,40,60,168)), labels = c("Part-time", "Full-time", "Over-time", "Workaholic"))
AdultUCI[[ "capital-gain"]] <- ordered(cut(AdultUCI[[ "capital-gain"]],
c(-Inf,0,median(AdultUCI[[ "capital-gain"]][AdultUCI[[ "capitalgain"]]>0]),Inf)),
labels = c("None", "Low", "High"))
AdultUCI[[ "capital-loss"]] <- ordered(cut(AdultUCI[[ "capital-loss"]],
c(-Inf,0, median(AdultUCI[[ "capital-loss"]][AdultUCI[[ "capitalloss"]]>0]),Inf)),
labels = c("none", "low", "high"))
Aby wygenerować reguły za pomocą algorytmu apriori, musimy stworzyć macierz transakcji. Poniższy kod pokazuje, jak to zrobić w języku R.
# Convert the data into a transactions format
Adult <- as(AdultUCI, "transactions")
Adult
# transactions in sparse format with
# 48842 transactions (rows) and
# 115 items (columns)
summary(Adult)
# Plot frequent item-sets
itemFrequencyPlot(Adult, support = 0.1, cex.names = 0.8)
# generate rules
min_support = 0.01
confidence = 0.6
rules <- apriori(Adult, parameter = list(support = min_support, confidence = confidence))
rules
inspect(rules[100:110, ])
# lhs rhs support confidence lift
# {occupation = Farming-fishing} => {sex = Male} 0.02856148 0.9362416 1.4005486
# {occupation = Farming-fishing} => {race = White} 0.02831579 0.9281879 1.0855456
# {occupation = Farming-fishing} => {native-country 0.02671881 0.8758389 0.9759474
= United-States}
Drzewo decyzyjne to algorytm używany do nadzorowanych problemów uczenia się, takich jak klasyfikacja lub regresja. Drzewo decyzyjne lub drzewo klasyfikacyjne to drzewo, w którym każdy węzeł wewnętrzny (bez liści) jest oznaczony cechą wejściową. Łuki wychodzące z węzła oznaczonego elementem są oznaczone każdą z możliwych wartości elementu. Każdy liść drzewa jest oznaczony klasą lub rozkładem prawdopodobieństwa w klasach.
Drzewa można się „nauczyć”, dzieląc zbiór źródłowy na podzbiory w oparciu o test wartości atrybutu. Ten proces jest powtarzany dla każdego pochodnego podzbioru w sposób rekurencyjny o nazwierecursive partitioning. Rekurencja jest zakończona, gdy podzbiór w węźle ma taką samą wartość zmiennej docelowej lub gdy dzielenie nie dodaje już wartości do prognoz. Ten proces odgórnej indukcji drzew decyzyjnych jest przykładem zachłannego algorytmu i jest to najpowszechniejsza strategia uczenia drzew decyzyjnych.
Drzewa decyzyjne używane w eksploracji danych są dwojakiego rodzaju -
Classification tree - gdy odpowiedź jest zmienną nominalną, na przykład czy wiadomość e-mail jest spamem, czy nie.
Regression tree - kiedy przewidywany wynik można uznać za liczbę rzeczywistą (np. Wynagrodzenie pracownika).
Drzewa decyzyjne są prostą metodą i jako takie mają pewne problemy. Jedną z tych kwestii jest duża zmienność w wynikowych modelach tworzonych przez drzewa decyzyjne. Aby złagodzić ten problem, opracowano zespolone metody drzew decyzyjnych. Istnieją dwie grupy metod zespołowych, które są obecnie szeroko stosowane -
Bagging decision trees- Drzewa te są używane do budowania wielu drzew decyzyjnych poprzez wielokrotne próbkowanie danych szkoleniowych z wymianą i głosowanie drzew na prognozę konsensusu. Algorytm ten nazwano losowym lasem.
Boosting decision trees- Zwiększanie gradientu łączy słabych uczniów; w tym przypadku drzewa decyzyjne przekształcają się w jednego silnego ucznia, w sposób iteracyjny. Dopasowuje słabe drzewo do danych i iteracyjnie dopasowuje słabych uczniów, aby poprawić błąd poprzedniego modelu.
# Install the party package
# install.packages('party')
library(party)
library(ggplot2)
head(diamonds)
# We will predict the cut of diamonds using the features available in the
diamonds dataset.
ct = ctree(cut ~ ., data = diamonds)
# plot(ct, main="Conditional Inference Tree")
# Example output
# Response: cut
# Inputs: carat, color, clarity, depth, table, price, x, y, z
# Number of observations: 53940
#
# 1) table <= 57; criterion = 1, statistic = 10131.878
# 2) depth <= 63; criterion = 1, statistic = 8377.279
# 3) table <= 56.4; criterion = 1, statistic = 226.423
# 4) z <= 2.64; criterion = 1, statistic = 70.393
# 5) clarity <= VS1; criterion = 0.989, statistic = 10.48
# 6) color <= E; criterion = 0.997, statistic = 12.829
# 7)* weights = 82
# 6) color > E
#Table of prediction errors
table(predict(ct), diamonds$cut)
# Fair Good Very Good Premium Ideal
# Fair 1388 171 17 0 14
# Good 102 2912 499 26 27
# Very Good 54 998 3334 249 355
# Premium 44 711 5054 11915 1167
# Ideal 22 114 3178 1601 19988
# Estimated class probabilities
probs = predict(ct, newdata = diamonds, type = "prob")
probs = do.call(rbind, probs)
head(probs)
Regresja logistyczna to model klasyfikacyjny, w którym zmienna odpowiedzi jest kategoryczna. Jest to algorytm wywodzący się ze statystyki i używany do nadzorowanych problemów klasyfikacyjnych. W regresji logistycznej staramy się znaleźć wektor β parametrów w następującym równaniu, które minimalizują funkcję kosztu.
$$logit(p_i) = ln \left ( \frac{p_i}{1 - p_i} \right ) = \beta_0 + \beta_1x_{1,i} + ... + \beta_kx_{k,i}$$
Poniższy kod demonstruje, jak dopasować model regresji logistycznej w R. Użyjemy tutaj zbioru danych spamu do zademonstrowania regresji logistycznej, tej samej, która została użyta dla Naive Bayes.
Z wyników prognoz pod względem dokładności dowiadujemy się, że model regresji osiąga 92,5% dokładność w zbiorze testowym, w porównaniu z 72% uzyskanymi przez klasyfikator Naive Bayes.
library(ElemStatLearn)
head(spam)
# Split dataset in training and testing
inx = sample(nrow(spam), round(nrow(spam) * 0.8))
train = spam[inx,]
test = spam[-inx,]
# Fit regression model
fit = glm(spam ~ ., data = train, family = binomial())
summary(fit)
# Call:
# glm(formula = spam ~ ., family = binomial(), data = train)
#
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -4.5172 -0.2039 0.0000 0.1111 5.4944
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) -1.511e+00 1.546e-01 -9.772 < 2e-16 ***
# A.1 -4.546e-01 2.560e-01 -1.776 0.075720 .
# A.2 -1.630e-01 7.731e-02 -2.108 0.035043 *
# A.3 1.487e-01 1.261e-01 1.179 0.238591
# A.4 2.055e+00 1.467e+00 1.401 0.161153
# A.5 6.165e-01 1.191e-01 5.177 2.25e-07 ***
# A.6 7.156e-01 2.768e-01 2.585 0.009747 **
# A.7 2.606e+00 3.917e-01 6.652 2.88e-11 ***
# A.8 6.750e-01 2.284e-01 2.955 0.003127 **
# A.9 1.197e+00 3.362e-01 3.559 0.000373 ***
# Signif. codes: 0 *** 0.001 ** 0.01 * 0.05 . 0.1 1
### Make predictions
preds = predict(fit, test, type = ’response’)
preds = ifelse(preds > 0.5, 1, 0)
tbl = table(target = test$spam, preds)
tbl
# preds
# target 0 1
# email 535 23
# spam 46 316
sum(diag(tbl)) / sum(tbl)
# 0.925
Szeregi czasowe to sekwencja obserwacji zmiennych kategorialnych lub numerycznych indeksowanych według daty lub sygnatury czasowej. Wyraźnym przykładem danych szeregów czasowych są szeregi czasowe ceny akcji. W poniższej tabeli możemy zobaczyć podstawową strukturę danych szeregów czasowych. W tym przypadku obserwacje są rejestrowane co godzinę.
Znak czasu | Cena akcji |
---|---|
11.10.2015 09:00:00 | 100 |
11.10.2015 10:00:00 | 110 |
11.10.2015 11:00:00 | 105 |
11.10.2015 12:00:00 | 90 |
11.10.2015 13:00:00 | 120 |
Zwykle pierwszym krokiem w analizie szeregów czasowych jest wykreślenie serii, co zwykle wykonuje się za pomocą wykresu liniowego.
Najpowszechniejszym zastosowaniem analizy szeregów czasowych jest prognozowanie przyszłych wartości wartości liczbowych przy użyciu struktury czasowej danych. Oznacza to, że dostępne obserwacje służą do przewidywania wartości z przyszłości.
Uporządkowanie danych w czasie oznacza, że tradycyjne metody regresji nie są przydatne. Aby zbudować solidną prognozę, potrzebujemy modeli uwzględniających czasowe uporządkowanie danych.
Najpopularniejszy model analizy szeregów czasowych nosi nazwę Autoregressive Moving Average(ARMA). Model składa się z dwóch części, anautoregressive (AR) część i a moving average(MA) cz. Model jest zwykle nazywany modelem ARMA (p, q), gdzie p jest rzędem części autoregresyjnej, a q jest rzędem części średniej ruchomej.
Model autoregresyjny
AR (p) jest odczytywana jako Model AR rzędu p. Matematycznie jest napisane jako -
$$ X_t = c + \ sum_ {i = 1} ^ {P} \ phi_i X_ {t - i} + \ varepsilon_ {t} $$
gdzie {φ 1 ,…, φ p } są parametrami do oszacowania, c jest stałą, a zmienna losowa ε t reprezentuje biały szum. Konieczne są pewne ograniczenia wartości parametrów, aby model pozostał nieruchomy.
Średnia krocząca
Notacja MA (q) odnosi się do modelu średniej ruchomej rzędu q -
$$ X_t = \ mu + \ varepsilon_t + \ sum_ {i = 1} ^ {q} \ theta_i \ varepsilon_ {t - i} $$
gdzie θ 1 , ..., θ q są parametrami modelu, μ jest oczekiwaniem X t , a ε t , ε t - 1 , ... są składnikami błędu białego szumu.
Autoregresywna średnia krocząca
Model ARMA (p, q) łączy warunki p autoregresyjne i q średniej ruchomej. Matematycznie model jest wyrażony następującym wzorem -
$$ X_t = c + \ varepsilon_t + \ sum_ {i = 1} ^ {P} \ phi_iX_ {t - 1} + \ sum_ {i = 1} ^ {q} \ theta_i \ varepsilon_ {ti} $$
Widzimy, że model ARMA (p, q) jest połączeniem modeli AR (p) i MA (q) .
Aby dać pewną intuicję dotyczącą modelu, weźmy pod uwagę, że część AR równania stara się oszacować parametry dla obserwacji X t - i w celu przewidzenia wartości zmiennej w X t . Ostatecznie jest to średnia ważona z poprzednich wartości. Sekcja MA stosuje to samo podejście, ale z błędem poprzednich obserwacji ε t - i . Ostatecznie wynikiem modelu jest średnia ważona.
Poniższy kod ilustruje sposób wdrożenia ARMA (p, q) w R .
# install.packages("forecast")
library("forecast")
# Read the data
data = scan('fancy.dat')
ts_data <- ts(data, frequency = 12, start = c(1987,1))
ts_data
plot.ts(ts_data)
Wykreślenie danych jest zwykle pierwszym krokiem do ustalenia, czy dane mają strukturę czasową. Z działki widać, że pod koniec każdego roku występują silne skoki.
Poniższy kod dopasowuje model ARMA do danych. Uruchamia kilka kombinacji modeli i wybiera ten, który ma mniej błędów.
# Fit the ARMA model
fit = auto.arima(ts_data)
summary(fit)
# Series: ts_data
# ARIMA(1,1,1)(0,1,1)[12]
# Coefficients:
# ar1 ma1 sma1
# 0.2401 -0.9013 0.7499
# s.e. 0.1427 0.0709 0.1790
#
# sigma^2 estimated as 15464184: log likelihood = -693.69
# AIC = 1395.38 AICc = 1395.98 BIC = 1404.43
# Training set error measures:
# ME RMSE MAE MPE MAPE MASE ACF1
# Training set 328.301 3615.374 2171.002 -2.481166 15.97302 0.4905797 -0.02521172
W tym rozdziale będziemy używać danych zeskrobanych w części 1 książki. Dane zawierają tekst opisujący profile freelancerów i stawkę godzinową, którą pobierają w USD. Ideą poniższej sekcji jest dopasowanie modelu, który biorąc pod uwagę umiejętności freelancera, jesteśmy w stanie przewidzieć jego stawkę godzinową.
Poniższy kod pokazuje, jak przekonwertować surowy tekst, który w tym przypadku ma umiejętności użytkownika w macierzy worek słów. W tym celu używamy biblioteki R o nazwie tm. Oznacza to, że dla każdego słowa w korpusie tworzymy zmienną z ilością wystąpień każdej zmiennej.
library(tm)
library(data.table)
source('text_analytics/text_analytics_functions.R')
data = fread('text_analytics/data/profiles.txt')
rate = as.numeric(data$rate)
keep = !is.na(rate)
rate = rate[keep]
### Make bag of words of title and body
X_all = bag_words(data$user_skills[keep])
X_all = removeSparseTerms(X_all, 0.999)
X_all
# <<DocumentTermMatrix (documents: 389, terms: 1422)>>
# Non-/sparse entries: 4057/549101
# Sparsity : 99%
# Maximal term length: 80
# Weighting : term frequency - inverse document frequency (normalized) (tf-idf)
### Make a sparse matrix with all the data
X_all <- as_sparseMatrix(X_all)
Teraz, gdy mamy tekst przedstawiony jako rzadka macierz, możemy dopasować model, który da rzadkie rozwiązanie. Dobrą alternatywą w tym przypadku jest użycie LASSO (operator najmniejszego absolutnego skurczu i selekcji). Jest to model regresji, który jest w stanie wybrać najbardziej odpowiednie cechy do przewidywania celu.
train_inx = 1:200
X_train = X_all[train_inx, ]
y_train = rate[train_inx]
X_test = X_all[-train_inx, ]
y_test = rate[-train_inx]
# Train a regression model
library(glmnet)
fit <- cv.glmnet(x = X_train, y = y_train,
family = 'gaussian', alpha = 1,
nfolds = 3, type.measure = 'mae')
plot(fit)
# Make predictions
predictions = predict(fit, newx = X_test)
predictions = as.vector(predictions[,1])
head(predictions)
# 36.23598 36.43046 51.69786 26.06811 35.13185 37.66367
# We can compute the mean absolute error for the test data
mean(abs(y_test - predictions))
# 15.02175
Teraz mamy model, który przy danym zestawie umiejętności jest w stanie przewidzieć wynagrodzenie godzinowe freelancera. Jeśli zostanie zebranych więcej danych, wydajność modelu poprawi się, ale kod do implementacji tego potoku będzie taki sam.
Uczenie się online to poddziedzina uczenia maszynowego, która umożliwia skalowanie nadzorowanych modeli uczenia się do ogromnych zbiorów danych. Podstawową ideą jest to, że nie musimy czytać wszystkich danych z pamięci, aby dopasować model, musimy tylko czytać każdą instancję na raz.
W tym przypadku pokażemy, jak zaimplementować algorytm uczenia się online za pomocą regresji logistycznej. Podobnie jak w większości algorytmów uczenia nadzorowanego istnieje funkcja kosztu, która jest zminimalizowana. W regresji logistycznej funkcję kosztu definiuje się jako -
$$ J (\ theta) \: = \: \ frac {-1} {m} \ left [\ sum_ {i = 1} ^ {m} y ^ {(i)} log (h _ {\ theta} ( x ^ {(i)})) + (1 - y ^ {(i)}) log (1 - h _ {\ theta} (x ^ {(i)})) \ right] $$
gdzie J (θ) reprezentuje funkcję kosztu, a h θ (x) reprezentuje hipotezę. W przypadku regresji logistycznej określa się ją wzorem -
$$ h_ \ theta (x) = \ frac {1} {1 + e ^ {\ theta ^ T x}} $$
Teraz, gdy zdefiniowaliśmy funkcję kosztu, musimy znaleźć algorytm, aby ją zminimalizować. Najprostszy algorytm służący do osiągnięcia tego nazywa się stochastycznym spadkiem gradientowym. Reguła aktualizacji algorytmu dla wag modelu regresji logistycznej jest zdefiniowana jako -
$$ \ theta_j: = \ theta_j - \ alpha (h_ \ theta (x) - y) x $$
Istnieje kilka implementacji następującego algorytmu, ale ten zaimplementowany w bibliotece wabbit samogłosek jest zdecydowanie najbardziej rozwinięty. Biblioteka umożliwia uczenie modeli regresji na dużą skalę i wykorzystuje niewielkie ilości pamięci RAM. Własnymi słowami twórców jest on opisany jako: „Projekt Vowpal Wabbit (VW) to szybki, poza rdzeniem system edukacyjny sponsorowany przez Microsoft Research i (wcześniej) Yahoo! Research”.
Będziemy pracować z zestawem danych Titanic z pliku kagglekonkurencja. Oryginalne dane można znaleźć wbda/part3/vwteczka. Tutaj mamy dwa pliki -
- Mamy dane treningowe (train_titanic.csv) i
- nieoznaczone dane w celu tworzenia nowych prognoz (test_titanic.csv).
Aby przekonwertować format csv do formatu vowpal wabbit format wejściowy użyj csv_to_vowpal_wabbit.pyskrypt Pythona. Oczywiście będziesz musiał mieć w tym celu zainstalowany Python. Przejdź dobda/part3/vw folder, otwórz terminal i wykonaj następujące polecenie -
python csv_to_vowpal_wabbit.py
Zauważ, że w tej sekcji, jeśli używasz systemu Windows, będziesz musiał zainstalować wiersz poleceń systemu Unix, wejdź na stronę internetową cygwin .
Otwórz terminal, a także w folderze bda/part3/vw i wykonaj następujące polecenie -
vw train_titanic.vw -f model.vw --binary --passes 20 -c -q ff --sgd --l1
0.00000001 --l2 0.0000001 --learning_rate 0.5 --loss_function logistic
Złóżmy, co każdy argument funkcji vw call znaczy.
-f model.vw - oznacza, że zapisujemy model w pliku model.vw w celu późniejszego wykonania prognoz
--binary - Zgłasza stratę jako klasyfikację binarną z etykietami -1,1
--passes 20 - Dane są używane 20 razy do nauki wagi
-c - utwórz plik pamięci podręcznej
-q ff - Użyj funkcji kwadratowych w przestrzeni nazw f
--sgd - używaj regularnej / klasycznej / prostej aktualizacji gradientu stochastycznego, tj. Nieadaptacyjna, nienormalizowana i niezmiennicza.
--l1 --l2 - regularyzacja norm L1 i L2
--learning_rate 0.5 - Współczynnik uczenia α zgodnie z formułą reguły aktualizacji
Poniższy kod przedstawia wyniki uruchomienia modelu regresji w wierszu polecenia. W wynikach otrzymujemy średnią utratę dziennika i mały raport o wydajności algorytmu.
-loss_function logistic
creating quadratic features for pairs: ff
using l1 regularization = 1e-08
using l2 regularization = 1e-07
final_regressor = model.vw
Num weight bits = 18
learning rate = 0.5
initial_t = 1
power_t = 0.5
decay_learning_rate = 1
using cache_file = train_titanic.vw.cache
ignoring text input in favor of cache input
num sources = 1
average since example example current current current
loss last counter weight label predict features
0.000000 0.000000 1 1.0 -1.0000 -1.0000 57
0.500000 1.000000 2 2.0 1.0000 -1.0000 57
0.250000 0.000000 4 4.0 1.0000 1.0000 57
0.375000 0.500000 8 8.0 -1.0000 -1.0000 73
0.625000 0.875000 16 16.0 -1.0000 1.0000 73
0.468750 0.312500 32 32.0 -1.0000 -1.0000 57
0.468750 0.468750 64 64.0 -1.0000 1.0000 43
0.375000 0.281250 128 128.0 1.0000 -1.0000 43
0.351562 0.328125 256 256.0 1.0000 -1.0000 43
0.359375 0.367188 512 512.0 -1.0000 1.0000 57
0.274336 0.274336 1024 1024.0 -1.0000 -1.0000 57 h
0.281938 0.289474 2048 2048.0 -1.0000 -1.0000 43 h
0.246696 0.211454 4096 4096.0 -1.0000 -1.0000 43 h
0.218922 0.191209 8192 8192.0 1.0000 1.0000 43 h
finished run
number of examples per pass = 802
passes used = 11
weighted example sum = 8822
weighted label sum = -2288
average loss = 0.179775 h
best constant = -0.530826
best constant’s loss = 0.659128
total feature number = 427878
Teraz możemy użyć model.vw przeszkoliliśmy się w generowaniu prognoz na podstawie nowych danych.
vw -d test_titanic.vw -t -i model.vw -p predictions.txt
Prognozy wygenerowane w poprzednim poleceniu nie są znormalizowane w celu dopasowania do zakresu [0, 1]. Aby to zrobić, używamy transformacji sigmoidalnej.
# Read the predictions
preds = fread('vw/predictions.txt')
# Define the sigmoid function
sigmoid = function(x) {
1 / (1 + exp(-x))
}
probs = sigmoid(preds[[1]])
# Generate class labels
preds = ifelse(probs > 0.5, 1, 0)
head(preds)
# [1] 0 1 0 0 1 0