ラベル 次元 の投稿を表示しています。 すべての投稿を表示
ラベル 次元 の投稿を表示しています。 すべての投稿を表示

2012/08/20

文系のための「データの観察」(2)

データの「真ん中」とは何か?その疑問について再び考える。
平均」というのは、確かに「真ん中」のようである。納得できる。
しかし、本当に「平均」だけで良いのか?少々疑問が残る。

どういうことであるか?日本人の「職種別平均収入」で考えてみる。
今回は、「前フリ」無しで、最初から R を立ち上げる。

そろそろ、データの読み込み方は大丈夫だろう。説明を省く。
自信の無い人は、これまでの投稿を確認。やり方は、書いてある。

まずは、一つ目のデータを準備する。
上から順に、薬剤師、精錬工、技術士、機械工、自動車組立工、
製紙工、電気工、看護師、営業用バス運転者、社会保険労務士、
と並んでいて、その横に各業種の平均収入が入っている。
参考データはあるが、色々と変更を加えているので、ほぼ架空のデータ
給料の単位は、「万円」となっている。そのようなデータを用意した。
なお、このデータは、後の操作がしやすいように、収入順で並んでいる

salary
pharmacist, 496.6
refining engineer, 494.3
professional engineer, 489
machinary engineer, 487.8
auto assemblyman, 477.6
paper making engineer, 471.5
electronic engineer, 465.9
clinical nurse, 465.2
bus driver, 450.1
specialist in social insurance, 446.8

このデータを「X1」という変数に格納する。

# Windows  と Linux の人は以下のコマンド
X1 <- read.table("clipboard", sep=",", header=TRUE)

# Mac の人は以下のコマンド
X1 <- read.table(pipe("pbpaste"), sep=",", header=TRUE)

では、実際にこのデータを使って分析を行なってみる。
平均収入はどのようになっているのか?以下が出力結果。

> mean(X1$salary)
[1] 474.48

なるほど、納得できる。これらの職種間の平均収入は、474.48万円である。
元のデータを観察してみると、なんとなく、納得のいく数値である。

では、次に別のデータを用意してみる。
今度は、先のデータに加えて、パイロット、大学教授、医者、
の3つの職業を加えた。このデータを変数「X2」に入れる。
このデータも、収入順に並んでいるこのことは後に重要

salary
pilot, 1295.5
professor, 1133.2
doctor, 1101.2
pharmacist, 496.6
refining engineer, 494.3
professional engineer, 489
machine engineer, 487.8
auto assemblyman, 477.6
paper making engineer, 471.5
electronic engineer, 465.9
clinical nurse, 465.2
bus driver, 450.1
specialist in social insurance, 446.8

データを変数にセットするコマンドは以下の通り。

# Windows  と Linux の人は以下のコマンド
X2 <- read.table("clipboard", sep=",", header=TRUE)

# Mac の人は以下のコマンド
X2 <- read.table(pipe("pbpaste"), sep=",", header=TRUE)

X1と同様に、平均を出してみる。以下は、出力結果。

> mean(X2$salary)
[1] 636.5154

うん?636.515万円?この結果を見て「違和感」を感じる。3つ加えただけ。
先程に比べて、値が大きすぎる。これは、本当に全体の「真ん中」と言えるか?
追加した3つの職種によって、平均は一気に引き上げられた。ここで疑問が生まれる。
これらは、むしろ、「外れ値」として考えた方が良いのでは無いか?と。

何か、新しい政策を考える際に、安易に収入の平均を用いると、
トンデモナイことが起きる。実態に合わない政策が決定されるかもしれない。
吟味せずに、数値データを扱うことは、極めて危険なことである。

などと、問題点を指摘していても仕方ない。別の方法が必要である。
どうするべきか?

そこで登場するのが、2つ目の「真ん中」の概念。
平均」ではなく、データの「真ん中」番目を見てはどうか?
なるほど。確かに、これも「真ん中」である。

では、最初にX2の対象数を数えてみる。Rを使って。
nrow()関数を覚えているだろうか?

> nrow(X2)
[1] 13

したがって、このデータの場合は、7番目が「真ん中」番目である。
今回は総数が奇数なので、上から数えても、下から数えても「7番目」である。
試しに、7番目のデータを見てみる。予め収入順で並んでいるので楽
7行目を指定するので、以下のような結果が出る。

> X2[7,]
[1] 487.8

通常は、下から数えることになっている。これを「中央値」と呼ぶ。
R では、中央値を出す関数を持っている。median()関数である。
この関数は、値が並んでいなくても使える

> median(X2$salary)
[1] 487.8

