Jak wyglądają ceny aut używanych w segmencie C, część 2

 

W poprzednim tygodniu (w tym wpisie) pisałem o tym jak modelować można cenę aut używanych, na przykładzie aut z segmentu C.

Dziś pokażę trzy wizualizacje tego zbioru danych, mam nadzieję, że interesujące.

Zobaczymy więc jak zmieniają się ceny aut w zależności od wieku aut, jak wygląda liczba oferowanych aut różnych marek i również jak wygląda wyposażenie aut różnych marek.

Zacznijmy od ceny.

[Rysunek 1. Rozkład cen ofertowych aut używanych w rozbiciu na markę i wiek auta. Czarna kropka odpowiada medianie, pudełka dolnemu i górnemu kwartylowi. Dla zwiększenia czytelności oś OY przedstawiono w skali logarytmicznej. ]

Spójrzmy teraz na dostępność ofert dla różnych marek. Dodatkowo przedstawimy liczbę oferowanych aut w danym roku w podziale na typy nadwozia.

[Rysunek 2. Liczba ofert sprzedaży używanego auta w rozbiciu na typ nadwozia, wiek auta i markę.  Dla niektórych modeli widoczna jest duża podaż +-5-letnich samochodów. Prawdopodobnie kończą się okresy gwarancyjne, auto się amortyzuje i takie auta są sprzedawane przez firmy leasingujące.]

I jeszcze rzut oka na wyposażenie.

[Rysunek 3. Na osi OY przedstawiono procent używanych aut oferowanych do sprzedaży, posiadających określony element wyposażenia. Najwięcej aut serwisowane w ASO stanowią auta mające 4 lata. Ciekawe trendy obserwuje się dla przyciemnianych szyb. Nowsze Astry, C4 i Cee’dy mają je coraz częściej, podczas gdy dla Audi A4 mamy odwrotny trend, przynajmniej  w ostatnich latach. Coraz więcej aut jest wyposażonych w takie elementy jak czujnik parkowania czy ESP (hmm, dziwny jest ten trend z ESP w Ceed’ach)]

 

Btw: wszystkie powyższe wykresy zostały wykonane funkcją xyplot() lub bwplot() w R z użyciem pakietu lattice.

Jak wyglądają ceny aut używanych w segmencie C i problemy modelowania

W poprzedni piątek, w tym wpisie, opisałem trzecią wersję zbioru danych o cenach aut używanych.  W trzech najbliższych wpisach przyjrzymy się bliżej temu zbiorowi danych. Wpisy będą znacznie bardziej technicznie niż poprzednie, ale mam nadzieję że ciekawie dla osób zaczynających przygodę z modelowaniem statystycznym.

Dzisiaj przedstawię kilka umiarkowanie złożonych podejść do modelowania ceny samochodu z użyciem modeli liniowych. Będzie kod w R i trochę narzekań na niezrównoważony zbiór danych. Kolejny wpis przedstawiać będzie przykładowe wizualizacje zbioru danych o cenach aut. A w trzecim wpisie przedstawię krótką prezentację wykonaną z użyciem narzędzia dostępnego online na stronie prezi.com. Narzędzie to jest bezpłatne w wersji średniej dla studentów i nauczycieli akademickich. Ciekawe jestem jak wypadnie prezentacja w nim wykonana, czy lepiej niż w Beamerze?

Pomimo iż większość (żmudnej) pracy związanej z wyborem modelu nie zostanie przedstawiona, i tak będzie dzisiaj bardzo technicznie.

Zaznaczę jeszcze, że modelowana jest cena używanego auta a nie zmiana ceny czy spadek wartości. Modelując cenę mogę dodać efekt wieku auta i mówić, że auta o rok starszy są o x PLN tańsze, ale to są inne auta! W innej wersji i innym wyposażeniem. Efekt wyposażenia można jeszcze usunąć ale efektu związanego z wersja nie. Można porównywać średnią cenę Passata z roku 2006 z ceną Passata z roku 2005. Ale z tego porównania nie można wyciągać wniosków co do utraty wartości tego auta. Są to różne wersje, z różnymi problemami estetyki wersji B5 czy problemów wieku młodzieńczego wersji B6. Modelowanie utraty wartości jest tematem ciekawym i wrócimy do tego gdy będziemy mieli ceny aut zebranych rok wcześniej i rok później.

Wybór podzbioru danych – filtrowanie

Zbiór danych o cenach aut z marca 2012 ma ponad 220 tys wierszy. Kusząca jest możliwość wykorzystania wszystkich tych wierszy do modelowania. Kuszące rzeczy często jednak są złe.

Zgodnie ze złotą zasadą ,,garbage in, garbage out” jeżeli do modelu włożymy śmieciowe dane, otrzymamy śmieciowe wyniki. Ponieważ będziemy wykorzystywać dosyć wrażliwe metody estymacji, w pierwszym kroku wyczyścimy zbiór danych tak by zawierał jak najmniej kłopotliwych zmiennych.

Nawet jeżeli czyszczenie danych jest dosyć żmudne, mało widowiskowe i potrafi zabrać więcej czasu niż cała reszta wizualizacji i modelowania to i tak jest to jeden z ważniejszych kroków. Co z tego, że użyjemy super wyrafinowanej metody estymacji skoro w danych mamy śmieci?

W tym przypadku proces czyszczenia danych polegał na wybraniu aut, które:

  • należą do segmentu C, jest to najpopularniejszy segment aut. Wybierałem z tego segmentu modele dla których znalazłem przynajmniej 100 ofert sprzedaży, co mam nadzieje wystarczy do rozsądnej estymacji. Wybrane modele to: Golf, Astra, A3, C4, Focus, Civic, i30, Cee’d, 308, Octavia.
  • mają mniej niż 12 lat, czyli rok produkcji to przynajmniej rok 2000,
  • ma nadwozie Kombi lub Hatchback, pozostałe wersje nadwozia są znacznie mniej popularne,
  • jest zarejestrowane w Polsce,
  • pochodzi z jednego z krajów: Polska, Wlochy, Czechy, Francja, Holandia, Belgia, Niemcy,
  • rodzaj paliwa to diesel, benzyna lub benzyna+LPG, inne bardziej egzotyczne źródła energii pomijam,
  • pojemność silnika jest z przedziału 1150 – 2200 cm3,
  • skrzynia biegów jest manualna,
  • auto nie jest uszkodzone a cena jest ceną brutto.

Po zastosowaniu tych filtrów pozostaje jedynie 13 419 aut, czyli mniej niż 10%. Wybrana grupa jest jednak bardziej jednorodna, mniej jesteśmy więc narażeni na ,,niespodziewane” problemy związane z brakiem zrównoważenia danych. Np. nie musimy się przejmować artefaktem związanym z tym, że najstarsze golfy mają po kilkadziesiąt lat, a modele i30 są co najwyżej kilkuletnie.

#
# Filtrujemy dane. Pozostawiamy tylko auta pasujące do powyższego opisu.
# W wyniku otrzymujemy trochę ponad 13 tys aut
#
load("cenyAutIII2012.Rdata")
modele <- c("Golf", "Astra", "A3", "C4", "Focus", "Civic", "i30", "Cee'd", "308", "Octavia") 
segmentC <- cenyAutIII2012[(cenyAutIII2012$Model %in% modele) & 
                 (cenyAutIII2012$Nadwozie %in% c("Kombi", "Hatchback")) & 
                 (cenyAutIII2012$Kraj.aktualnej.rejestracji == "Polska" | cenyAutIII2012$Kraj.aktualnej.rejestracji == "") & 
                 (cenyAutIII2012$Kraj.pochodzenia %in% c("Wlochy", "Czechy", "Francja", "Holandia", "Belgia", "Polska", "Niemcy", "")) & 
                 (cenyAutIII2012$Rodzaj.paliwa %in% c("benzyna+LPG", "benzyna", "olej napedowy (diesel)")) &
                 (cenyAutIII2012$Pojemnosc.skokowa > 1150 & cenyAutIII2012$Pojemnosc.skokowa < 2201) &
                 cenyAutIII2012$Rok.produkcji > 2000 & 
                 cenyAutIII2012$Skrzynia.biegow == "manualna" & 
                 cenyAutIII2012$Brutto.netto == "brutto" & (cenyAutIII2012$Liczba.drzwi %in% c("2/3", "4/5")) & cenyAutIII2012$Pojazd.uszkodzony == "",]
segmentC <- segmentC[!is.na(segmentC$Cena),]

Kodowanie zmiennych i wstępne transformacje

Zanim zaczniemy cokolwiek modelować, trzeba zastanowić się jak zakodować zmienne w modelu. Po serii prób wybrałem następujące transformacje przygotowujące dane

  • zamiast roku produkcji analizowany będzie wiek auta, czyli 2012 – rok produkcji. Ułatwi to interpretację ceny efektu wieku auta (porównywałem też wyniki z wiekiem traktowanym jako zmienna jakościowa, ale nie były lepsze, więc wiek pozostał zmienną ilościową)
  • pojemność silnika została zamieniona na zmienną jakościową z poziomami co 100cm3.
  • z adresu auta wyciągnąłem informację o kodzie pocztowym, odpowiednio pierwszej cyfrze kodu pocztowego, dwóch pierwszych cyfrach i wszystkich pięciu cyfrach.
  • z kolumn wyposażenie dodatkowe i informacje dodatkowe wyciągnąłem elementy wyposażenia pojawiające się w przynajmniej 100 ofertach. Dodałem kolumny kodujące binarnie czy auto posiada: niezalezne ogrzewanie, instalacja gazowa, szyberdach, bagażnik na dach, blokada skrzyni biegow, skorzana tapicerka, ksenony, EDS, system nawigacji, hak, podgrzewane fotele, pod. przednia szyba, przyciemniane szyby, czujnik deszczu, czujnik parkowania, tempomat, kierownica wielofunkcyjna, welurowa tapicerka, ASR, garażowany, ESP, alufelgi, autoalarm, lwiatla przeciwmglowe, pierwszy wlasciciel, serwisowany w ASO, bezwypadkowy, komputer, el. lusterka, radio / CD, immobiliser, el. szyby, poduszka powietrzna, klimatyzacja, centralny zamek, ABS, wspomaganie kierownicy.
  • cenę wyrażoną w różnych walutach zamieniłem na cenę w PLN.
  • zmienną do analizy będzie logarytm dwójkowy ceny. Analiza ceny z użyciem modeli gaussowskich nie ma sensu, mając do wyboru transformację ceny albo rozważanie bardziej złożonych klas modeli wybrałem transformację. Z rodziny transformacji Boxa Coxa najlepiej wypadała transformacja y^0.2, ale nie różniła się ona znacząco od logarytmu więc wybrałem logarytm bo łatwiej go interpretować.
#
# Dodajemy do zbioru danych zmienne po transformacji.
#
# Zamieniamy rok produkcji na wiek
segmentC$wiek <- 2012 - segmentC$Rok.produkcji
 
# Zamieniamy ilościową zmienną pojemność na zmienną jakościową
segmentC$pojemnosc <- factor(((segmentC$Pojemnosc.skokowa - 50) %/% 100) * 100 + 50)            
 
# konstruujemy zmienną opisująca lokalizację geograficzną, 
# odpowiadającą pierwszej cyfrze kodu (mniej więcej województwo), 
# dwóm pierwszym cyfrom kodu pocztowego lub wszystkim pięciu cyfrom kodu pocztowego.
segmentC$kodPocztowy5 <- factor(substr(segmentC$Adres, 1,6))
segmentC$kodPocztowy1 <- factor(substr(segmentC$Adres, 1,1))
segmentC$kodPocztowy2 <- factor(substr(segmentC$Adres, 1,2))
 
