Analiza w projektach IT

Python w służbie analizy danych

Lipiec 4, 2018 2
Podziel się:

Trwające Mistrzostwa świata w piłce nożnej wzbudzają wiele emocji. Warto sprawdzić co do powiedzenia o grze piłkarzy mają znawcy futbolu i kibice. Jednak scrollowanie twitterowego feedu i przeglądanie wpisu po wpisie okazuje się bardzo czasochłonnym i monotonnym zajęciem. Aby dowiedzieć się, o którym z piłkarzy internauci mówili najczęściej, bez konieczności inwestowania w narzędzia komercyjne, można posłużyć się językiem programowania Python.

Czas poświęcony na ręczne przeglądanie opinii użytkowników Twittera jest niewspółmierny z korzyściami płynącymi z analizy danych w ten właśnie sposób. Oczywiście, na rynku usług dostępnych jest wiele komercyjnych narzędzi, które zagregują dane za nas, jednak co w wypadku kiedy mamy ograniczony budżet lub po prostu nie chcemy wydawać na to pieniędzy?

Proponuję rozwiązanie nie tylko prostsze i szybsze, niż manualne sprawdzanie mediów społecznościowych, ale też pozwalające analizować dane dla interesujących nas wydarzeń, jak chociażby nowe wzmianki o produkcie, marce czy też popularności kandydatów w wyborach prezydenckich w Warszawie. Jedyny koszt, jaki trzeba będzie ponieść to czas na przygotowanie kodu w języku programowania Python oraz zarejestrowanie konta w serwisie Twitter, z którego zbierzemy interesujące nas informacje.

Na potrzeby swojej analizy posłużę się przykładem komentarzy, które pojawiły się na Twitterze po naszym mundialowym meczu o wszystko z Kolumbią. Warto podkreślić, że taką analizę można przeprowadzić za pomocą Pythona nie tylko w odniesieniu do komentarzy o wyczynach sportowych, ale także wyłonić najlepiej oceniony zespół na Openerze czy najbardziej popularną plażę nad Bałtykiem oraz stwierdzić, który kandydat w wyborach samorządowych był najczęściej wymieniany.

Przewodnik krok po kroku

Na początek potrzebne nam będzie środowisko do pracy. Instalacja wszystkiego, co będzie potrzebne nam poniżej jest stosunkowo prosta, dlatego nie będę opisywać po kolei instrukcji instalacji. Niezbędne nam będą:

  • Python 3.6
  • Biblioteka tweepy (pip install tweepy)
  • Biblioteka pandas (pip install pandas)
  • Edytor kodu (np. PyCharm)

Dodatkowo do zbierania wpisów z serwisu Twitter niezbędne będzie nam zarejestrowane tam konto.

Zanim zaczniemy pisać pierwsze linijki kodu, przejdziemy do wygenerowania danych, które uwierzytelnią nas i pozwolą korzystać z twitterowego API. Jako zalogowany użytkownik Twittera przechodzę zatem do strony: https://apps.twitter.com

Rozpoczynam proces tworzenia nowej aplikacji:

apps twitter com create new app 1024x511 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

 

W kolejnym kroku wypełniam wszystkie niezbędne pola, zaznaczam checkbox z potwierdzeniem zapoznania się z regulaminem i klikam na przycisk Create your Twitter application, żeby przejść dalej.

apps twitter com create new app step2 1024x793 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

 

Jeśli wszystkie wymagane pola zostały wypełnione prawidłowo, to pojawi się następny ekran – aplikacji, z którego będzie nas interesować przede wszystkim API key:

apps twitter com create new app step3 1024x545 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

 

którego jeszcze nie kopiuję, bo muszę przejść do ekranu docelowego przez kliknięcie na niebieski link manage keys and access tokens.

Po kliknięciu na niego pojawia się ostatni ekran, który będzie potrzebny do zbudowania prostej aplikacji agregującej tweety.

Teraz nadszedł moment, w którym kopiuję do notatnika dwie wartości:

  • Consumer Key
  • Consumer Secret

zaznaczone na screenie poniżej.

apps twitter com create new app step4 1024x539 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

Z tego samego ekranu potrzebne będą mi jeszcze 2 wartości, które muszę wygenerować sobie samodzielnie. Żeby to zrobić, scrolluję na koniec strony i klikam na Create my access token.

apps twitter com create new app step5 1024x342 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

Po kliknięciu pojawią mi się w tym samym miejscu na stronie ostatnie już dane, które muszę skopiować do notatnika (zaznaczone na screenie poniżej):

apps twitter com create new app step6 1024x359 - Python w służbie analizy danych. O którym polskim piłkarzu polscy Twitterowicze pisali najczęściej z okazji meczu Polska – Kolumbia?

Czas na kodowanie!

Dane skompletowane. Nadszedł czas, aby przejść w końcu do części pythonowej.
To również dobry moment na zadanie sobie pytania – „Co muszę zrobić, żeby otrzymać oczekiwany efekt?”.

Po pierwsze mój program musi uwierzytelnić się w aplikacji twitterowej za pomocą danych, które mam zapisane w notatniku.
Po drugie, dobrze byłoby narzucić odgórny limit na zaciągnięte tweety, aby pobieranie nowych tweetów nie trwało w nieskończoność.
Po trzecie, potrzebna mi jest klasa, która zagreguje tweety.
Na koniec warto byłoby dodać filtr, który zbierze mi tweety z hashtagami, po których chcę odszukać wpisy ze streamu, w przypadku meczu Polska – Kolumbia będą to #POL-COL i #POLCOL.

Zatem, do dzieła!

W pierwszej kolejności dokonuję niezbędnych importów z biblioteki tweepy:

from tweepy import OAuthHandler, Stream
from tweepy.streaming import StreamListener

W kolejnym kroku podaję dane z notatnika, którymi będę się uwierzytelniać:

CONSUMER_KEY = "TU_WKLEJ_SWOJE_DANE" 
CONSUMER_SECRET = "TU_WKLEJ_SWOJE_DANE" 
ACCESS_TOKEN = "TU_WKLEJ_SWOJE_DANE" 
ACCESS_TOKEN_SECRET = "TU_WKLEJ_SWOJE_DANE"

Narzucam odgórny limit, po którym program przestanie zbierać tweety:

LIMIT = 50

Jak widać, limit to zaledwie 50 tweetów, ale chodzi o to, żeby przetestować wykonywanie kodu na mniejszej próbie, co znacznie oszczędzi czas. Oczywiście narzucony limit można później zwiększyć i nic nie stoi na przeszkodzie, aby podać tam np. 50000.

Czas przejść do clou programu. Definiuję klasę Listener, która dziedziczy z klasy StreamListener z biblioteki tweepy.

class Listener(StreamListener):

Następnie definiuję sobie atrybut klasy niezbędny w dalszej części programu.

count = 0

Teraz kolej na funkcję, która będzie agregować „spływające” dane:

def on_data(self, data):
    self.count += 1
    print(data)
    if self.count > LIMIT:
        return False
    return True

 

a w razie błędu, np. przy uwierzytelnianiu wyświetlę błąd i jego numer:

def on_error(self, status):
    print(status)

 

Agregowane dane dobrze byłoby zapisać do pliku, który posłuży mi do dalszego przetworzenia ściągniętych danych. Rozszerzam więc funkcję def on_data o zapis do pliku:

def on_data(self, data):
    self.count += 1
    print(data)

    with open(POLCOL.txt', 'a', encoding='utf-8') as ts:
        for text in data:
            ts.write(text)

    if self.count > LIMIT: 
            return False 
    return True
Ostatnia część programu to instrukcja specjalna, która przed wykonaniem części zbierającej dane uwierzytelni nas za pomocą kluczy z początku kodu w serwisie Twitter:
if __name__ == '__main__':

Tworzę obiekty na podstawie klas dostępnych w bibliotece tweepy (OAuthHandler do autoryzacji i Stream do ustawienia klasy Listener dla streamu danych z Twittera):

start_stream = Listener()
auth = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) 
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) 
stream = Stream(auth, start_stream)

Na koniec pozostaje mi do ustawienia filtr z językiem dla którego chcę zebrać wpisy oraz hashtagami dla pobieranych danych:

stream.filter(languages=["pl"], track=['#POLCOL','#POL-COL'])

Najwyższa pora na przetestowanie działania programu:

Przetestowanie działania programu

Działa! Dla stuprocentowej pewności sprawdzam jeszcze plik ‘twitter_dane.txt’ do którego zapisywane są agregowane dane. UWAGA! Twitter API zwraca dane w formacie JSON i tak też zapisze je w naszym pliku txt.

Co dalej?

Chcę odczytać interesujące mnie dane z zebranych tweetów. Tworzę zatem drugi pythonowy plik, ja nadałem mu nazwę counter.py i planuję, co policzę oraz jakie kroki będą do tego potrzebne.

Po pierwsze muszę otworzyć plik z danymi, a same dane sprowadzić do formy, z której łatwiej i szybciej będzie mi je odczytać. Po drugie potrzebuję te dane przeszukać i obliczyć np. liczbę wystąpień szukanego przeze mnie słowa.

Do obróbki danych niezbędne są mi biblioteki:

import json
import re
import pandas as pd

Tworzę pustą listę, do której przy pomocy pętli for dodam dane z pliku:

tweets_data = []
tweets_file = open('POLCOL.txt', 'r') for line in tweets_file:
    try:
        tweet = json.loads(line)
        tweets_data.append(tweet)

    except:
        continue

Sprawdzę jeszcze, czy kod wykonywany jest poprawnie za pomocą … funkcji print, która wyświetli mi policzoną liczbę ściągniętych wpisów:

print('\n Total scraped tweets count: {}' .format(len(tweets_data)))

 

W moim kodzie wszystko działa jak powinno, dlatego nadszedł moment na skorzystanie z biblioteki pandas i utworzenie DataFrame (w dużym skrócie – to taka struktura danych), który posłuży mi dalej np. do przeszukiwania tekstu i liczenia wystąpień wg narzuconych przeze mnie kryteriów.

tweets = pd.DataFrame()
tweets['text'] = [*map(lambda tweet:tweet['text'] if 'text' in tweet else ' ', tweets_data)]

 

Ja dla przykładu na potrzeby tego artykułu „zmierzę popularność” odwołań do nazwiska naszego selekcjonera i kapitana naszej reprezentacji w kontekście właśnie meczu z Kolumbią 😊

Aby to zrobić, tworzę prostą funkcję, którą wywołam przy licznikach do nazwisk (funkcja policzy mi liczbę wystąpień słowa w tekście przy okazji ujednolicając je) i narzucam w kodzie kryteria wyszukiwania:

    
def word_in_text(word, text):
    word = word.lower()
    text = text.lower()
    match = re.search(word, text)
    if match:

         return True
    return False

tweets['Nawałka'] = tweets['text'].apply(lambda tweet: word_in_text('Nawałka', tweet)) 
tweets['Lewandowski'] = tweets['text'].apply(lambda tweet: word_in_text('Lewandowski', tweet))

Teraz pozostaje już tylko liczyć 😊

keywords = ['Nawałka', 'Lewandowski']
tweets_by_keywords = [tweets['Nawałka'].value_counts()[True], tweets['Lewandowski'].value_counts()[True]]

 

I sprawdzić działanie kodu:

for i in range(0, len(keywords)):
    try:
        print(keywords[i] + ": " + str(tweets_by_keywords[i]))
    except:
        continue

Prezentację danych w wygodnym dla siebie formacie pozostawiam jako zadanie do samodzielnej realizacji wszystkim śmiałkom, którzy dotarli do końca tego wpisu. Pokażę też przykład i zarazem odpowiedź na tytułowe pytanie:

Wykres - liczba wzmianek o poszczególnych osobach

Na koniec dodam tylko, że zaprezentowane tutaj obliczenie jest najprostszym jakie przyszło mi do głowy, ale nic nie stoi na przeszkodzie, żeby z zebranych tweetów zebrać np. informacje o geolokalizacji wpisów, urządzeniach z których Twitterowicze publikowali swoje wpisy, najpopularniejszych wpisach i wielu, wielu innych, na które pozwala nam API serwisu Twitter.

Wszystko zależy od Twojej fantazji 😊

4.9 / 5
Robert Kazuła
Autor: Robert Kazuła
Jestem Inżynierem ds. Testów i Analiz w Sii Polska z doświadczeniem w projektach których fundamentem jest Python. Lubię czasem wyjść ze swojej roli i "sprawdzić się" w zupełnie innej np. Pentestera, Badacza danych czy Trenera IT. Cenię sobie proaktywność i pragmatyczne podejście do rozwiązywania trudnych problemów, zwłaszcza w branży IT. Po godzinach też testuję - głównie gry na Xboxie :)

Imię i nazwisko (wymagane)

Adres email (wymagane)

Temat

Treść wiadomości

komentarze(2)

avatar'
Grzesiek
1 sierpnia 2018 Odpowiedz

Świetny artykuł :) akurat zacząłem interesować się Pythonem, więc chętnie wypróbuje nowego pomyslu :) Pozdrawiam

avatar'
whfr
2 sierpnia 2018 Odpowiedz

bardzo pomocny post, python to chyba najbardziej przyszlosciowe narzedzie, szczegolnie w dobie duzej mocy obliczeniowej

Zostaw komentarz