なるほど。この結果を見てみると、平均よりも中央値の方が実態に合っている。
そのように思える。では、X1の場合と比較してみる。

> median(X1$salary)
[1] 474.55
> median(X2$salary)
[1] 487.8

若干、値が高くなっているが、平均よりも安定している。
データの「真ん中」を決める際に、安定感が無い指標は良いとは言えない。
したがって、中央値の方が、より適切にデータの「真ん中」を示していると言える。

ただし、データの総数が非常に大きく、
また、データが真ん中に向かって「綺麗な釣鐘状」に存在する場合、
平均値と中央値は近づく。そのような場合には、平均でも良いということになる。

ところで、気づいた人も居るハズ。X1のデータの総数は、偶数であった

奇数の場合は、ちょうど「真ん中」というのがあって決めやすいが、
偶数の場合は、「真ん中」が2つあって簡単に決めることができない。


実は、中央値というのは、奇数(odd)偶数(even)で取り方が異なる。
どうするべきか?議論が分かれるところである。


上を採用する方法、下を採用する方法も考え得る。
あるいは、上下2つの値の平均を採用するという方法もある。

どの方法が正しいかを述べることは困難であるが、
やはり、「真ん中」という意味では、平均を取る方法が適切に思える。
なお、R の median()関数 も偶数の場合には平均を取っている。

基本的な説明は以上であるが、やはり、数理的なことも理解しておいた方が良い。
もう少し、詳しく、「中央値」について考えてみる。



数式に慣れていない人は卒倒するかもしれない。落ち着きが必要。

ここで、Qという変数が登場する。これは、Quantile (分位数)の頭文字。
分位数というのは、あるデータをある数で等分すること

なるほど、「中央値」というのは、全体を2つに等分するので、
二分位数」ということか。もっとも、そんな言い方はしないが。
とにかく、そのように考えると、Qの「添字」である「1/2」の意味が解る。

さて、イコールを挟んで右側、つまり、右舷を見てみる。厄介に見えるかもしれない。
二段に分かれている。上には「if n is odd」、下には「if n is even」と書いてある。
なるほど、上の方は奇数の場合で、下の方は偶数の場合であるか。

大体、分かってきた。ここで、ちょっとした疑問がある。
何故、「x」ではなく、「x'」となっているのか?疑問に思わない人もいるかも。

そもそも、元のデータの変数が「x」だったして、
元のデータ「x」が今回のように、昇順に並んでいるとは限らない
そのような場合には、必ず、並び替え(ソーティング)が必要となる。
「x'」というのは、要するに、元のデータを並び替えただけのもの

さて、後は簡単である。添字は、データの「何番目」であるかを表す。
したがって、次のことが言える。

  • 奇数の場合には、「総数nに1を足して2で割った数」番目が「中央値」となる。
  • 偶数の場合には、「総数を2で割った」番目と、「それより一つ上」番目を足して、さらに、その合計を「2で割った値」が「中央値」となる。

解りにくいかもしれない。X2の場合は、総数が13であった(n=13)。
つまり、奇数。したがって、(13+1) ÷ 2 = 7番目の値が中央値となる。

では、X1の場合はどのようになるのか。確か、総数は10であった(n=10)。
今度は、偶数。だから、二段目の式を当てはめることになる。
10÷2番目と(10÷2)+1番目、つまり、5番目と6番目の値を足して割った数が中央値
この場合は、少々厄介であるか。Rで確認してみる。以下、実行結果。

> X1[5,]
[1] 477.6
> X1[6,]
[1] 471.5
> (X1[5,]+X1[6,])/2
[1] 474.55
> median(X1$salary)
[1] 474.55

確かに、正しく計算されていて、上に提示した式とも合致している。
R を用いると、数式上の表現と、実際の処理を比較できるので良い。

さてさて、以上のことで、データの「真ん中」ということが整理できた。
平均と中央値という2つの決め方がデータの「真ん中」なのである。

本当にそれで良いのか?まだ、「真ん中」の決め方があるかもしれない。
では、どのような方法があるか?確か、外れ値に影響されないことが重要だった
例えば、最も頻繁に登場する値を「真ん中」として考えられないだろうか?
ふむふむ。これは検討の余地がありそうである。この話はいずれ。

2012/08/19

文系のための「データの観察」(1)

ケトレーの話では、「平均人」というものが出てきた。
平均人は、対象の個性を測るための架空の擬似人格のようなものであった。
そして、個性というのは、この平均人からの距離(偏差)であった。

データの「真ん中」を見極めることと、
個性の強さとも言える「バラツキ」を評価すること、
この2つの基本的操作は、データ解析において、最も重要なことである。
特に、データの個性を表す「バラツキ」はデータ解析において基本中の基本。

