How to | 無効データや欠落データを置換したり削除したりする方法

データ分析において,分析する前にデータ集合をきれいにすることが必要であることがよくある.入力に欠落項目があるデータ点あるいは無効な値を含むデータ点は,分析を行う前に削除するか推定値で置換するかする必要がある.Wolfram言語はこのような前処理を行うための環境を豊富に提供する.

特定の記号,文字列,あるいは範囲外の数を使って,データ集合内で欠落している情報を表すということがよくある.Missingのシンボルはこの目的のためにWolfram言語の組込みのデータ関数で使われる.

以下では,CountryDataで既知の国すべてについて国内総生産(GDP)を得る.大きな出力はセミコロン(;)によって非表示にする:

これは,アルファベット順に並べた場合の最初の10ヶ国についてgdpsの値を示す:

このデータについて最大のGDPを求めることにする.しかし,データには値のない国も含まれる.

生のデータから完全な最大値を求めることはできない:

データはさまざまな理由から欠落している可能性があるが,CountryDataではこれらをすべてMissingで始まる式で表示する.データ中の欠落値の数は頭部Missingを持つ式を数えることによって分かる.

Countをパターン_Missingと一緒に使って,頭部Missingを持つ式を数える:

データ集合全体におけるデータ点の数と比べて,欠落している結果の数は比較的少ない:

このような大きなデータ集合については,欠落している点を削除して,データが存在している点についてだけ分析を行っても問題ない.これらのデータ点を削除する簡単な方法としてCountにおいてMissingの式に使用したパターンと同じパターンをDeleteCasesに使うという方法がある:

新しいデータ集合の長さと最大値から,欠落値が削除されたことが分かる:

これで,数のリストに対して行える計算ならどのような計算でも,新しくフィルタをかけられたデータ集合に対して行うことができる.

    

前の例では,無効データ点が非常に特定の形(すべて頭部Missingを持っている)で示されていることは既知であった.しかし実際のケースでは,欠落している情報に対して使われる表記はさまざまである.スプレッドシートにデータを入力する人の中には,存在しないあるいは適用できない値に対してNAと入力する人がいる.また,データ収集ソフトウェアの中には,欠落している測定値を特定の範囲外の数で表すものもある.その結果,どの値が無効であるかを見極めるためには,データが何を表しているかを知ることが重要になる.

以下は,第1要素が2つのグループ番号のいずれか1つを表し,あとの2つの入力がそのグループの個々の測定値であるデータ集合である:

データを格子で表すと,データの中の問題がある部分をより簡単に見極めることができる:

この場合は,2つの問題があることが分かる.1および2という2つのグループしかないはずであるのに,グループ番号が4という入力がある.さらに,3列目に数値ではない入力がある.この問題のある点を削除あるいは修正するために何らかの処理を行う必要がある.

このデータ集合において有効なデータ入力は,第1要素には1あるいは2のいずれか,2番目と3番目の要素には数値という形である.この型のデータのパターンは,{1|2, _?NumberQ, _?NumberQ}である.「|」の記号は選択肢を表し,第1要素は1あるいは2でなければならない.NumberQは引数が数字であるかどうかを検証し,_?NumberQは数に対するパターンである.このパターンをMatchQおよびNotと使って悪いデータ点を識別する関数を書く.

この関数は,入力がパターンに合うかどうかをチェックすることによってそのような点を識別する.入力がパターンに合わない場合はTrueを返す:

無効なデータ点を削除するために,_?baddataDeleteCasesのパターンとして使うことができる:

データ点を完全に削除してしまう代りに,他のデータ点に基づく推定値で無効な値を置き換えた方がよい場合もよくある.しかし,この場合のデータ集合では,グループ4という入力はランダムに1 か2を選んで置き換えることしかできない.このような場合には,やはりデータ点を削除した方がよいかもしれない.

入力の第1要素が1か2であることをチェックすることによって,グループ番号の入力が無効であるかどうかを見極める関数である badgroupを定義する:

パターン_?badgroupDeleteCasesと一緒に使って,無効なグループの値を持つデータ点を削除する:

第3列で"NA"がデータを持たない唯一の入力であり,これはグループ1に属するため,グループ1のその他の第3列のデータ点すべての平均値か中央値でこの入力を置き換えることができる.

グループの平均で置き換えることは,グループ1のデータ点を選び,数字である第3要素について平均を計算し,"NA"をその平均値で置き換えることによって,直接行うことが可能である.

Selectを使ってグループ1からデータ点を取り出す:

もう一度Selectを使ってgroup1データの最終要素(第3列)から数を取り出してから,その平均を計算する:

今度は置換規則を使って"NA"を平均値で置き換える:

Gridを使ってフィルタをかけたデータを表示する:

上のステップは,まだ手作業をかなり行う必要がある.代りに,列に含まれるすべての無効な入力を別の列の値に基づいた値で置き換えることができるような関数を書くことができる.そしてこの関数を使ってデータ集合の各列を処理することができる.

以下の関数はデータ集合,処理する列の番号,グループ化後の列の番号,関数を引数として取る.この関数は,処理される列の要素をグループ化する列の値でグループ分けし,その列にある非数値をすべて,列内の要素に適用される関数の結果で置き換える:

まず,グループ4の項目を削除して,もとのデータを定義する:

列3の非数値項目をその関連するグループの平均値で置き換える:

列3の非数値項目をその関連するグループの中央値で置き換えることもできる:

その後Tableを使って列ごとにデータ集合を処理することができる.TransposeGridと一緒に使って新しくきれいにされた結果を表形式で表示する.以下の例ではグループの平均値を置換値として使っている:

関数は1つの列に働くように設定されているため,それぞれの列に対して異なる推定値を使うことができる.

以下では,第2列の無効要素がその列のそれぞれのグループの平均値で置き換えられ,第3列の無効要素はその列のそれぞれのグループの中央値で置き換えられている: