Rowery Veturilo – część druga

Jakimi trasami poruszają się rowery Veturilo?

Czy ludzie dojeżdżają rowerem do metra?

Jak szybko jeżdżą rowery?

Czy to od czegoś zależy?

W pierwszej części opisałem skąd pobrać dane, pokazałem jak wygląda liczba rowerów Veturilo poruszających się po Warszawie (w ciągu dwóch miesięcy, ale także średnio w poszczególnych dniach tygodnia). Zderzyliśmy dane o ruchu rowerowym z pogodą, co w efekcie pozwoliło dojść do wniosku (chyba mało zaskakującego), że jak jest cieplej i nie pada to jeździmy więcej.

Dzisiaj będzie o tym skąd i dokąd jeżdżą sobie rowery

Sprawdzimy też czy teza postawiona w poprzedniej części (na podstawie ruchu w poszczególnych porach dnia) o dojazdach do i z pracy jest prawdziwa. A przynajmniej zbliżymy się do jej weryfikacji.

Zaczniemy od podłączenia się do źródła danych:

Gdzie są stacje Veturilo?

Pobieramy dane o lokalizacji stacji do pamięci – nie są to duże dane, więc możemy je mieć pod ręką.

Od razu pobierzmy mapę Warszawy z Google Maps i zobaczmy gdzie są zlokalizowane stacje:

Ważne, zgodnie z komentarzem Maćka spod poprzedniej części brakuje nam informacji o stacjach sponsorskich. Bardzo żałuję, że tego nie wiedziałem. Nie mamy informacji o stacjach w pobliżu centrów handlowych (nie “galerii”, bo w gelariach to wiszą obrazy, sklepy są w centrach handlowych), a to byłyby ciekawe dane (w jakich godzinach przyjeżdżają do nich ludzie?). No trudno.

Czy rowerem dojeżdza się do i z pracy?

W poprzedniej części wysnułem wniosek, że rowery w dni robocze używane są jako sposób dotarcia do i z pracy. Ja działałbym według schematu:

  • z domu dojść do najbliższej stacji Veturilo
  • podjechać rowerem do metra
  • przejechać metrem kilka stacji
  • przy docelowej stacji metra wziąć kolejny rower
  • i dojechać do najbliższej pracy stacji metra

Oczywiście ma to sens, kiedy mieszkamy i pracujemy w rozsądnej odległości od stacji Veturlio. I mamy do przejechania kawałek metrem. To może się sprawdzać dla kogoś kto pracuje w okolicach ulicy Grzybowskiej (jest tutaj kilka biurowców – na przykład nowy Q22, jest stajca rowerów o numerze 9483), a mieszka na przykład na Ursynowie przy ulicy Romera (stacja 9606): rowerem z Romera do metra Stokłosy, metrem do Świętokszyskiej, rowerem z metra do stacji na rogu Grzybowskiej i al. Jana Pawła II.

Zakładając taki sposób dotarcia do pracy możemy spodziewać się widocznych zmian w ilości rowerów na stacjach Veturilo w pobliżu metra. Sprawdźmy czy tak jest.

Napierw wyznaczymy stacje przy metrze. Na szczęście mają w nazwie “Metro”, więc wybierzemy odpowiednie; potrzebne nam są jedynie numery stacji:

Teraz możemy z tabeli z pełnymi danymi wyjąć tylko te, które dotyczą stacji metra. Agregując dane do godzin w poszczególne dni tygodnia zobaczymy, że:

W dni robocze na stacjach koło metra średnia liczba przypiętych rowerów spada w okolicach 17-18. To mogłoby potwierdzać tezę – ludzie wychodząc z pracy wracają metrem i do domów dojeżdżają rowerami. Albo nie do domów tylko gdzieś indziej. Rano nie widać tego dołka, ale widać górki – rowerów przy stacjach metra przybywa (bo ktoś dojechał do metra i tam zostawił rower). Stosowne przeciały 8-10 i 16-18 zaznaczyłem pionowymi kreskami.