近年、文系分野の研究者が「見様見真似」で難しい分析を行なっているの見かける。
確かに、私自身、そうした時期があったし、そういった悪しき癖は残っている。
しかしながら、基本的な事だけでも、重要なことは分かる。

最初に考えるべきことは、データの「真ん中」である。「バラツキ」はその後。
データの「真ん中」が分からないと、「バラツキ」を計るための基準も定まらない。
本当は「バラツキ」について考えたいのだが、まずは「真ん中」の話から。

そもそも、データの「真ん中」とは何か?

多くの人は、「平均」という言葉を思い浮かべるのではないか?
なるほど、確かに、平均というのは良い考えである。
実際、ケトレーは、平均という概念が、データ全体を説明するものと考えた。

では、平均とは何か?魚の値段を例に考えてみる。
まぁ、魚である必要は無いのだが、私は魚介類が好きなのだ。

仮に、魚屋さんで400円のお刺身、200円の目刺し、600円の鰈の一夜干し、
この3つの品目が並んでいたとする。
適当だが、妥当な値段である。まぁ、良い。単なる実験データ。

ふむ。では、この3つの品目の値段の平均は?電卓を使っても良い。
もちろん、Rで計算しても良い。計算式は、自分で立てられるだろう。

答えは、400円。さすがに、この計算は大丈夫であろう。
この程度の計算ができないと困る。「文系」とかそういう問題では無い。

では、どような計算を行ったのか?数式を見ながら考えてみる。
おそらく、以下のような計算を考えたはずである。



あるいは、以下のように考えた人もいるはず。



2つ目の式は、品目3つを一つの単位(つまり全体を「3」)としていて、
したがって、値段全体を単位一つ分として考えた場合の、
単位一つ分の値段理屈上どうなるかを考えている。どこかで聞いたような?

確か、「文系のための「逆行列」(1)」の話。

なるほど、1/3 を掛けるというのは、
対象数に合致するような単位に換算するために、
対象数の逆数をかけているのだった。

要するに、3つの品目に個性が無く、全て同じ値段だったら?というわけである。
したがって、400円という単位が3つで全体が説明できる

ところで、上記の場合は、たった三品であったが、
品目が多くなると、式が長すぎて書くのも、見るのも面倒。
そこで、上記の式を抽象化し、より一般的なものに書き直してみる



まず、品目の変数をxと置く。右下の数字と記号は何であったか?
これは「添字」と呼んだ。何番目の対象かを示していて、
不特定番目の対象を「i」番目、
最後番目の対象を「n」番目としている。
したがって、全体の個数(総数)は当然「n」個。

なるほど、これで、対象がいくら増えたとしても、
この長さの式で平均を書き表すことができる。

だが、やはりまだ長い。しかも、「・・・」という記号は美しくない
ということで、自称「文系」が苦手とする「Σ(シグマ)」を使って表現する。



イコールで分けられた3つの式は同じ。
左端は、nで割るというイメージ。自称文系には、解りやすいが見難い。
真ん中は、nの逆数を掛けるというイメージ。理屈っぽい式。教科書はこの形式。
右端は、慣例的な表現で、「エックスバー」と読む。玄人向け。計算式を省略。
上に「-」が付いているものは、何かの平均を表す。

さて、ここで、シグマの見方を復習しておく。
Σという記号は、「足し算の繰り返し」を表す。
Σの記号の「」についてあるのが、添字の記号とその開始番号
Σの記号の「」についてあるのが、添字の最後(総数)を表している。

一回目の足し算が終わる度に、iの値が1〜nまで一つずつ繰り上がる。
そして、i=nとなったときに、足し算の計算が終了する。
その結果を総数nで割ると考えるか、総数nの逆数で掛けると考えるかで、
式の表現は異なる。ただし、結果は同じ。

エックスバー」による表現は、非常によく出てくる。
平均というのは、誰もが理解している(という前提)ので、
慣例的にこの表現を使う。説明無しに登場することも多い
この意味が解らないと、教科書の内容をサッパリ理解できない。

以上で基本的な「平均」の話は終わり。

さて、ここからは、「R」を使って平均の計算をやってみる。
今度は、「魚の卸売価格」を例に考えてみる。
私は、魚介類が好きでなのである。

まずは、コンソールを立ち上げて、データ読み込みのコマンドを入力。実行はまだ

データの読み込みは、read.table() 関数を使うのだった。

# Windows と Linux の人は次のコマンド
X <- read.table("clipboard", sep=",", header=TRUE)

# Mac の人は次のコマンド
X <- read.table(pipe("pbpaste") , sep=",", header=TRUE)