# usuwamy zbędne puste poziomy
segmentC$Model = factor(segmentC$Model)
segmentC$Nadwozie = factor(segmentC$Nadwozie)
segmentC$Rodzaj.paliwa = factor(segmentC$Rodzaj.paliwa)
 
# Konstruujemy macierz cech dodatkowych, najpierw identyfikujemy listę nazw wyposażenia dodatkowego 
# a następnie budujemy odpowiednią ramkę danych
tmp <- paste(as.character(segmentC$Wyposazenie.dodatkowe),as.character(segmentC$Informacje.dodatkowe), sep=", ")
tmps <- strsplit(tmp, split=", *")
cechy <- names(sort(table(factor(unlist(tmps))))[10:46])
ncechy <- sapply(cechy, function(x) grepl(x, tmp))
 
# Składamy nowe zmienne w ramkę danych segmentC2
segmentC2 <- data.frame(segmentC[,c("Cena.w.PLN", "Model", "Nadwozie", "Pojemnosc.skokowa", "Rodzaj.paliwa", 
  "wiek", "kodPocztowy2", "kodPocztowy1")], ncechy)

 

Model 1. Najistotniejsze czynniki

Korzystając z tzw. wiedzy eksperckiej i po kilkunastu próbach eksperymentalnych jako trzy najważniejsze czynniki wpływające na cenę samochodu wybrałem: model samochodu, nadwozie i wiek auta. Jeżeli w modelu uwzględni się wiek to okazuje się, że deklarowany przebieg w km ma minimalne znaczenie, więc na tym etapie został pominięty.

Poniżej przedstawiam wyniki estymacji współczynników modelu. W kolejnym wpisie, gdy pokażemy wizualizacje naszych danych łatwiej będzie uwierzyć, że otrzymany model jest sensowny. Btw: poniższy model tłumaczy 85% zmienności ceny auta, całkiem dużo jak na trzy zmienne.

Co ciekawego można zauważyć? Audi A3 jest średnio najdroższe bez względu na to czy w wersji Kombi czy nie (droższe przynajmniej o 1/4), czy jest to efekt samej marki czy wyposażenia okaże się z później. Dla różnych modeli auta z nadwoziem kombi są średnio droższe (Octavia, Cee’d) lub tańsze (Civic, Focus) od hatchbacków. W salonach wersja kombi jest zawsze droższa (podobnie jak diesel) ale jak się okazuje dla Forda lub Civica na rynku może być więcej aut w nadwoziu kombi ze słabszym wyposażeniem lub większym przebiegiem lub sprowadzonych lub z inną cechą która odbija się na cenie.

#
# Pomocnicza funkcja, przedstawiająca tabelę efektów w bardziej zwartej i czytelnej postaci. Przekształcamy efekty liczone na logarytmach tak by przedstawiały ,,efekt multiplikatywny'' czyli porównanie procentowej ceny aut.
#
opisz <- function(x, filtr="") {
 tt <- data.frame(round(2^x[grepl(filtr, rownames(x)),1,drop=F]*1000)/10, 
       signif = cut(x[grepl(filtr, rownames(x)),4,drop=F], c(-1,0.001,0.01,1), c("**","*","")))
 tt[order(tt[,1]),]
}
 
#
# Wyniki analizy wariancji
# Jak widzimy największy wpływ na cenę auta ma wiek, w drugiej kolejności model auta i typ nadwozia
#
> anova(model <- lm(log(Cena.w.PLN,2)~Model:Nadwozie+wiek, segmentC2))
Analysis of Variance Table
 
Response: log(Cena.w.PLN, 2)
                  Df Sum Sq Mean Sq  F value    Pr(>F)    
wiek               1 5873.4  5873.4 67373.01 < 2.2e-16 ***
Model:Nadwozie    18  706.9    39.3   450.47 < 2.2e-16 ***
Residuals      13399 1168.1     0.1                       
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1 
#
# Referencyjnym poziomem jest Skoda Octavia Kombi
# Wartość w kolumnie ,Estimate' odpowiada mniej więcej temu ile procent średniej ceny 
# Skody Octavii Kombi  stanowi średnia cena danego auta w określonej wersji nadwozia. 
# Czyli np. cee'd kombi jest o 15% tańszy od octavii kombi (przyjmując tę samą utratę 
# wartości z uwagi na wiek), za to Audi A3 kombi jest średnio o 35% droższe niż Octavia Kombi.
#
# Wartość przy zmiennej wiek oznacza że auta średnio tracą około 14% wartości na rok.
# 
> opisz(summary(model)$coefficients)
                                Estimate signif
ModelCivic:NadwozieKombi            69.7       
ModelFocus:NadwozieKombi            70.2     **
ModelC4:NadwozieHatchback           72.9     **
Modeli30:NadwozieHatchback          73.9     **
ModelCee'd:NadwozieHatchback        74.5     **
ModelAstra:NadwozieKombi            75.3     **
ModelFocus:NadwozieHatchback        75.4     **
Modeli30:NadwozieKombi              78.0     **
ModelAstra:NadwozieHatchback        78.5     **
Model308:NadwozieKombi              79.6     **
Model308:NadwozieHatchback          80.6     **
ModelCee'd:NadwozieKombi            86.3     **
ModelOctavia:NadwozieHatchback      93.4     **
ModelGolf:NadwozieKombi             93.6     **
ModelCivic:NadwozieHatchback        96.0     **
ModelGolf:NadwozieHatchback         98.8       
ModelA3:NadwozieHatchback          124.5     **
ModelA3:NadwozieKombi              135.4     **
wiek                                86.0     **

Model 2. Wyposażenie dodatkowe

Opisując transformacje zmiennych napisałem że do zbioru danych dodałem 37 binarnych zmiennych opisujących wyposażenie auta. Zobaczmy, które elementy wyposażenia mają największy wpływ na cenę auta.