W weekendy natomiast dołek jest nieco dłuższy i zaczyna się wcześniej (po obiedzie przy Familiadzie, jak na polski dom przystało ;). Wytłumaczyć to można tym, że społeczeństwo dojeżdża sobie metrem do atrakcyjnej lokalizacji, bierze tam rower i rusza w trasę.

Spróbujmy zobaczyć na jakich stacjach te efekty widać najbardziej. Wybierzmy tylko poniedziałek i wtorek (tutaj te popołudniowe spadki są najbardziej widoczne). Dodatkowo, aby było łatwiej – dodajmy nazwy stacji zamiast ich numerów (nie mamy ich w tabeli veturilo_data, trzeba ją złączyć z veturilo_map):

Popołudniowy spadek widać szczególnie na stacjach Dworzec Gdański, Służew, Słodowiec, Stadion Narodowy oraz Rondo Daszyńskiego. Czy to jest dowód potwierdzający moją tezę?

Mam wrażenie, że to jednak cherry picking… ale lepszej tezy nie mam na podorędziu :)

Zobaczmy jeszcze z ciekawości to samo w weekendy:

Popularne weekendowe miejsca to Kabaty, Natolin, Plac Wilsona, Słodowiec, Bielany i Wierzbno. Wiecie dlaczego? Bo niedaleko są duże parki i lasy, po których można przyjemnie pojeździć rowerem. Chyba, że to znowu cherry picking ;).

Najpopularniejsze trasy rowerowe

Czy to wybieranie danych pod tezę (jeśli jeszcze nie sprawdziliście co to cherry picking to jest to właśnie to) czy też fakt możemy sprawdzić w inny sposób. Na przykład badając skąd dokąd (z której do krótej stacji) jeżdżą rowery.

Mamy do tego przygotowaną tabelę bikes, w której znajdują się tylko trzy informacje (ale za to jest ich bardzo dużo) – timestamp (czyli godzina i data pobrania informacji), numer roweru i numer stacji na której rower był przypięty w danej chwili. To są informacje o rowerach na stacjach – rowery w ruchu “nie istnieją” w bazie w danej chwili. Skąd są te informacje?

W danych z Veturilo mamy dla każdej stacji listę przypiętych do niej rowerów (jako jedno pole, numery rowerów rozdzielone przecinkami). Wystarczy wyłuskać te numery do osobnych kolumn (na przykład używając separate() z pakietu tidyr), a później z-melt-ować (melt() z reshape2) albo zrobić im gather() (z tidyr). Ja te wszystkie operacje przeprowadziłem i ich wynik mam w tabeli “bikes” w SQLite’owej sqllite_db.

Początek tabeli wygląda tak:

timestamp station_number bike_number
1489189543 9402 24892
1489189543 9403 24809
1489189543 9404 24979
1489189543 9405 24939
1489189543 9406 24561
1489189543 9407 24861

Jednocześnie możemy sprawdzić ile tak na prawdę jest rowerów – wystaczy policzyć unikalne numery:

Jak widać unikalnych rowerów mamy 4013 Ograniczenie ich liczby w poprzednim wpisie poprzez średnią i odchylenie standardowe dało o około 400 mniej, na co zwrócił uwagę Maciek w komentarzu.

Przy okazji ciekawostka – union() wbudowane w R nie zadziała na danych trzymanych w tabeli “na serwerze” (SQLite, mySQL). A to dlatego, że serwer SQL nie rozumie funkcji unique. Ale rozumie distinct, a pakiet dplyr takową posiada (w dodatku według dokumentacji jest szybsza). Cóż – trzeba się przestawić na inną funkcję, robiącą to samo…

Niestety nie każda funkcja która działa w przypadku tabel trzymanych w pamięci działa na serwerach (na przykład przydałyby się nam funckje lag lub lead – przesuwające dane w tabeli o zadaną ilość rzędów). Ale można sobie poradzić, przynajmniej spróbujemy. A tutaj lag() bardzo by się przydało – potrzebujemy przesunąć o jeden wiersz dane dla każdego z rowerów. Tak, żeby otrzymać informację o obecnej i poprzedniej stacji, do której rower jest przypięty.

Dygresja – pokazuję i objaśniam

Dla uproszczenia przykład (“Nic nie działa na wyobraźnię tak, jak dobry przykład” – rzekomo to słowa Lenina, ale nie znajduję potwierdzenia w Google), który wyjaśni co trzeba zrobić. Jeśli nie chcesz zrozumieć na czym polega trick – kliknij tutaj i przejdź dalej.

Zbudujmy sobie tabelkę z przykładowymi danymi:

czas_o stacja_o rower
15 B R3
17 B R2
14 D R3
16 C R3
8 C R1
3 B R1
5 C R1
7 C R1
9 A R1
11 B R2
1 D R3
2 A R3
6 A R1
10 C R1
20 B R3
19 B R2
12 D R3
4 D R1
13 C R2
18 A R1

Teraz sortując po czasie i grupując po numerze roweru – przesuńmy dane o czasie i stacji jeden wiersz w górę:

rower czas_o czas_p stacja_o stacja_p
R1 3 4 B D
R1 4 5 D C
R1 5 6 C A
R1 6 7 A C
R1 7 8 C C
R1 8 9 C A
R1 9 10 A C
R1 10 18 C A
R1 18 NA A NA
R2 11 13 B C
R2 13 17 C B
R2 17 19 B B
R2 19 NA B NA
R3 1 2 D A
R3 2 12 A D
R3 12 14 D D
R3 14 15 D B
R3 15 16 B C
R3 16 20 C B
R3 20 NA B NA

Wynik to tabela z przesuniętymi czasami i stacjami – czas_p oraz stacja_p to przesunięte położenie (czasowe i przestrzenne, że się tak wyrażę) danego roweru. I tak widzimy, że rower R1 przebył drogę z B do D pomiędzy chwilą 3 a 4. Później z D pojechał na C w czasie od 4 do 5. Z 5 do 6 – z C do A. I tak dalej. Pomiędzy chwilą 7 a 8 stał na stacji C. Na koniec, po chwili 18 gdzieś sobie odjechał ze stacji A i jeszcze nigdzie się nie zameldował. Analogicznie jest dla innych rowerów. Prześledźcie to proszę.

Możemy policzyć teraz ile rowerów przejechało ze stacji do innej stacji. Na początku pozbędziemy się informacji o rowerach, które nie wróciły i które stały na tej samej stacji:

rower czas_o czas_p stacja_o stacja_p
R1 3 4 B D
R1 4 5 D C
R1 5 6 C A
R1 6 7 A C
R1 8 9 C A
R1 9 10 A C
R1 10 18 C A
R2 11 13 B C
R2 13 17 C B
R3 1 2 D A
R3 2 12 A D
R3 14 15 D B
R3 15 16 B C
R3 16 20 C B

Teraz zobaczmy jak wygląda ruch – jakie trasy są najpopularniejsze? Z której na którą stację przejeżdża najwięcej rowerów?

stacja_o stacja_p n
C A 3
A C 2
B C 2
C B 2
A D 1
B D 1
D A 1
D B 1
D C 1

Teraz popatrzmy – 3 przejazdy to trasa C do A. I to się zgadza – porównując z drugą tabelką z naszego przykładu:

  • R1 w 5 do 6
  • R1 w 8 do 9
  • R1 w 10 do 18

A na przykład B do C:

  • R2 w 11 do 13
  • R3 w 15 do 16

Koniec przykładu

Dokładnie to samo trzeba zrobić z rowerami (już nie tymi przykładowymi) – kod jest analogiczny. Ponieważ danych jest bardzo dużo obrobiłem je na boku. Grupowanie w ramach tabeli sprawia, że kolejne operacje przeprowadzane są na grupach, a nie na całości (na przykład średnia liczona jest w ramach grupy, a nie wszystkich danych). Ten sam efekt da wyjęcie grupy do osobnej tabeli, przeprowadzenie obliczeń i dołączenie kolejnych podzbiorów (grup) do nowej tabeli. Tak też zrobiłem, wyniki zapisując w pliku RDS. Potrzeba matką wynalazków. Jednak jeśli masz dużo pamięci w komputerze poniższy kod powinien zadziałać:

Z około 49 milionów wierszy zrobiło się 630 tysięcy. Zobaczmy jak wygląda ruch pomiędzy stacjami. Numery stacji nie są ciągłe od jedynki, są pomiędzy 9400 i 9716, a powyżej mamy trzy stacje z numerami w okolicach 95000 – dlatego na poniższym obrazku odrzucamy te trzy odstające stacje, dodatkowo logarytmujemy liczbę przejazdów, żeby zaakcentować różnice kolorami:

Ładnie to wygląda, niewiele mówi. Coś jednak – najczęstrze podróże są w ramach stacji o sąsiednich numerach (pierwsza dwudziestka “tras”, już bez wyłączenia stacji o dużych numerach, za to z zamianą numerów na nazwy stacji) wygląda następująco:

StacjaA StacjaB Liczba
Marymoncka – Dewajtis Dewajtis – UKSW 1242
Dewajtis – UKSW Marymoncka – Dewajtis 1232
al. Niepodległości – Batorego Stefana Banacha – UW 997
Stefana Banacha – UW al. Niepodległości – Batorego 979
Lipowa – Dobra 2 Lipowa – Dobra 907
Lipowa – Dobra Lipowa – Dobra 2 772
Jastrzębowskiego – SGGW Metro Ursynów I 635
Pileckiego – Alternatywy Metro Imielin 633
Metro Imielin Pileckiego – Alternatywy 625
Metro Ursynów I Jastrzębowskiego – SGGW 592
Plac Hallera – Dąbrowszczaków Plac Wileński 572
Rosoła – Ciszewskiego – SGGW Jastrzębowskiego – SGGW 537
Metro Natolin Metro Kabaty 508
Jastrzębowskiego – SGGW Rosoła – Ciszewskiego – SGGW 492
Metro Kabaty Stryjeńskich – Wąwozowa 466
Plac Wileński Plac Hallera – Dąbrowszczaków 458
Dworzec Wschodni – Kijowska Pętla Kawęczyńska-Bazylika 454
Metro Kabaty Metro Natolin 445
Stryjeńskich – Belgradzka Metro Natolin 441
Wybrzeże Szczecińskie – Stadion Narodowy Rondo Waszyngtona – Stadion Narodowy 431

Takie zestawienia świetnie nadają się do prezentacji w formie grafu, w dodatku skierowanego (takiego, gdzie kierunek przepływu ma znaczenie). Ograniczymy jego rozmiary do par stacji pomiędzy którymi było co najmniej 100 przejazdów. Najpierw przygotujemy graf:

Z takim grafem już można się fajnie pobawić. Grupowanie (automatyczne, według jakiegoś tam algorytmu) wierzchołków dało ciekawe efekty:

Na powyższym obrazku niewiele widać, ale można zastosować pewną sztuczkę. Otóż przygotować odpowiedni layout dla grafu na podstawie współrzędnych stacji. Piękna infografika wówczas wyjdzie. Nie trzeba jednak do tego narzędzi związanych z grafami – wystarczy *ggplot**:

Wracając jeszcze go grafu – można przejrzeć dokładnie wynik przypisania wierzchołków (stacji Veturilo) do grup (lista wc). Na przykład skład pierwszej grupy to:

Jak widać są to punkty w dość zwartym rejonie. Nic dziwnego – mało kto jedzie z jednego końca miasta na drugi.

Chociaż trafi się dłuższa wycieczka – na przykład z Placu Bankowego na wschodną stronę Mostu Północnego (znaczy Skłodowskiej-Curie, jak on się tam formalnie nazywa). Najdłuższa trasa jest pomiędzy stacjami Aluzyjna-Trąby (stacja 9624) a Belgradzka-Rosoła (9618) – jakieś 27 kilometrów. W zakresie za jaki mamy dane przejechały ją 2 rowery (ruszające z Aluzyjnej), co więcej oba w tym samym czasie 31 marca pomiędzy 21:15 a 21:35. Nie zrobił tego człowiek jak sądzę. Musiałby jechać ze średnią prędkością 81 km/h.

Zrobimy coś fajniejszego – wersję interaktywną. Użyjemy biblioteki D3.js, pośrednio przez pakiet networkD3.

Można powiększać, klikać, przeciągać. Polecam zabawę. Im grubsza gałąź tym większy ruch, podobnie z kolorem – im bardziej żółte tym większa popularność trasy.

Średni czas trwania przejazdu pomiędzy stacjami

Teraz sprawdźmy jak wyglądają czasy przejazdu pomiędzy stacjami.

W tabeli bikes_local mamy nadal dwie kolumny z czasem przypięcia danego roweru na stacji wyjściowej i końcowej – na tej podstawie możemy policzyć ile czasu trwała podróż. A właściwie to wypożyczenie roweru. Sprawdźmy jak to się rozkłada dla wypożyczeń nie dłuższych niż 90 minut:

Dominuje czas 10-20 minut. Oczywiście. Wynika to z regulaminu Veturilo i tego, że pierwsze 20 minut jest za darmo. Pełny rozkład to:

ta nieco ponad godzina (średnia) jest zdaje się podawana w podsumowaniach rocznych Veturilo. I jest niezłym zabiegiem marketingowym tak na marginesie… Dlaczego? zastanówcie się sami.

Jak szybko jeżdżą?

Policzymy teraz średnią prędkość jazdy użytkowników Veturilo.

Jak to zrobić? Potrzebujemy czas przejazdu i odległość. Bo jak wszyscy pamiętamy z fizyki – prędkość to:

    \[v = \frac{s}{t}\]

Odległości wyznaczymy na podstawie położenia stacji. Będą to odległości w linii prostej, dla uproszczenia. Potrzebujemy przejść wszystkie pary stacji, każdą z każdą (trochę to potrwa):

Mamy odległości kątowe. Ale to nie są odległości w kilometrach, trzeba to przeliczyć. Jakiś czas temu sprawdzaliśmy, że według Google Maps stopień kątowy to 111 km. Tak więc po prostu przez tyle mnożymy wszystkie wartości. Dodatkowo przekształcimy macierz na ramkę danych, tak żeby później łatwiej było ją łączyć z tym co już posiadamy (czasami przejazdów).

Teraz łączymy otrzymaną bazę odległości z czasami i liczymy średnią prędkość:

Średnia prędkość przejazdu pomiędzy stacjami to 8.4 km/h. Ja z kilku pomiarów na Endomondo mam średnią w okolicach 13 km/h – te 8.4 km/h wygląda prawdopodobnie, tym że odległość liczymy w linii prostej (co pewnie zaniża ją o jakieś 10-15%), oraz przyjmujemy że każdy przejeżdza trasę od stacji do stacji, bez zbaczania i zatrzymywania się.

Rozkład prędkości wygląda następująco:

Jak to wygląda pomiędzy różnymi stacjami?

Widać, że jest to dość równomierne i trasa nie ma większego znaczenia dla prędkości.

Można spróbować zestawić średnie czasy przejazdu z warunkami atmosferycznymi (głównie temperaturą, wilgotnością i prędkością wiatru). Aby to zrobić trzeba:

  • zestawić dane z tabeli bikes_local z tabelą weather z poprzedniego odcinka (grupując najpierw dane po godzinach)
  • dodać do tego odległości między stacjami
  • policzyć prędkość dla przejazdów między stacjami
  • uśrednić prędkości według godzin
  • dodać warunki pogodowe

Zobaczmy co mamy i jak wygląda korelacja pomiędzy prędkością a godziną i warunkami atmosferycznymi:

Widać słabe (mniejsze niż 0.5) korelacje prędkości – dodatnią z wilgotnością (0.32) oraz ujemną z temperaturą (-0.31). Zobaczmy to w szczegółach.

Temperatura:

Trochę jest tak, że im zimniej tym szybciej jeżdżą. Zupełnie inaczej niż z cząsteczkami według praw termodynamiki ;) ale trzeba pamiętać, że jak na razie to temperatury nie były zbyt wysokie. Takie zestawienia można robić dla danych z całego roku.

Dla wilgotności wygląda to zaś tak:

Im bardziej mokro tym większa prędkość. Wiadomo, trzeba uciekać przed deszczem.

Na koniec jeszcze zależność prędkości od pory dania (godziny):

Można pokusić się o tezę, że nad ranem (4-6 rano) jest mały ruch na ulicach i ścieżkach rowerowych, więc da się jeździć szybciej. Widać też większą rozpiętość (większe prostokąciki) w tych porach, co może wskazywać na mniejszą ilość pomiarów i ich większe różnicowanie.

Wróćmy jeszcze do popularności tras – w tabeli wyżej (gdzieś w tych okolicach, po wykresie) widać było głównie trasy tam i z powtorem. Zobaczmy dwie najpopularniejsze:

Dewajtis-UKSW (stacja numer 9402) do Marymoncka-Dewajtis (stacja 9404) i z powrotem:

oraz al. Niepodległości-Batorego (9558) do Stefana Banacha-UW (9551) i z powrotem, ale tym razem w rozbicu na dni tygodnia:

Tutaj piękie widać dojazd na Banacha przed południem i powrót po południu.

Warszawiacy wiedzą co jest w okolicy (dla obu par stacji), ciekawe czy przypuszczają co powoduje taki ruch? Podpowiem: UKSW i UW w nazwach stacji, a dodatkowo lokalizacja SGH oraz stacji metra.

Na dzisiaj to wszystko. Jeśli masz jakiekolwiek uwagi lub pytania – zostaw je w komentarzu.

6 myśli na temat „Rowery Veturilo – część druga

  1. Super opracowanie!

    I kolejne uwagi :-)

    1. Nie wiem czy dobrze zrozumiałem, ale chyba nie uwzględniasz przejazdów, które zaczynają się i kończą w tej samej stacji.
    W danych, które ja zbieram (mniej więcej od początku kwietnia) to 3 najpopularniejsze trasy zaczynają się i kończą w tej samej stacji:
    – al. Niepodległości – Batorego
    – Rondo Waszyngtona – Stadion Narodowy
    – Stefana Banacha – UW

    Dane zbieram co minutę, jeżeli między jedną obecnością roweru w stacji a drugą jest chociaż minuta przerwy, to uznaję, że rower ją opuścił

    2. Z rozważań o prędkości wynika, że nie wszystkie transfery rowerów między stacjami, to przejazdy ludzi na rowerach. Tak jest w istocie: zgodnie z umową między miastem a NextBike, firma jest zobowiązana dokonywać między 22-8 rano transferów rowerów, tak by w każdej stacji było rano zajęte między 20%-80% stojaków.

    • Tak, start i powrót na tej samej stacji wykluczam. Co do danych minutowych – powrót po minucie na tą samą stację to może być zwrot wadliwego roweru, to bym wykluczał (sam kilka razy tak robiłem, jak się zorientowałem że rower nie ma na przykład pedału)

Dodaj komentarz