2016年9月19日月曜日

Histogram と Density Plot:安易さと誤用

ある single variables(年収、寿命、数学の成績、等の一つの変数)を俯瞰するのに、histogram(ヒストグラム)と density plot(密度プロット)はどちらが優れているか?

「優れている」の定義を、ここでは

外れ値や無効な値を見つけやすい分布

とする。

本投稿は、Nina Zumel, John Mount 著 "Practical Data Science with R" の第 3 章 "Exploring data" の "Histograms" と "Density plots" をもとにした。


Practical Data Science With R
Practical Data Science With R
posted with amazlet at 17.02.10
Nina Zumel John Mount
Manning Pubns Co
売り上げランキング: 107,052

本章は「データ分析の開始で、最初にやること」という感じなのだが、非常に面白い。知っていたことではあるが、こやって再整理すると理解が深まる。また、ggplot2 を使っているのも嬉しい。


小学生な Histogram

一般的に見られるグラフは、histogram なのは間違いない。その意味するところは、小学生でも分かるし作れるから。普段のニュースなどの報道の場面で使われるのも histogram の方なのは、そんな分かりやすさが理由だろう。しかし、

「分かりやすい」ほど「誤解を招きやすい」

というのは、多くの場合に当てはまる。histogram の「誤解を招きやすい」=「誤用しやすい」面を見ていく。

以下は本書提供の顧客データ

> custdata <- read.table(
  "zmPDSwR-master/Custdata/custdata.tsv",header=T,sep="\t")

この「年齢」の histogram が、次の図 3.3
ggplot(custdata) +
  geom_histogram(aes(x=age),binwidth=5,fill="gray") + 
  geom_text(data=data.frame(),
            aes(130,10,label="Outliers",colour=1)) + 
  geom_text(data=data.frame(),
            aes(0,10,label="Invalid\nvalues",colour=1)) + 
  theme(legend.position="none")
R 備考:geom_textdata=data.frame() でフォントが綺麗になる。theme(legend.position="none")  で geom_text(aes(label=...)) による legend の表示を消すため。
geom_histogram の引数に binwidth=5 のように「棒幅」の指定がなければ、30 が使われる。これが最大に面倒なところ、そして誤用の原因。

次は、binwidth=10 で再作成したもの
y 軸のスケールなどが変わってしまう。outliers「外れ値」の印象も違う。


Density Plot は "Continuous Histogram"

density plot を「密度プロット」と訳して良いものか不明なので、density plot と記す。先の histogram の記述も、これに従ったもの。

density とは「密度」のことで、確率密度関数(probability density function, PDF)の density のこと。年齢は「離散型」データなので、連続型を扱う「確率密度」は不自然に思われるかもしれない。この辺も、histogram が好まれる理由なのだろう。

何よりも、density plot は histogram より分かりにくい。y 軸は絶対値ではなく確率の「相対値」で、これでは「小学生には難しい」だろう。「曲線と x 軸で囲まれた面積は 1.0」の認識が必要。概念的には「潰したスポンジ」と考えると分かりやすい(参考:「確率密度を例える(潰したスポンジ)」)。

本書で density plot を "continuous histogram"「連続型 histogram」と表したのは上手。

同じ「年齢」を density plot したもの
summary(custdata$age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0    38.0    50.0    51.7    64.0   146.7 
c <- "> summary(custdata$age)\n   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.\n    0.0    38.0    50.0    51.7    64.0   146.7"
ggplot(custdata) + geom_density(aes(x=age)) + 
  geom_text(data=data.frame(),
    aes(70,0.015,label=c,colour=1),size=3.3,hjust=0, family="mono") +
  theme(legend.position="none")
備考:geom_text で文字の中央配置を変更するのが hjust 、等幅フォントの指定は family="mono"

binwidth=5 のような指定は不要で、density plot を知っている人には、誤解を与えようがない。

データ分析において、絶対値で云々する、というのは稀だと思う。その意味で「histogram が優れている」という考えには同意しない。とはいえ、上記のような「素直な density plot」だけでは不十分で、次回はその点を取り上げる。


対数スケール」に続く。

0 件のコメント:

コメントを投稿