作者:張土豆,R語言中文社區專欄作者
博客專欄:
https://www.hellobi.com/u/tudouZhang
在最初接觸數據分析時,常常把數據文件一股腦兒導入,接著開始嘗試各種模型,目的就是為了快速得到分析預測結果。但這樣倉促操作的後果並不像想像中高效,很多次在模型結果差的離譜時,回過頭才發現原來數據中的很多「不良」記錄也被用到的分析過程中。有時回過頭再仔細推敲一遍時,很多特徵之間的關係是顯而易見的,然而我卻在運用模型時沒有重點關注。
我開始思考,難道沒有一組「套路」可以操作?讓探索數據的過程更有章法。
在走了很多彎路之後,我學習到了「探索性數據分析」(EDA)這樣一個概念。第一次接觸在Coursera網站的這門ExploratoryData Analysis課程裡,這是一整套「數據分析課程」的其中一門,主要介紹了如何運用R語言對數據進行探索性的發現,將數據用簡單的圖示表示以便於更好的發現數據的潛在特徵。完成課程之初,並不以為這是數據分析過程中一個關鍵的步驟,在做項目時只是簡單的跑跑summary語句大概看看分布,之後還是我行我素。
直到最近在Kaggle上看了越來越多大神們的kernels,才猛然意識到EDA並不是一個可有可無的過程,而是進行建模分析之前的相當關鍵的步驟,它是幫助你熟悉數據並且探索數據的過程。在EDA的過程中,你能探索到越多的數據特性,你在建模的過程中就越高效。
在此決定把EDA過程總結並規範化,以便於自己和大家在未來進行探索性數據分析時有步驟可依。為了方便說明,會用到Kaggle上最近較火的Zillow房產數據分析比賽。
讀取數據通常情況下,用於導入數據文件的方法有三類。分別是base R 中的read.csv(),readr library read_csv() 和data.table library 中的fread()。
在進行一些小型數據分析時,base R和readr library 足夠應付。但在處理的數據量越來越大時,最高效也最常用的是fread()。在讀入數據時,fread()會自動檢測各類數據,如sep,colClass和nrows等等。並且現在大量的數據都是機器產生的結構化數據,fread()能充分應付這類大型數據,為之後的數據分析開好頭。
library(data.table)train <-fread("train_2016_v2.csv")properties_2016 <-fread("properties_2016.csv")
基本數據統計信息導入數據之後,就需要對數據進行全方位的查看。在接觸很多項目之後,我發現無論之前看過再多對數據的描述文檔,在真實「摸到」數據之前,其實腦海中對於數據的認知都是非常表面的。那麼數據到手之後,怎麼開始上手?
第一步,看數據。用head()語句首先查看數據結構。head()會列印出前6行數據。假如想要一次性看到更多數據,head()提供了可以設置行列的參數。
head(train)
parcelid logerror transactiondate
1: 11016594 0.0276 2016-01-01
2: 14366692 -0.1684 2016-01-01
3: 12098116 -0.0040 2016-01-01
4: 12643413 0.0218 2016-01-02
5: 14432541 -0.0050 2016-01-02
6: 11509835 -0.2705 2016-01-02
head(train,10)
也許有不走尋常路的同學,想要從最後幾行數據來認識結構,R提供了tail(),操作和head()一樣。
第二步,查看統計數據。統計數據是指數據的最大最小值等。對於數值類型的數據,統計數據可以讓我們快速了解到這個數據的分布和均值如何,對數據範圍做到心裡有數。對於字符類型的數據,可能需要先轉換類型,再得到統計結果。
summary(train)
parcelid logerror transactiondate
Min. : 10711738 Min. :-4.60500 Length:90275
1st Qu.: 11559500 1st Qu.:-0.02530 Class :character
Median : 12547337 Median : 0.00600 Mode :character
Mean : 12984656 Mean : 0.01146
3rd Qu.: 14227552 3rd Qu.: 0.03920
Max. :162960842 Max. : 4.73700
train$transactiondate <- as.Date(train$transactiondate)summary(train)
parcelid logerror transactiondate
Min. : 10711738 Min. :-4.60500 Min. :2016-01-01
1st Qu.: 11559500 1st Qu.:-0.02530 1st Qu.:2016-04-05
Median : 12547337 Median : 0.00600 Median :2016-06-14
Mean : 12984656 Mean : 0.01146 Mean :2016-06-11
3rd Qu.: 14227552 3rd Qu.: 0.03920 3rd Qu.:2016-08-19
Max. :162960842 Max. : 4.73700 Max. :2016-12-30
第三步,查看缺失數據(missing values)。數據集中通常會有一些缺失或不良數據,造成這些問題的理由很多樣。一些是源於人為的數據錄入問題,例如用戶的性別未填寫。或者有些是在從其他系統導出數據時產生的缺失。面對這些問題,我們在使用數據時應該儘量避免選擇缺失量過大的屬性。所以在分析之前,我們需要掌握數據的缺失情況。
通常採取的操作是統計出每一項屬性中缺失數據所佔比例,然後以圖像簡單直接的呈現出來。我最常用的就是柱狀圖,把排序後的缺失率結果展示出來。因此在之後進行分析決策時,那些缺失率相對較高的特徵應該被排除在外。
color:blue">library(dplyr) missinga_values <- properties_2016 %>%summarise_each(funs(sum(is.na(.))/n()))missing_values <- gather(missinga_values,key ="feature",value = "missing_percent")missing_values %>% ggplot(aes(x =reorder(feature,missing_percent),y = missing_percent)) + geom_bar(stat ="identity",fill ="light blue") + theme_bw() + coord_flip()
對於有些重要的變量,我們希望了解它的分布組成。比如一組數據的時間分布或者一組數值的區間分布,這些都屬於這個單一變量的變化。
在Zillow這個項目中,交易產生的時間和每筆交易的誤差是我們想要重點研究的。對於這類分析,我們可以畫出數據的直方圖或者密度圖。
train %>% ggplot(aes(x = logerror)) + geom_histogram(bins = 400, fill = "red")++ theme_bw() + theme(axis.title = element_text(size = 16),axis.text = element_text(14))++ ylab("Count") + xlab("Logerror") + coord_cartesian(x=c(-0.5,0.5))
train %>% ggplot(aes(x = logerror)) + geom_density(fill = "steelblue",color = "steelblue") + coord_cartesian(x = c(-0.5,0.5))
對於交易時間分布也是類似,將數據簡單組合歸類之後,畫出分布直方圖。
train %>% + mutate(year_month = make_date(year = year(transactiondate), month= month(transactiondate))) %>% + group_by(year_month) %>% + count() %>% + ggplot(aes(x=year_month,y= n)) + geom_bar(stat= "identity", fill = "lightblue") + geom_vline(aes(xintercept = as.numeric(as.Date("2016-10-01"))),size = 3) + labs(y = "Count")
多變量分析是統計學裡一個重要的方法,也是單變量分析的延伸。幾乎我們想在所面臨的所以數據分析項目都是多變量的,也就是說問題涉及的因素是多種多樣的。這篇文章主要介紹的是探索性分析,所以就只介紹幾個高效好用的多變量分析方法。
關聯性分析當數據只是一列列數字時,我們很難發現各個變量之間的聯繫,這時候最好的就是對整體做一組關聯性分析,然後將結果用圖像呈現出來。用corrplotlibrary中的cor()可以幫我們求出變量之間的相關矩陣,再做得關係矩陣圖。(關於關係矩陣圖的屬性還有很多介紹,需要的朋友可以查閱corrplotpackage)
library(corrplot)cnt_vars <- c('bathroomcnt', 'bedroomcnt', 'calculatedbathnbr', 'finishedfloor1squarefeet', 'calculatedfinishedsquarefeet', 'fireplacecnt','fullbathcnt', 'garagecarcnt', 'garagetotalsqft', 'roomcnt', 'threequarterbathnbr', 'unitcnt', 'numberofstories', 'logerror')cor_matrix <- cor(dtrain[,..cnt_vars],use = 'pairwise.complete.obs')
corrplot(cor_matrix,insig = "blank")
通過corrplot,我們可以清晰的發現哪些參數之間是正相關或負相關,在之後的建模分析中更有針對性。
組合分析根據前幾步的初步學習,我們對數據集有了一個基本的了解,接下來可以進一步探查變量之間的關係。通常會有幾組目標組合,想要探查或者驗證我們的猜測是否準確。此時我們就需要提出問題,然後通過做圖將他們展示出來,這樣可以讓我們更容易發現數據規律以及一些我們容易遺漏的情況。
train %>% mutate(year_month = make_date(year = year(transactiondate), month= month(transactiondate))) %>%group_by(year_month) %>%summarize(mean_logerror = mean(logerror)) %>% ggplot(aes(x= year_month, y = mean_logerror)) + geom_line(size =1.5, color = "lightblue") + geom_point(size = 5, color = "lightblue")
cor_temp %>% group_by(yearbuilt) %>% summarize(mean_logerror = mean(logerror),n()) %>% ggplot(aes(x = yearbuilt,y= mean_logerror))+ geom_smooth(color = "grey40") + geom_point(color = "red") + ggtitle("Relationship between Built_year and logerror") +labs(x="Built year",y="Mean logerror") + coord_cartesian(ylim = c(0,0.075)) + theme_bw()
以上就是我在不斷摔跤試錯過程中總結的一些套路,大家學會了麼?歡迎大家相互交流,讓我們在數據分析的道路上共同進步!
微信回復關鍵字即可學習
回復 R R語言快速入門免費視頻
回復 統計 統計方法及其在R中的實現
回復 用戶畫像 民生銀行客戶畫像搭建與應用
回復 大數據 大數據系列免費視頻教程
回復 可視化 利用R語言做數據可視化
回復 數據挖掘 數據挖掘算法原理解釋與應用
回復 機器學習 R&Python機器學習入門