Aby zmniejszyć objętość poniższego przykładu przedstawiam wyniki tylko dla wybranych elementów wyposażenia. Cztery elementy wyposażenia najdroższych aut to kseony, ESP, klimatyzacja i elektryczne lusterka. Auta, które w opisie wyposażenia miały wymienione wspomaganie kierownicy lub poduszkę powietrzną są o kilka procent tańsze od aut bez tych elementów w opisie. Nie oznacza to oczywiście, że z dwóch aut podobnych to bez wspomagania kierownicy jest droższe. Oznacza to raczej, że w opisie auta jeżeli pojawia się wspomaganie kierownicy to nie pojawiają się inne elementy jeszcze bardziej zwiększające ceny auta. Należy więc być bardzo ostrożnym interpretując wyniki z modelowania cen.

Poniższy model wyjaśnia już ponad 90% wariancji.

#
# Auta z kseonowymi lampami, klimatyzacją, ESP, elektrycznymi lusterkami są 
# średnio o kilka procent droższe od aut bez tych elementów. 
# Większość elementów wyposażenia nie różnicuje istotnie ceny auta
#
> model <- lm(log(Cena.w.PLN,2)~Model*Nadwozie+wiek+.-kodPocztowy1-kodPocztowy2, segmentC2)
> opisz(summary(model)$coefficients, "TRUE")
                              Estimate signif
wspomaganie.kierownicy        91.4     **
poduszka.powietrzna           94.6     **
welurowa.tapicerka            96.2     **
...
pierwszy.wlasciciel          100.2       
serwisowany.w.ASO            100.5       
bezwypadkowy                 100.7       
przyciemniane.szyby          101.0       
czujnik.deszczu              101.3       
system.nawigacji             101.9      *
tempomat                     101.9     **
bagaznik.na.dach             102.1       
skorzana.tapicerka           102.3      *
podgrzewane.fotele           102.5     **
el..szyby                    102.5      *
alufelgi                     103.0     **
kierownica.wielofunkcyjna    103.1     **
komputer                     103.2     **
klimatyzacja                 103.3     **
el..lusterka                 103.8     **
ESP                          104.3     **
ksenony                      108.2     **

 

Model 3. Lokalizacja, lokalizacja, lokalizacja

Kuszące jest dodać do modelu informację o kodzie pocztowym aby sprawdzić czy miejsce w którym oferowane jest auto istotnie wpływa na cenę ofertową.

#
# Różnice pomiędzy cenami aut są ,,istotne statystycznie''
# Nie jest to jednak duże osiągnięcie, biorąc pod uwagę 13 tysięcy ofert 
# na których przeprowadzamy testowanie.
# Wartość różnic nie jest duża w porównaniu do efektu wieku, modelu czy typu nadwozia.
#
> anova(model <- lm(log(Cena.w.PLN,2)~Model:Nadwozie+wiek+kodPocztowy1+kodPocztowy2+kodPocztowy5, segmentC2))
Analysis of Variance Table
 
Response: log(Cena.w.PLN, 2)
                  Df Sum Sq Mean Sq    F value    Pr(>F)    
wiek               1 5873.4  5873.4 72953.9503 < 2.2e-16 ***
kodPocztowy1      10    7.4     0.7     9.1992 2.489e-15 ***
kodPocztowy2      88   39.0     0.4     5.5087 < 2.2e-16 ***
kodPocztowy5    1091  240.8     0.2     2.7419 < 2.2e-16 ***
Model:Nadwozie    18  604.7    33.6   417.2709 < 2.2e-16 ***
Residuals      12210  983.0     0.1                         
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

 

Model 4. Te wszystkie nieistotne zmienne

Ciekawym eksperymentem może być samodzielne znalezienie innych czynników istotnie różnicujące cenę auta. Szybko jednak się okazuje, że wyniki rozjeżdżają się z intuicją. I jest to za każdym razem efekt niezrównoważonych zmiennych (porównując diesle i silniki benzynowe trudno uciec od tego że diesle mają większy przebieg). Drugi ciekawy problem to szybko rosnąca macierz modelu. Jeżeli uwzględnimy wiek jako zmienna jakościowo i będziemy analizować jego interakcje z kodem pocztowym to jedna interakcja generuje ponad 1000 kolumn do macierzy modeli.

Analiza takich danych jest znacznie ciekawsza niż analiza zależności pomiędzy szerokościami płatków irysów jest też znacznie trudniejsza. Ale też bliższa rzeczywistym problemom.

Więc życzę miłej zabawy!

Plan na kolejny wpis: przedstawić powyższe liczbowe wyniki graficznie.

Ceny używanych aut po raz trzeci

 

W październiku poprzedniego roku i 1 stycznia tego roku zebrałem na bazie serwisu www.otomoto.pl zbiór opisujący cen i wiele dodatkowych parametrów z ofert sprzedaży samochodów używanych (zobacz między innymi te wpisy). Dzisiaj dodaję zbiór danych o cenach samochodów z połowy marca roku 2012. Na podstawie tych trzech pomiarów będziemy mogli się przyjrzeć temu jak się zmieniały ceny używanych aut w przeciągu ostatnich 6 miesięcy.

Do pierwszego zbioru danych dołączyłem kilka analiz statystycznych i wizualizacji. Do drugiego zbioru danych dodałem szczegółowy opis jak takie dane pobierać. Zabrakło mi jednak czasu by przedstawić wyniki analiz statystycznych danych zebranych w styczniu.

Okazało się jednak, że nawet surowe dane mogą być przydatne. W tak zwanym między czasie otrzymałem od trzech osób informację, że ten zbiór danych bardzo im się przydał w projekcie licencjackim. A od jednej osoby otrzymałem nawet napisaną już pracę licencjacką poświęconą różnym technikom analizy danych z przykładami na zbiorze danych o samochodach pobranym z tego bloga.
Super!!!
Więcej takich projektów!
Jeżeli autorzy się zgodzą to podlinkuję ich wyniki do odpowiednich wpisów.

