先日の記事の続きです。統計学の手法を用いようとしていますが、自分は統計学を学んだことはありません。。。(正確には学生の頃の研究でほんっとに触りの触りを独学でしていましたが)
今回の目的
e-Statで取得した統計情報をNode.jsで統計解析し、相関関係を導出すること。
対象データ
まずは適当にスポーツ庁が公開している体力測定(握力とか上体起こしみたいなやつ)の結果を対象にしてみます。東京オリンピックも近いですしね。
データの確認
ブラウザからAPIを実行してみて帰ってくるデータを確認してみました。
するとこんなXMLが返ってきます。(かなり割愛しています)
<VALUE tab="00100" cat01="100" cat02="100" cat03="100" time="2016100000">1121</VALUE>
<VALUE tab="00100" cat01="100" cat02="100" cat03="100" time="2015100000">1119</VALUE>
<VALUE tab="00100" cat01="100" cat02="100" cat03="100" time="2014100000">993</VALUE>
<VALUE tab="00100" cat01="100" cat02="100" cat03="110" time="2016100000">1124</VALUE>
<VALUE tab="00100" cat01="100" cat02="100" cat03="110" time="2015100000">1090</VALUE>
各項目について
- tab データ種別。平均値なのか標準偏差なのかみたいな。
- cat01 年齢。
- cat02 性別。
- cat03 種目。握力なのか上体起こしなのかみたいな。
- time 測定日だと思います。
相関を測るために
相関係数を出すためにsimple-statisticsというライブラリを使用します。
今回は長距離走と50m走の結果の相関関係を測定してみます。長距離向けの筋肉と短距離向けの筋肉ってモノが違うって聞きますけど、統計的にそういう結果って出るんですかね?
インストールは以下のコマンドです。
npm install --save simple-statistics
実装内容
実装したのは以下のようなコードです。
var req = require('request');
var parser = require('fast-xml-parser');
var statistics = require('simple-statistics');
var url1 = 'http://api.e-stat.go.jp/rest/2.1/appId=xxxxx&lang=J&statsDataId=0003254482&metaGetFlg=Y&cntGetFlg=N§ionHeaderFlg=1'
var options = {
url: url1,
method: 'GET'
}
req(options, function (error, response, body) {
if (error) {
console.log('Error: ' + error.message);
return;
}
var xmlOption = {
textNodeName : "value",//xmlタグの値は"value"というキーでJSON変換する
attributeNamePrefix : "",//Attribute名の先頭prefixを指定しない
ignoreAttributes : false
};
var jsonData = parser.parse(body,xmlOption);
var dataList = jsonData.GET_STATS_DATA.STATISTICAL_DATA.DATA_INF.VALUE;
//長距離走の結果を入れる
var longRunList = new Array();
//50m走の結果を入れる
var dashList = new Array();
for(var i in dataList){
var data = dataList[i];
var tab = data.tab;
var cat03 = data.cat03;
//長距離走の平均値リストを生成
if(tab == '00110' && cat03 == '130'){
longRunList.push(data.value);
}
//50m走の平均値リストを生成
else if(tab == '00110' && cat03 == '180'){
dashList.push(data.value);
}
}
//配列の値を全て数値にする
longRunList = paramChange(longRunList);
dashList = paramChange(dashList);
//相関関係を導出する
var correlation = statistics.sampleCorrelation(longRunList,dashList).toFixed(2);
console.log('長距離走と50m走の相関係数は' + correlation + 'です。');
})
function paramChange(dataList){
for (var i in dataList){
var data = dataList[i];
if(typeof(data) == 'string'){
dataList[i] = 0;
}
}
return dataList;
}
詰まったところ
- 配列のループ
for-inで配列から取れるのはオブジェクトとなぜか思い込み、なかなかハマりました。取れるのは配列のインデックスであることに気づき、 問題は解決しました。 - fast-xml-parser
XMLのパースに用いているモジュールですが、XMLタグの値はJSON変換するとデフォルトだと"#text"キーで変換されます。(以下の感じ)
{ "#text":7.22,
XXX:00100,
XXX:XXX,
XXX:XXX }
これだと、オブジェクトのアトリビュートとして指定できず、かなり苦労しました。
これも色々と調べるとオプションのtextNodeNameで指定できることが分かりました。なので、キーはvalueと指定します。
- 取得データ
実はAPIするデータは数値だけではありません。結果がない場合は{...}という値で返ってきていました。simple-statisticsの統計処理は数値型の配列を引数に渡さなければ正しく処理されません。そこで、paramChangeという処理で文字列の要素は0を代入するように処理しました。
相関を測ってみると
相関係数の算出結果は以下の通りです。
長距離走と50m走の相関係数は-0.17です。
うーん、相関はないとういうのが予想でしたが、それにしても値が低すぎる気がします。。。
まとめと反省
ひとまず、データを得る⇨データを処理⇨新たなアウトプットを出すという一連のプロセスはできました。
0の代入処理は間違った処理かもしれません。インプットとなる数列の標準偏差が変わっちゃいますね。。。
文字列を含む配列から数値配列のみを取り出して、要素数を揃えて統計処理をかける、これが正しかったかもしれません。次回への反省です。。。
他にもいろんな解析を加えたりして、データの料理をしていきたいですね!