sampleing

DataSicnce No85 Data visualization サンプリングやアンサンブル平均によってデータ量を減らして可視化できる

背景

大量のデータを扱う場合、そのまま可視化を行うと処理に時間がかかることがある。そこでデータ分析の初期段階では大量のデータをサンプリングや平均により、データ量を減らすことで、探索的な可視化・分析が可能となる。その中でデータのおおよその概要を掴むことが重要である。 # 全データをプロットすると見づらいのでサンプリング・平均をとることもあるのか?見づらい場合ってグラフ構造や対応分析をプロットする場合を思いつくけれども、それは出現頻度が上位N件とかの枝刈りが多く、サンプリングではない気がする。。

項目の意味

サンプリング

サンプリングとは任意のデータセット(母集団)から標本を抜き出すこと。
無作為に抽出したり、層化して抽出する方法などがある。

アンサンブル平均・時間平均

アンサンブル平均とは、同じ条件で測定されたいくつかのグループの測定値の平均をとること。時間平均とは、特定のグループにおいて測定値の時間的な平均をとること。
# A君、B君、C君の1,2,3学期の点数
df <- data.frame(
  A=as.integer(runif(3, min = 0, max = 100)),
  B=as.integer(runif(3, min = 0, max = 100)),
  C=as.integer(runif(3, min = 0, max = 100))
)
head(df)
##    A  B  C
## 1 61 37 42
## 2  8 75 40
## 3 39 30 56
# アンサンブル平均 1学期のアンサンブル平均の点数
mean(as.matrix(df[1,]))
## [1] 46.66667
# 時間平均 A君の時間平均の点数
mean(df$A)
## [1] 36

問題

  • 実際のデータを用いてサンプリング・アンサンブル平均の可視化を行ってみる
    • 下記の例
    • もっと簡単でも良い?
  • サンプリングを行う際の注意点を述べよ
    • データを減らしすぎると母集団のとは違う性質になる可能性あり # どの程度が適切なのだろうか
  • ブートストラップ法の利点を述べよ
  • アンサンブル平均と時間平均の違いを述べよ

データの読み込み

今回は気象庁の気温データを利用した。
場所:函館、東京、熊本 期間:2015年8月6日から2016年8月6日まで
データ粒度:時別値
tokyo.hours <- read.csv("~/Projects/DataSicnce/sampling/data/tokyo.hours.csv", quote="")
# datatimeがカテゴリ型になっているのでPOSIXct(datetime)型に変換
tokyo.hours$datetime <- as.POSIXct(tokyo.hours$datetime, "%y/%m/%d %h:%m:%s")
tokyo.hours$location <- "tokyo"

hakodate.hours <- read.csv("~/Projects/DataSicnce/sampling/data/hakodate.hours.csv", quote="")
hakodate.hours$datetime <- as.POSIXct(hakodate.hours$datetime, "%y/%m/%d %h:%m:%s")
hakodate.hours$location <- "hakodate"

kumamoto.hours <- read.csv("~/Projects/DataSicnce/sampling/data/kumamoto.hours.csv", quote="")
kumamoto.hours$datetime <- as.POSIXct(kumamoto.hours$datetime, "%y/%m/%d %h:%m:%s")
kumamoto.hours$location <- "kumamoto"

japan.hours <- union(union(tokyo.hours, hakodate.hours), kumamoto.hours)
head(japan.hours)
##              datetime temperature quality num location
## 1 2016-08-06 22:00:00        28.3       8   1 kumamoto
## 2 2016-08-06 21:00:00        28.6       8   1 kumamoto
## 3 2016-08-06 20:00:00        28.7       8   1 kumamoto
## 4 2016-08-06 19:00:00        30.0       8   1 kumamoto
## 5 2016-08-06 18:00:00        30.1       8   1 kumamoto
## 6 2016-08-06 16:00:00        32.4       8   1 kumamoto
summary(japan.hours)
##     datetime                    temperature        quality     
##  Min.   :2015-08-06 01:00:00   Min.   :-11.00   Min.   :1.000  
##  1st Qu.:2015-11-05 18:45:00   1st Qu.:  7.90   1st Qu.:8.000  
##  Median :2016-02-05 12:30:00   Median : 15.50   Median :8.000  
##  Mean   :2016-02-05 12:30:00   Mean   : 14.69   Mean   :7.999  
##  3rd Qu.:2016-05-07 06:15:00   3rd Qu.: 21.70   3rd Qu.:8.000  
##  Max.   :2016-08-07 00:00:00   Max.   : 36.40   Max.   :8.000  
##                                NA's   :2                       
##       num      location        
##  Min.   :1   Length:26424      
##  1st Qu.:1   Class :character  
##  Median :1   Mode  :character  
##  Mean   :1                     
##  3rd Qu.:1                     
##  Max.   :1                     
## 

そのまま可視化

# 全データ
ggplot(japan.hours, aes(x=datetime, y=temperature)) + geom_point() + geom_smooth(span=0.3)
# 地点別
ggplot(japan.hours, aes(x=datetime, y=temperature, color=location)) + geom_point() + geom_smooth(span=0.3, color="black") + facet_wrap(~location)

そのまま散布図を書くと一日あたり24個(1時間ごと)のデータがある。データ分析の初期段階からすべてのデータを使うと処理に時間がかかることが多い(1回実行するのに1時間もかかる実験は探索的にデータを見ることができない)。そこで①サンプリングをしてデータを減らす、②粒度を時間単位ででなく一日単位にする、の2点をやってみよう。

サンプリングによるデータ削減

# sample_fracにより10%のデータ量にする
japan.hours.10par <- sample_frac(tbl = japan.hours, size = 0.1)
# 全データ
ggplot(japan.hours.10par, aes(x=datetime, y=temperature)) + geom_point() + geom_smooth(span=0.3)
# 地点別
ggplot(japan.hours.10par, aes(x=datetime, y=temperature, color=location)) + geom_point() + geom_smooth(span=0.3, color="black") + facet_wrap(~location)

全データからランダムに10%にデータを削減した。この場合でもおおよそ元データと同様の傾向を示しており、処理も軽く、探索的な分析フェーズにはこちらを使うとさくさくできる。

アンサンブル平均によるデータの要約

japan.hours$date <- as.Date(format(japan.hours$datetime, "%Y/%m/%d"))
japan.summarize.hours <- 
  dplyr::group_by(japan.hours, datetime) %>%
  dplyr::summarise(temperature=mean(temperature))
# 全データ 
ggplot(japan.summarize.hours, aes(x=datetime, y=temperature)) + geom_point() + geom_smooth(span=0.3)

時間平均によるデータの要約

japan.hours$date <- as.Date(format(japan.hours$datetime, "%Y/%m/%d"))
japan.days <- 
  dplyr::group_by(japan.hours, location, date) %>%
  dplyr::summarise(temperature=mean(temperature))
# 全データ
ggplot(japan.days, aes(x=date, y=temperature)) + geom_point() + geom_smooth(span=0.3)
# 地点別
ggplot(japan.days, aes(x=date, y=temperature, color=location)) + geom_point() + geom_smooth(span=0.3, color="black") + facet_wrap(~location)

参考文献

https://ja.wikipedia.org/wiki/%E6%A8%99%E6%9C%AC%E8%AA%BF%E6%9F%BB http://park.itc.u-tokyo.ac.jp/tkdlab/member/ohbuchi/labo/average.htm https://oku.edu.mie-u.ac.jp/~okumura/stat/bootstrap.html