Jeden z częściej pojawiających się komentarzy od osób pracujących na zebranych danych dotyczył braku informacji o typie nadwozia. W poprzednio zbieranych danych typ nadwozia nie był bezpośrednio identyfikowalny.

Mając to na uwadze tym razem listę zmiennych opisujących ofertę sprzedaży auta rozszerzyłem o dwie nowe zmienne. Pierwszą jest typ nadwozia a drugą jest kod pocztowy i nazwa miejscowości z której pochodzi dane ogłoszenie.

Ponieważ ostatnio interesowałem się analizą danych przestrzennych i funkcjami do przedstawiania danych na mapach, więc postaram się w najbliższych dniach pokazać co ciekawego można zrobić z cenami samochodów używanych mając też informacje o miejscu złożenia oferty sprzedaży.

Skrypt wczytujący do programu R dane zebrane w marcu 2012 znajduje się tutaj.

Dane w postaci tekstowej i binarnej znajdują się w tym katalogu.

Jeden zły rysunek jest wart 1000 słów … korekty

 

W poniedziałek w tym wpisie napisałem o konkursie na wyśledzenie złej wizualizacji. Do tej pory rozdałem już cztery nagrody, dziś przedstawię jedno z ciekawszych znalezisk.

Rzecz dotyczy artykułu z serwisu interia.pl ,,Drożejąca energia podnosi koszty utrzymania mieszkań’’. Na wstępie możemy przeczytać

,,Inflacja niespodziewanie podniosła się w październiku do 4,3 proc. Ceny związane z utrzymaniem mieszkania rosły natomiast w takim samym tempie jak we wrześniu, czyli aż o 6,7 proc. rok do roku. Miesięczne koszty utrzymania mieszkania zajmowanego przez czteroosobową rodzinę przekroczyły już 849 zł.’’

Pomijam już czepianie się słówek typu ,,niespodziewanie” (dla kogo było to niespodziewane?), bo wszystko to przyćmiewa drugi obrazek dołączony do tego artykułu.

 

Niewątpliwie wykres pokazuje szybki wzrost z 205 pln do 212 pln w ciągu 10 miesięcy ale:

  • wrażenie szybkiego wzrostu wywołane jest skalą na osi OY, w skali 10 miesięcy na osobę wzrost wynosi 7pln,
  • daje to około 4% wzrostu w skali rocznej, a więc wzrost kosztu utrzymania mieszkania jest niższy niż ta niespodziewana październikowa inflacja i niższy od średniej rocznej inflacji (na rok 2011 inflacja to 4,3% według GUS),
  • oś OY jest tak dziwnie zmieniona, że jest wręcz anegdotyczna,
  • poziome ,,pomocnicze” linie przebiegają w trudnych do ustalenia wartościach, nie wiem czy słowo ,,pomocnicze’ jest tu odpowiednie.

Tak więc ten rysunek do artykułu nakręcającego strach przed rosnącymi cenami utrzymania mieszkania pasuje jak kwiatek do kożucha.

Czasem warto zmienić oś OY, ale zazwyczaj robi się to gdy porównuje się dwie krzywe i chce się uwypuklić różnice pomiędzy krzywymi lub gdy chce się przedstawić zmiany w dynamice krzywej. Przedstawiając na wykresie wartości bezwzględne lepiej pozostawić na osi OY punkt 0 aby długość lub wysokość odpowiadały tym wartościom bezwzglednym.

Ceny używanych aut po nowym roku a prosty pająk sieciowy

Trzy miesiące temu opisywałem zbiór danych o ofertach sprzedaży samochodów z serwisu otomoto.pl (zobacz tutaj). Po kwartale ponownie zebrałem informacje o ofertach sprzedaży. Porównując te dwa zbiory będzie można sprawdzić jak zmieniają się ceny różnych modeli w odpowiedzi na podwyższoną akcyzę na olej napędowy. Kolejne interesujące pytanie to globalna zmiana cen aut używanych w ,,czasach kryzysu’’. Interesujący będize trend zmian w liczbie ofert samochodów sprowadzanych z zagranicy. Efekt starzenia się auta, z dnia na dzień auto staje sie o rok starsze, ciekawe czy dla aut używanych wiek w latach ma duzy wpływ na cenę auta.

Nowy zbiór danych jest dostępny w postaci csv i Rdata pod tym adresami [csv 80Mb], [Rdata 5,5 MB].

Skrypt wczytujący dane bezpośrednio z Internetu do R znajduje się tutaj.

 

Ponieważ ostatnio pojawiały się pytania o skrypty użyte do parsowania stron interntowych i zbierania automatycznego danych, więc do tych danych dołączam wszystkie skrypty potrzebne do ich zebrania i przetworzenia. Poniżej krótko je opiszę. Wykorzystuję tutaj głównie Perla i wyrażenia regularne pozwalające na łatwe i szybkie parsowanie tekstu. Z pewnością istnieją lepsze (łatwiejsze) sposoby parsowania stron HTML, chętnie usłyszę sugestie.

W moim rozwiązaniu proces zbierania danych jest dwuetapowy. Pierwszy etap to przejrzenie hierarchicznej struktury ofert sprzedaży samochodów oraz zapisanie z każdej oferty wybranych pól. Dodatkowo należy zatroszczyć się o to by to samo auto nie zostało dwukrotnie dodane do listy aut. Ponieważ parsowanie 200 tys ofert trochę trwa, a tym czasie do serwisu dodawane są nowe oferty, więc potrzebna jest dodatkowa tablica haszująca pamiętająca, które auta zostały już przetworzone. Skrypt perlowy, który wykorzystałem w tym celu znajduje się tutaj [skrypt perl]. Plik wynikowy, z zebranymi danymi znajduje się tutaj [surowe dane po pierwszym etapie 140MB].

Ponieważ dla różnych ofert sprzedaży  przedstawiane są różne charakterystyki, niektórych opisów brakuje, niektóre parametry są w różnych formatach, dlatego też w drugim kroku wykorzystuję skrypt R obrabiający surowe dane i przekształcający je do postaci tabelarycznej, łatwiejszej w obróbce. Przy okazji cena aut w walucie przeliczana jest na PLN, liczona jest pojemność skokowa, moc i inne parametry, które w surowych danych sa zapisane w formacie tekstowym. Skrypt użyty do transformacji znajduje sie tutaj [skrypt r], a plik wynikowy znajduje się tutaj [plik csv].

Smacznego!

 

Gdzie można zarobić? Kto może zarobić?

Tym wpisem mam nadzieję, że zakończę pokaźną serię wizualizacji danych z Diagnozy Społecznej i znajdziemy kolejne ciekawe dane.

Jakiś czas temu pojawiła się w komentarzach sugestia, by sprawdzić jak na dochody wpływa miejsce zmieszkania, wykształcenie, zawód, stan cywilny itp. Nie każdą z tych rzeczy łatwo sprawdzić na danych z Diagnozy, np. frakcja osób, które podały zawód jest dosyć nieduża. Ograniczymy się więc do zależności, które możemy badać na dużych grupach ankietowanych

Widzieliśmy już, że dochody zależą istotnie od wieku i od płci. Aby usunąć wpływ tych zmiennych poniżej wykonamy analizą tylko dla pracujących mężczyzn w wieku od 30 do 45 lat.

Zaczniemy od związku miejsca zamieszkania z dochodami. Prosta dwukierunkowa analiza wariancji pokazuje, że dochody zależą od województwa i od wielkości miasta i również, że ta zależność nie jest addytywna. Tzn. wpływ/efekt wielkości miasta jest różnych w różnych województwach. Wyników analizy wariancji nie zamieszczam ale można ją odtworzyć z skryptu w R. Co ciekawe otrzymujemy podobne wyniki bez względu na to czy analizujemy dochody zlogarytmowane czy nie, czy użycjemy transformacji Boxa Coxa czy nie.

Wielkość miasta w którym pracuje akietowany podzielono na trzy grupy: 'wieś’, do 200 tys’ i 'powyżej 200tys’. W oryginalnych danych tych grup jest więcej, ale połączone zostały te najbardziej do siebie podobne w celu otrzymania możliwie czytelnych wykresów. Województw jest 16, w czterech z nich nie ma miast o wielkości powyżej 200tys mieszkańców, stąd brakujące elementy ponizej.

Na poniższym wykresie zaznaczono dla każdego województwa rozkład dochodów netto w rozbiciu na wielkość miasta zamieszkania. Kolory odpowiadają wielkości miasta. Jasny/blady pasek odpowiada rozpiętości średnich dochodów 50% zarabiających osób z danej lokalizacji, lewy brzeg odpowiada dolnemu kwartylowi, prawy brzeg górnemu kwartylowi. Czyli możemy potraktować ten pasek jako reprezentację najbardziej typowych dochodów. (Uwaga! oś logarytmiczna). Kropką zaznaczono medianę dochodów a krzyżykiem średnią. Średnia potrafi być znacznie wyższa niż mediana, ale tak to już jest z dochodami. Po prawej stronie wykresu podano dla każdego województwa informację o liczbie osób na podstawie której konstruowany jest ten wykres (odpowiednio na wsi, małym mieście, dużym mieście).

Co ciekawego tu widać? Zazwyczaj im większe miasto tym wyższe dochody. Stolica znacząco odstaje od pozostałych lokalizacji. Ale są też wyjątki od tej reguły. W województwie Podlaskim duże miasto (czyli Białystok) charakteryzuje się mniejszymi dochodami niż otaczające go małe miasta i wsie (region żyje z turystyki). W innych województwach najniższe dochody mają osoby mieszkające na wsi.

 

Poniżej przedstawiamy te same dane ale zamieniając kolejność zmiennych, tym razem pokazemy obok siebie województwa. To samo województwo jest oznaczone tym samym kolorem, a kolejność odpowiada średniemu dochodowi. W grupie dużych i średnich miast najwyższe dochody mają osoby mieszkające w województwie Mazowieckim. Ale juz  w kategori wieś najlepiej zarabiają mieszkańcy Pomorza. Przy czym średnia bardzo odstaje od mediany, więc nie wszystkim mieszkańcom tego województwa się tak świetnie powodzi.

 

Jako uzupełnianie tematu poniżej przedstawiam zależności pomiędzy stanem cywilnym a dochodami oraz pomiędzy liczbą lat edukacji a dochodami. Miło zobaczyć piękną korelacje pomiędzy liczbą lat nauki a dochodami.

 

Jakie będą ceny mieszkań za 12 miesięcy?