次に、今回の例で用いるデータをコピーした後、上のコマンドを実行する。

Oroshi_Kg, Taka, Naka, Yasu
Tai, 1336, 3150, 1217, 53
Chinu, 226, 630, 513, 105
Sawara, 212, 1575, 1259, 840
Yazu, 4834, 840, 315, 179
Suzuki, 618, 1575, 1146, 525
Akou, 21, 4725, 3129, 1575
Kochi, 28, 2100, 874, 210
Okoze, 28, 5250, 2635, 210
Ainame, 29, 3150, 621, 315
Hage, 1205, 1890, 383, 210
Konoshiro, 21, 2100, 1100, 105
Sayori, 12, 5250, 3916, 1260
Anago, 1637, 2625, 1721, 630
Mebaru, 330, 4200, 1680, 315
Tachiuo, 1211, 2310, 930, 105
Hamo, 1622, 3938, 592, 53
Karei, 41, 6300, 3178, 525
Hirame, 540, 2100, 1496, 210
Aji, 5149, 3150, 789, 210
Saba, 5413, 3675, 625, 53
Ika, 2414, 2888, 1083, 105
Tako, 1844, 1890, 1180, 525
Ebi, 560, 7350, 1420, 525
KurumaEbi, 222, 8925, 6508, 2625
Koiwashi, 1316, 1155, 617, 328
ObaIwashi, 2716, 499, 267, 175
Mentai, 678, 1155, 859, 394
Hamachi, 4772, 998, 632, 105
Isaki, 268, 2625, 1465, 840

このデータは多次元データになっている。
このデータにおいては、対象が魚の名前で、属性がそれぞれ、
卸売数量(Kg):Oroshi_Kg、高値:Taka、中値:Naka、安値:Yasu、
となっている。つまり、四次元のデータとして表現されていることになる。

ところで、データのことを事前に知っておくことは重要である。

このデータの出典は、広島市中央卸売市場の水産物市況(2012/08/18)から
欠損データを抜いたもの。すでに、ある程度要約されているデータである。

高値、中値、安値、というのは魚の値段のおおよその基準。
魚には大小があって、大小によって値段も、可能な調理の幅も異なる。
高値は、大きくて色々な用途に使えるもの。そして、高い。
中値は、一般的なサイズで、多くの人が目にして、買って、家庭で調理するもの。
安値は、小ぶりなもので、利用の用途が限られるようなもの。
このデータでは、(おそらく)それぞれの値の平均。詳細は不明。

この話に関しては、以下のページに解りやすい説明があった。
http://www.shonai-nippo.co.jp/square/feature/food/sf48.html

少し話が逸れたが、まずは、卸売数量の平均を求めてみる。
Rでは、mean()関数で平均を計算できる。非常に、簡単。

mean(X$Oroshi_Kg)

このコマンドでは、Xという変数の属性名を「$」記号を挟んで指定している。
あるいは、次ようにして求めることもできる。

mean(X[,1])

この表記は、Xの「1列目」という考え方で指定している。
ちなみに、大カッコ(「[ , ]」)のカンマの右側は行数左側は列数を表す。
以下は、実行結果。

> mean(X$Oroshi_Kg)
[1] 1355.276
> mean(X[,1])
[1] 1355.276

同じことを行なっているので、計算結果は同じ。これは当然。
同様に、他の変数の平均も計算してみる。

mean(X$Taka)
mean(X$Naka)
mean(X$Yasu)

以下は、上記コマンドの実行結果。

> mean(X$Taka)
[1] 3035.103
> mean(X$Naka)
[1] 1453.448
> mean(X$Yasu)
[1] 458.9655

ついでなので、以下のコマンドも実行してみる。
なお、大文字と小文字に注意すること。
Rのコマンドは大文字と小文字を区別する。

colMeans(X)

どのような結果が出てくるか?以下は実行結果。
4つの変数の平均を同時に計算できる。

> colMeans(X)
Oroshi_Kg       Taka       Naka       Yasu 
1355.2759 3035.1034 1453.4483  458.9655 

このコマンドは「列平均(Column Means)」を計算する関数であり、
colMeans()関数と呼ぶ。複雑な分析を行うようになると頻繁に登場する。
今の段階で覚えておくと良い。

今回のデータでは、全く意味は無いが、行平均(Row Means)」もある。
これは、rowMeans()関数で計算できる。
あくまで練習。これもやってみる。実行結果は以下の通り。

> rowMeans(X)
      Tai     Chinu    Sawara      Yazu    Suzuki      Akou     Kochi     Okoze 
  1439.00    368.50    971.50   1542.00    966.00   2362.50    803.00   2030.75 
   Ainame      Hage Konoshiro    Sayori     Anago    Mebaru   Tachiuo      Hamo 
  1028.75    922.00    831.50   2609.50   1653.25   1631.25   1139.00   1551.25 
    Karei    Hirame       Aji      Saba       Ika      Tako       Ebi KurumaEbi 
  2511.00   1086.50   2324.50   2441.50   1622.50   1359.75   2463.75   4570.00 
 Koiwashi ObaIwashi    Mentai   Hamachi     Isaki 
   854.00    914.25    771.50   1626.75   1299.50 

となる。各対象(魚)について、卸売数量、高値、中値、安値、の平均が出ている。
全く意味は無い。このような無意味なことはやってはいけない。

そもそも、卸売数量と、他の3つの属性は単位が異なっていて比較できないし、
高値、中値、安値というのは、各対象の何かの代表的な値であって、
しかも、中値がある意味でデータの「真ん中」を示している。
あくまで、コマンドの実行例として割りきる。

さて、今回は、「平均」というデータの真ん中について考えた。
ふむ。納得できた。だが、ここで一つの疑問が湧いてくる。
すなわち、平均以外の方法はあり得るのか?という疑問である。

なるほど。確かに、平均という考え方は的を得ているように思えるが、
何か、重大な問題を見落としているようにも思える。何が問題なのか?
この疑問については、次回に考えてみることにしよう。

2012/08/10

文系のための「行列」(4)

行列というものがどのようなものであるか、大体は理解できた。
ふむ。では、さっそく、統計の教科書を読んでみる...。

何やら、色々と記号があって、理解できない。
アルファベットの上に何かが書いてあったり、
右下に「i」とか「j」などと書いてあったり、
見たことの無いような記号「λ」といったものある。

っという状況にある人のために、
変数」と「添字」の見方についても整理しておく。
意味が解っている人には不要。

数学が苦手で、逃げ続けてきた(いる)人は多い。
そういった類の人は、「変数」と聞いただけで卒倒する。

あっ...理系の人なんですね〜。私、文系なんで〜。
はっきり言って、関係ない。

多くの場合、この手の人は、そもそも、何もできない。
そういう人になってはいけない。文系を自称して数学の苦手を強調する人で、
自身の文系能力を「きちんと」説明できた人に会ったことが無い。

深くは述べるつもりは無いが、私は古典的な文化科学の流れを引く文系研究者である。
確かに、数学は苦手ではあるが、これは「文系だから」ではなく、
中学校以来、逃げ続けてきた「結果」に過ぎない。別問題である。

何やら、愚痴っぽいな。私の身に何かあったのかもしれない。
まぁ、それで良い。そういったことを書けるのも、個人のブログ。自己満足。

話が逸れたが、「変数」とは何か?を考える。
以前の投稿で、多次元データにおける「次元」が
ある事象を空間に布置するための「」であると説明した。

この「」というのは、ある事象の特性の量的な大小であり、
したがって、「属性」の大小を布置するための基準であり、
ある属性の「」は軸上の「どこかに」布置される。

では、その「どこか」とは、何によって決まるのか?
それは、個々の実際の対象「観測値」に依存する。
実際の対象によって、「」わる「」の値であるから「変数」と呼ぶ。

例えば、「」という事象に関して、「身長」、「体重」、「年齢」、「体脂肪率
という属性が定義されていて、「Aさん」、「Bさん」、「Cさん」、「Dさん」、
の四つの対象があったとすると、四人のそれぞれの属性の値が「変数」である。

この変数というのは、一般的に、どのような数字が入るのか不明なので、
したがって「x」や「y」、あるいは他の文字で置き換えるのである。

さらに、この話を一般化し、多次元データとして考えてみる。

ここでは、p個の属性から成る事象について、n個の対象を集めてきたとする。
すると、以下のように表現できる。これを「np行列」と呼ぶことにする。
古い教科書では、「nm行列」で表している場合がある。



データによって、属性の数も、対象も変化するので、文字に置き換えているだけである。
つまり、対象数と属性数自身が変数として説明してある。

さて、この行列の個々の「成分」は「スカラー」の「変数」である。
状況に応じて変わるので当たり前。「x」という記号で表されている。

この記号をよく見ると、右下に申し訳なさそうに、
数字(と文字)がちょこんと座っている。これを「添字(そえじ)」と呼ぶ。
要するに、この行列内における変数の場所を示しているのである。
ちなみに、英語では、「subscript」と呼ぶ。

添字も、増えていくと訳が解らなくなるが、
要するに、「何番目の変数であるか?」を表しているだけである。

上の多次元データにおいて、左上の「成分」は、 となっている。
これは、1行目の1列目の成分にある変数であることを指している。

では、 となると、どこを示しているのだろうか?
答えは、5行目の3列目の成分を示す変数である。

次に、「不特定」番目の表現について考えてみる。
対象の数が、1〜nまで存在したとして、この区間の不特定の地点を「i」とし、
属性の数が、1〜pまで存在したとして、この区間の不特定の地点を「j」とすると、
任意のある地点の変数は、 で表現できる。

これで、「変数」と「添字」の意味は大体は理解できた。抑えておきたい点は、

行列として表現されたある多次元データの成分は、
スカラーの変数であり、そのスカラーの行列内の位置を添字で特定する、

次に、行列の「ベクトル」を変数として扱う場合と、
行列自身を一つの変数として扱う場合について考える。
とにかく、最初に、どういった状況であるかを見てみる。

まずは、「横ベクトル」の場合を考える。



この例では、「横ベクトル」を取り出し、それぞれを「変数」として表現している。
つまり、以下のようになっている。全部書くのは面倒なので一行目だけ。



次に、「縦ベクトル」の場合。「横ベクトル」の場合と同じ。
ただし、並び方の関係上、直感的に解りにくいかもしれない。



これも、1列目だけを取り出してみる。
すると、以下のようになる。



疑問に思った人も居るかもしれない。つまり、
縦ベクトル」と「横ベクトル」の区別ができない、と。
中々、良いセンスである。結論から言うと区別は無い。
そもそも、ベクトルには、縦と横の区別が無い。

では、どうするか?これが厄介である。文脈から判断する
大抵の場合は、データの一部(あるいは全体)が示されていたり、
計算方式が、どこかに示されているので、それを見て判断する。
実際、混乱の元になるのだが…慣れれば問題ない。

最後に、「行列」自身を変数とする場合。これは、すでに示されてある。
慣例的には、「大文字」の斜体太文字アルファベットで表すのである。
行列の計算では、よくこの大文字の変数で表されていて、
教科書などでこれが出てきたら、とりあえず、行列をイメージすることが重要。


2012/08/09

文系のための「行列の演算」

ここまでの話は、行列に関する基本概念の話であった。
だから、覚えないといけないことも、それなりにあった。

このブログを最初から呼んでいる人の中には、
なぜ、わざわざ「行列」という話から入ったのか、
イマイチ、解らないという人もいるかも知れない。
新しいことなので、そのように思うことがあるかもしれない。

しかしながら、「Σ」が一杯並んだ数式をよりも、
様々な計算が簡略化され、慣れてしまえば意外に楽な事も多い。

以前にも述べたことであるが、多次元データというのは、
ある事象を空間的に布置するという意味がある。
例えば、「人」という事象があって、その事象が、
「慎重」、「体重」、「年齢」、「体脂肪率」という
四つの属性によって定義されていたとする。
すると、この「人」というのは「四次元」の空間に布置できる。

「次元」や「空間」という言葉を聞いて「図形」の話と思ってはいけない。
ただし、多次元データは、空間に布置できる。これが重要。
要するに、人が知覚しやすいように、空間として考えるのである。

なぜ、わざわざ、このようなことを強調しているのか。
理由は、「ベクトル」と「行列」を使うと「空間」に布置された対象の「変換」が楽になる。
例えば、3Dゲームの多くは、視点の変化と三次元オブジェクトの見え方を
瞬時に計算し、それを二次元平面のディスプレイに表示するが、
その処理は、「ベクトル」や「行列」の演算を用いる(ハズである)。

前置きは、この辺りで止めておこう。長くなる。

さて、スカラーにおける四則演算があるように、
ベクトル」や「行列」においても四則演算は存在する。
少々、複雑ではあるが。これを理解しない限りは、先にすすまない。

ということで、まずは、「行列」の「足し算」と「引き算」から始めよう。
これは、それほど難しくはない。手計算もできる。

なお、今回の説明に関しては、あくまで文系向けであって、
厳密には「ベクトル」の足し算ではあるのだが、
理工系の方々で、事情を解っている方々には目をつむってもらえると幸いである。

では、始めよう。サンプルデータを用意し、統計パッケージの「R」で実習する。

最初に、「R」を起動し、以下のコマンドを貼付ける。
貼付けるだけで、まだ、実行してはいけない。
(実行とは、エンターキーを押す事である。)

# Windows と Linuxの場合
shape <- read.table("clipboard", sep = ",")


# Mac の場合
shape <- read.table(pipe("pbpaste"), sep = ",")

貼付けたら、今度は、下のデータをコピーし、
コピーしてから、上記のコマンドを実行する。

x,y
P1,0,0
P2,40,40
P3,40,0
P4,0,0

何もエラーが出なければ問題なく読み込めたハズ。
一連の操作で、shape という変数に行列データが代入された。

なお、Linux の場合は、以下のようなエラーが出るかもしれないが、
データは入る。おそらく、改行コードの問題であろう。

Warning message:
In read.table("clipboard", sep = ",") :
  incomplete final line found by readTableHeader on 'clipboard'

とにかく、shape と入力し、以下のように出力されれば問題ない。

> shape
    x  y
P1  0  0
P2 40 40
P3 40  0
P4  0  0

この程度であれば頭で想像できるが、いや、苦手な人もいるかもしれない。
それはそれで良い。とにかく、「可視化」というものをやってみる。

plot(shape, type="b")

とする。要するに、shape という変数が入ったデータを「プロット(布置)」する。
plot()関数は、様々なデータを布置して可視化するための関数である。
type = "b" というのは、表示方法のパラメータ(引数)であり、
線(line)と点(point)の両方(both)を表示するという指定である。
なるほど、英語の最初の一文字を使っているのである。
したがって、線のみで表示したい場合には type = "l" とし、
点のみで表示したければ、type = "p" とすれば良い。

問題が無ければ、以下のような図が表示されるはずである。
もっと複雑な形状でも構わないのだが、
モノグサな私には大掛かりな準備が億劫であったので、
このようなシンプルな図形にしてみた。
図形の想像もしやすいので、これで良いことにする。
さて、今回のテーマである行列の「足し算」と「引き算」というのは何か?
図形として考えると、足し算と引き算は、空間上の「移動」に相当する。
例えば、GISや地図ソフトの水平移動の機能は、内部的にこの計算を行っている。

行列の「足し算」と「引き算」というのは、直感的に理解しやすい。
おそらく、一回説明を聞けば誰でも理解できる。
ようするに、「同じサイズ」の2つの行列を準備し、
同じ場所にある要素同士を足したり、引いたりするだけ。

ここで重要なポイントは、同じサイズの行列同士でしか出来ない、
ということである。


例えば、x軸方向に10移動し、y方向に15移動する。
中学校までの知識では、以下のようになる。

P1(x,y)=(0 + 10, 0 + 15)
P1(x,y)=(40 + 10, 40 + 15)
P3(x,y)=(40 + 10, 0 + 15)
P4(x,y)=(0 + 10, 0 + 15)

確かに、そのようであった。
これを、「行列」を使って表現すると、以下のようになる。



どういう計算であるか、見れば分かる。
2つの同じサイズの行列があって、
同じ場所にある、要素同士を足しているだけである。
これが、空間上の操作であると考えると、「移動」に相当する。

では、本当にそのようになるのか、実際に「R」を使って計算してみる。
とりあえず、加える行列を作ってみる。

A <- matrix(c(10,10,10,10,15,15,15,15), nrow=4, ncol=2)

どういう行列かと言うと、

> A
     [,1] [,2]
[1,]   10   15
[2,]   10   15
[3,]   10   15
[4,]   10   15

では、実際に計算してみる。

> shape + A
    x  y
P1 10 15
P2 50 55
P3 50 15
P4 10 15

ふむ。予想通りの結果となった。
要するに、各要素に足し算を行なっているだけである。
どういう図形になっているかを確認する。

plot(shape + A, type="b")

一見すると、最初の図と変わっていないように見えるが、
原点位置を確認してみると、移動していることがわかる。
試しに、2つの図を重ねてみる。以下をコピー・アンド・ペースト。

plot(shape + A, type="b", col = "blue", xlim = c(0,60), ylim = c(0, 60))
par(new=TRUE)
plot(shape, type="b", col = "red", xlim = c(0,60), ylim = c(0, 60))

すると、以下のようなプロットが出てくる。
赤い方が、shape をプロットしたものであり、
青い方が、shape + A をプロットしたものである。
卒倒する人もいるかもしれない。一行目のコマンドを確認してみる。
plot()関数 は、色々と任意のパラメータを加えることができる。
まず、col = "blue" のところで、出力結果を「青色」で表示させ、
xlim = c(0, 60) の部分で、x軸の最小値と最大値を決めている。
同様に、ylim = c(0, 60) でy軸の最小値と最大値を決めている。
xlimylim を設定しない場合、最初の図の表示範囲に依存するので、
いずれかの図が、はみ出てしまうのである。

ついでに、「引き算」もやってみる。次のような状況を考える。
x軸方向は、マイナス方向に20、
y軸方向は、マイナス方向に10、移動するような計算。

足し算」と同様に、「同じサイズの行列を準備し、
元の行列から別の行列を引く。



この処理は以下のようになる。


B <- matrix(c(20,20,20,20,10,10,10,10), nrow=4, ncol=2)


plot(shape, type="b", col = "red", xlim = c(-20,40), ylim = c(-10, 40))
par(new=TRUE)
plot(shape - B, type="b", col = "blue", xlim = c(-20,40), ylim = c(-10, 40))

同様に可視化してみる。すると、次のようになる。

行列の足し算は、大して難しいものではない。
次は、「掛け算」の話が必要なのだが、それは少々複雑である。

2012/08/06

文系のための「行列」(2)

さて、「行列」見た目上の形式については、既に述べた。
難しいことは無く、ただ、行方向に属性の項目が並んでいて、
列方向に観測対象ごとの属性値が並んで入るのである。当たり前の話である。

ところで、以前の話では、最後に「多次元データ」という言葉が出てきた。
ここで、「うん?多次元??どういう事?」っと思ってしまうのが文系出身者。
だと思う。「現実世界が三次元で、時間が加わって四次元になって...ド○えもん?」とか。

そういった状況では、とにかく困るのである。分析どころでは無い。
少なくとも、以下の四つの用語については知ってもらわないと困る。

  1. スカラー(Scalar)
  2. ベクトル(Vector)
  3. 行列(Matrix)
  4. 次元(Dimension)
これらの用語を知らないと、統計の教科書も読めないのである。
それ故に、最初の章で挫折していまう人が、残念ながら少なからず存在する。

まず、聞き慣れないけれども、最も簡単なのが「スカラー」。
これは、普段我々が目にする「普通の数」のことである。
100円ショップで売っている「電子卓上計算機(電卓)」で使う数字である。

中学校までに扱う数字は、全て「スカラー」なのである。それだけ。

では、それ以外には?ということで登場するのが「ベクトル」。
簡単に言うと、「スカラー」が並んでいるもの。[1, 3, 5, 7, ...] といった感じ。それだけ。

じゃ、「行列」は?これも簡単。要するに、ベクトルが並んでいるもの。
つまり、次のように並んでいるもの。
| 1, 3, 5 |
| 4, 6, 8 |
| 6, 8, 0 |

気付いてもらえただろうか?
「行列」を「ベクトル」で説明しようとした場合、
縦方向で説明したい場合と、横方向で説明したい場合がある。
ところが、「ベクトル」には、縦横が無い。
そこで、横向きに見たときには「行ベクトル」、
逆に、縦方向に見たときには「列ベクトル」と呼ぶ。

前の例で考えると、各対象ごとでは「行ベクトル」であるし、
特定の属性ごとで見ると「列ベクトル」となる。

なぜ、わざわざ「ベクトル」や「行列」というものが存在するのか?
それは、スカラーに対して、足し算、引き算、かけ算、割り算、
といった演算(いわゆる「四則演算」)があるように、
「ベクトル」と「行列」に対しても、四則演算の方法があって、
これが便利なのである。このことについては、別の所で。

最後に「次元」。「ド○えもん」のポケットのことではない。
次元というのは、ある事象の特徴を「空間」に落とし込むための概念であって、
その空間には、次元数に対応した「軸」が存在する。
したがって、ある事象の特徴というのを図形的に表現することができるのだが、
かならずしも、図形を空間上に表現するとは限らない。

ということで、「人」を例に考えてみる。
そして、「人」は、「体重」、「身長」、「年齢」を「属性」に持っているとする。
すると、「人」の特徴は三次元空間上に投影することができる。
さらに、「体脂肪率」という属性を加えると、次元はどうなるか?
簡単。四次元空間に投影することができる。人の特徴は四次元で表現できる。

したがって、「次元」とは、事象の特徴を「空間」に写像するための「軸」と言える。
より高次元なデータは、低次元なデータと比較して、ディテールを表現している。

「なるほど!では、高次元のデータの方は良いな!」...とはならない。
文系の人が陥りやすい問題。高次元の事象を低次元に落とし込むことが、
ある意味では、定量的な分析の課題なのである。
人間は、せいぜい三次元くらいまでしか、視覚的に直感できないのであるし、
実際には、平面上では、二次元に落とし込まないと解釈できないのである。

ある原則にも関わる。すなわち、「ある事柄を説明するためには、
必要以上に多くの実体を仮定するべきでない」ということである。
これを「オッカムの剃刀」と呼び、統計学にも適用される。

余談ではあるが、「オッカムの剃刀」は、
オッカムのウィリアムという人物が提唱者であり、
ショーン・コネリー主演の「薔薇の名前」の主人公である。
いわゆる、歴史サスペンスであり、中々の名作。私好みの映画であった。