Przeglądałem dzisiaj stare wydania Rzeczpospolitej, i znalazłem ciekawy wykres w kwietniowym wydaniu (http://www.rp.pl/galeria/8,2,641431.html).

Deweloperom zadano pytanie czy ceny mieszkań wzrosną czy spadną w przyszłym roku. Porównano wyniki z odpowiedzi z czerwca i grudnia roku 2010. Odpowiedzi przedstawiono za pomocą następującego wykresu.

 

Ponownie, najdziwniejsze w tym wykresie jest to, że na pierwszy rzut oka nie widać czy i jak odpowiedzi się zmieniły. Najbardziej w oczy rzuca się para dwóch czerwonych i dwóch zielonych słupków. Nie wiedzieć czemu czerwone odpowiadają grudniowi a zielone czerwcowi.

Do pokazywania uporządkowanych zmiennych jakościowych lepsze są wykresy paskowe. Pozwalają ona na łatwe porównywanie skumulowanych liczebności. Przedstawmy więc te dane co powyżej za pomocą prostego wykresu paskowego.

Myślę, że po spojrzeniu na ten wykres nikt nie ma wątpliwości że opinie pytanych deweloperów zmieniły się znacznie przez te 6 miesięcy.

 

Zmiany zamożności Polaków

Kontynuujemy analizy danych z badania Diagnoza Społeczna. Średnia pensja w Polsce rośnie szybciej nawet niż inflacja. Można więc uważać, że jest coraz lepiej.

Ten i kolejny wpis powstał ponieważ po pierwsze wyniki są ciekawe, a po drugie, ponieważ będzie okazja wprowadzić kolory w analizie gradacyjnej.

W kwestionariuszu dla gospodarstw piąte pytanie dotyczy sposobu gospodarowania dochodem, czy na wszystko wystarcza pieniędzy, czy wystarcza ale przy oszczędnym życiu, czy brakuje na coś. Będziemy poniżej porównywać odpowiedzi pomiędzy latami 2005 (kolumna „cl7”) i 2001 (kolumna „fL5”). Do porównania odpowiedzi w tych dwóch rocznikach wykorzystamy analizę gradacyjną.

Kilka linii kodu w R

# czy wystarcza pieniedzy w roku 2005 i 2011
zb1 = rev(table(factor(diagnozaGospodarstwa2011[,"fL5"])))
zb2 = rev(table(factor(diagnozaGospodarstwa2011[,"cl7"])))
 
plotGradeStat(t(t(zb2)), t(t(zb1)), osX="rok 2005", osY="rok 2011", skala=c(0.01,0.5), cutoff=0.011,uporzadkujMalejaco=F)

i mamy następujący wykres.

Etykiety można by skrócić, ale póki są czytelne nie walczyłem z nimi. W porównaniu z rokiem 2005 w roku 2011 ubyło o około jedną trzecią osób, którym wystarcza co prawda na najtańsze jedzenie, ale nie wystarcza na inne potrzeby. Liczba osób, którym wystarcza i jeszcze oszczędzają wzrosła trzykrotnie.

Ceny mieszkań spadły o 20%!!! albo wzrosły o 5%!!! albo się nie zmieniły!!!

Ostatnio w gazetach pojawiło się kilka artykułów w których aby przyciągnąć więcej czytelników zastosowano bardzo głupie tytułu w stylu ,,Realne ceny mieszkań spadły/ mieszkania potaniały o 25% także w Warszawie”. Artykuły np. [gazeta na podstawie open finance], [raport oferty net], [wyborcza biz finanse] mają tą cechę wspólną, że podają liczby bez żadnej refleksji na temat tego jak liczby uzyskano i jakie ma to znaczenie. W każdym z przypadków badano zmianę ceny w trakcie ostatnich czterech lat (czyli od tzw górki 2007) tak więc i poniższe rozważania oprzemy na tym okresie.

Celem tego wpisu jest nie polemika z tym co to znaczy realna cena mieszkania, ani z tym czy spadek wynosił 25% czy nie, ale z tym, że jeżeli nie porównujemy ceny tego samego mieszkania to mówiąc o zmianie wartości należy dokładnie opisać zmianę wartości czego liczymy, bo wyniki mogą być bardzo różne. Dla każdej dzielnicy Warszawy na 8 sposobów policzymy jak zmieniały się ceny przez ostatnie 4 lata. I w każdym przypadku otrzymamy 8 różnych liczb opisujących zmianę ceny.

We wczorajszym wpisie dyskutowaliśmy różnice pomiędzy cenami m2 w dużych i małych mieszkaniach różnych dzielnic. Pisząc o strukturze koszyka pokazaliśmy, że badanie ,,tak po prostu” średniej mieszkań sprzedanych/oferowanych nie ma sensu jeżeli nie uwzględnimy jakie mieszkania (powierzchnia/lokalizacja/stan itp) wchodzą w skład koszyka. Poniżej będziemy podawać różne liczby ale nie po to by dowieść że cena zmieniła się o X%, ale by zaznaczyć jakie problemy wiążą się z analiza zmiany ceny. Wszystkie ceny to ceny ofertowe, nie pokrywają one całego rynku i pewnie nie są całkowicie reprezentacyjne. Nie mniej powinno być fajnie popatrzeć na obrazki.

Przyjrzyjmy się dzielnicy Żolibórz. Oś OY jest w skali logarytmicznej, pionowe szare linie oznaczają koniec roku. Na poniższym wykresie dla każdego miesiąca począwszy od września 2007 wyznaczamy wykres pudełkowy opisujący zmiany cen w danym miesiącu. W środku pudełka czarną kropką oznaczamy medianę cen w danym miesiącu. Następnie czterema liniami oznaczamy następujące trendy:

* linią czerwoną zaznaczamy trend liniowy wyznaczony na bazie wszystkich obserwacji używając regresji odpornej (funkcja rlm() w R), regresja odporna ma nas uchronić przed wpływem pojedynczych obserwacji odstających, nie uchroni nas jednak przed obciążeniem wynikającym z tego, że większość ofert sprzedaży dotyczy ostatniego roku.\ i to ten okres będzie głównie wpływał na ocenę trendu liniowego. W nagłówku wykresu podano cztery procenty, pierwszy z nich opisuje o ile ten trend liniowy się zmienił prze ostatnie cztery lata (-15.6%).

* linią niebieską zaznaczamy trend liniowy wyznaczony na bazie median cen używając regresji odpornej. Czyli najpierw wyznaczamy mediany cen w każdym miesiącu a później wyznaczamy trend. Tym razem trend nie jest już dominowany przez ceny z ostatniego roku. W nagłówku wykresu druga liczba to zmiana tego trendu przez ostatnie 4 lata (-7.6%, czyli około połowa poprzedniej liczby),

* linia zielona i trzecia liczba odpowiadają trendowi wyznaczonemu za pomocą lokalnego wygładzania. Ponieważ używanie trendu liniowego wydaje się być słabo uzasadnione, porównujemy trend liniowy z trendem wyznaczonym przez funkcję loess z parametrami rodzina = symmetric, span = 2/3, stopień wielomianu = 1. Oczywiście dla innych parametrów otrzymalibyśmy inne wygładzenie, te jednak wygląda w miarę dobrze. Trzecia liczba nagłówku opisuje o ile się zmieniła ocena trendu we wrześniu 2011 w stosunku do września 2007 (-11.1%).

* linia fioletowa łączy medianę ceny m2 mieszkań ferowanych we wrześniu 2007 z medianą ceny m2 mieszkań oferowanych we wrześniu 2011. Ponieważ danych o sprzedaży we wrześniu 2007 jest niewiele, ta linia wykazuje spora zmienność pomiędzy dzielnicami. Dla Żoliborza zmiana medianowej ceny m2 pomiędzy wrześniem 2007 a wrześniem 2011 to (-3.6%).

 

Mamy więc cztery liczby, począwszy od spadku niecałych 4% w cztery lata do spadku o ponad 15%. A to jeszcze nie wszystko. Te same analizy możemy zrobić uwzględniając strukturę wielkości mieszkań. Odrzućmy więc mieszkania najmniejsze i największe (te największe najwięcej straciły) i zajmujmy się tylko cenami m2 mieszkań o powierzchni od 49 do 68m2. Poniżej odpowiadający im wykres z oznaczeniami jak powyżej,

Jak widzimy ograniczając się tylko do segmentu mieszkań o średniej powierzchni otrzymujemy 4 inne trendy i cztery inne % opisujące zmianę tych trendów.

Która z tych 8 liczb lepiej opisuje zmianę cen mieszkań? Oczywiście to zależy jaki aspekt zmiany chcemy analizować. Ceny mieszkań zmieniają się w sposób złożony. Mnie najbardziej podoba się  trend lokalnie wygładzany, nie zakłada on liniowości tak jak linie czerwone i niebieskie a jednocześnie czerpie informacje z prawie wszystkich danych (w przeciwieństwie do linii fioletowej która patrzy tylko na skrajne miesiące).

W przypadku trendu nieliniowego nadużyciem jest stwierdzenie, że ceny spadały o X%, ponieważ w różnych okresach zachowywały się różnie.

Poniżej wyniki dla wszystkich dzielnic, pierwszy wykres bazuje na wszystkich obserwacjach, drugi dotyczy tylko mieszkań o średniej wielkości.

 

 

Czym się różnią ceny mieszkań na Żoliborzu od cen mieszkań na Bemowie

Dzisiejszy wpis to przygotowanie gruntu do jutrzejszego, w ktorym rozliczymy sie ze zmianami cen mieszkan. Od jakiegos czasu na różnych stronach można znaleźć artykuły o nazwach ”realne ceny mieszkań spadły o X %’’ (dobrze że realne, co to by byly gdyby spadaly ceny nierealne). Celem tego i kolejnego wpisu jest pokazanie że zmianę ceny można liczyć na wiele różnych sposobów otrzymując wiele różnych wyników. Więc podanie zmiany nie mówiąc dokładnie jak była ona liczona to zwykłą propaganda.

Będziemy korzystać ze zbioru danych mieszkaniaKWW2011, przeanalizujemy tylko ceny z miasta Warszawa dla mieszkan o powierzchni do 300m2. Na początek przyjrzymy się dwóm dzielnicom. Jednej w której mieszkam (Bemowo) i jednej w której ceny się ciekawie zachowują (Żoliborz).

Przedstawimy zmianę trendu ceny mieszkań w czasie w rozbiciu na trzy grupy wielkości mieszkań. Kwantyle rzędu 1/3 i 2/3 z rozkładu wielkości mieszkań wynoszą 49m2 i 68m2, wiec będziemy analizować cenę m2 w grupie mieszkań w trzech grupach: do 49m2, w grupie mieszkań dużych o powierzchni powyżej 68m2 i w grupie pozostałych – średnich co do wielkości mieszkań.

Na poniższym wykresie każdy punkt to jedna oferta sprzedaży. Linia zielona, różowa i niebieska oznaczają lokalne wygładzenie wielomianowe dla ceny m2 dla różnych grup wielkości mieszkań, a czarna linia przerywana to globalny trend w cenach mieszkań bez uwzględnienia struktury mieszkań. Struktura jest istotna ponieważ hipotetycznie, jeżeli mieszkania duże maja niższa cene za m2, i przed czterema laty mieszkań dużych bylo sprzedawanych mniej niż teraz to zaobserwujemy zmiane w średniej cenie nie ze względu na rzeczywistą zmianę ceny ale ze wzgledu na zmianę struktury sprzedawanych mieszkań. Podobnie z analizą cen w Warszawie. Jeżeli w tym roku sprzedaje sie więcej mieszkań na obrzeżach Warszawy niż przed czterema laty (z roku na rok buduje się średnio coraz dalej bo tam jeszcze jest miejsce) to zmiana średniej ceny będzie zwiazana z tym ze w koszyku jest coraz więcej mieszkań dalekich od centrum a wiec tańszych.

No dobrze, to tyle tytułem teorii a teraz obrazki dla dwoch obiecanych dzielnic.

 

Dla Żoliborza jak widzimy ceny m2 dla mieszkań dużych sa wyzsze niz dla malych, moze byc to zwiazane ze duze mieszkania to juz apartamenty dlatego cenę ich m2 ciezko porównywać z cena m2 mieszkania o standardowym wykonczeniu. Pdobnie beda zachowywaly sie mieszkania w Śródmieściu. Te apartamenty tez najbardziej straciły na wartości. Na Bemowie jest inaczej. Nie buduje sie raczej apartamentow w dzielnicy sypialni wiec tutaj to male mieszkania maja wyższą cenę za m2. W obu przypadkach ceny maja tendencje do spadania ale w kazdej kategorii tempo spadku jest inne.

 

Poniżej prezentujemy wykresy dla wszystkich dzielnic Warszawy.