Ebook

第2章

一般的な前処理


機械学習アプリケーションに必要な前処理タスクは、使用しているデータの種類と選択したアルゴリズムの種類によって異なります。ただし、他と比べて、より一般的に実行されるタスクがあります。この章では、最も一般的な 5 種類のデータ前処理の手法と、MATLAB でそれらを実行する方法について説明します。

section

データの整形

多くの前処理タスクでは、データセットを何らかの方法で統一する必要があります。特にタイムスタンプ付きのデータに関しては、フォーマットの設定も含まれます。

データの形式の問題は、早期に対処しなければ時間を浪費する大きな問題を引き起こす可能性があります。これらの問題は必ずしもエラーを発生させるわけではないので、モデルの精度を暗に低下させている可能性があります。次の2つの関数は、タイムスタンプ付きデータの整形を簡単にします。

  • datetime
  • duration

時間の標準化およびオフセット

タイムスタンプ付きのデータを扱う場合、日付と時刻が一貫した形式で書かれていることを確認する必要があります。

datetime 配列は、時間を離散的に表現し、タイムゾーン、サマータイム、うるう秒を考慮できます。

Syntax

t = datetime
t = datetime(relativeDay)
t = datetime(DateStrings)
t = datetime(DateVectors)
t = datetime(Y,M,D)

持続時間

MATLABでは、経過時間を表すデータはduration配列で表されます。異なるデータロギングシステム、開始時刻のばらつき、およびその他の要因により、経過時間を測定する相対的なタイムスタンプに問題が生じる可能性があります。

duration 配列を使用して、開始時刻の異なるタスクがどれくらいの時間続いたかの比較、しきい値の設定、一貫性のある時間の長さ(例えば、10秒間隔の信号データなど)を作成することができます。

日付、時刻、およびカレンダー期間を使用する際の詳細の情報はこちらです。

Syntax

D = duration(H,MI,S)
D = duration(H,MI,S,MS)
D = duration(X)

section

結合

複数の場所のデータやデータセットを組み合わせることが、機械学習モデル構築を成功させる鍵となります。例えば、小売店のデータセットに気象データを追加すると、日焼け止めの売上を予測する機械学習モデルの精度が大幅に向上します。データセットを結合する一般的な方法は2つあります。

  • あるキー値に基づいて結合 - メールアドレスのような一意の識別子を活用
  • 時間に基づいて結合

キー値に基づく結合は、希望するタイプの結合 (joininnerjoin, outerjoin) のコマンドを使用するか、ライブエディター > タスク> tableの連結 を使用して実行できます。

Merging table example

時間に基づいた結合はtimetableとsynchronizeコマンドを使ってMATLABで実行可能です。同期されるタイムテーブルが全く同じタイム ステップを持っていない限り、特定の変数が測定されなかった時のタイム ステップで何が発生したか留意し処理する必要があることに注意してください。synchronize コマンドには、線形補間やスプライン補間の実行、測定が行われた最も近いタイム ステップから値をコピーするなど、この問題に対処するための多くの組み込みメソッドがあります。

タイムテーブルの結合

% 2つのサンプルtimetableをファイルからロードします。そして、
% それらのデータを新しい行の時刻のベクトルに同期させます。

load smallTT

% timetableを表示します。TT1は行の時間が順番通りに並んでいません。
% また、TT1とTT2では変数が異なります。

TT1
TT1=3×2 timetable
            Time            Temp
    ____________________    ____

    18-Dec-2015 12:00:00    42.3
    18-Dec-2015 08:00:00    37.3
    18-Dec-2015 10:00:00    39.1

TT2
TT2=3×2 timetable
         Time               Pressure
    ____________________    ________

    18-Dec-2015 09:00:00     30.1 
    18-Dec-2015 11:00:00    30.03 
    18-Dec-2015 13:00:00     29.9 

% TT1 と TT2 を同期させます。出力されるタイムテーブルTTには、
% 両方のtimetableからのすべての行時間がソートされた順番で含まれています。
% TTでは、TempにはTT2からの行時間のNaNが、PressureにはTT1からの行時間のNaNが含まれています。

TT = synchronize(TT1,TT2)
TT=6×3 timetable

    Time                    Temp    Pressure
    ____________________    ____    ________

    18-Dec-2015 08:00:00    37.3    NaN 
    18-Dec-2015 09:00:00     NaN    30.1 
    18-Dec-2015 10:00:00    39.1    NaN 
    18-Dec-2015 11:00:00     NaN    30.03 
    18-Dec-2015 12:00:00    42.3    NaN 
    18-Dec-2015 13:00:00     NaN    29.9

このコマンドをMATLABに貼り付けて、次の例を試してみてください。

openExample('matlab/SynchronizeTimetablesAndInsertMissingDataIndicatorsExample')

MATLABコマンドウィンドウに入力してコマンドを実行します。Webブラウザ版ではMATLABコマンドをサポートされていません。

section

欠損データの処理

機械学習アルゴリズムは、データ内の特徴と、それらの特徴がどのように相互に関連しているかに基づいて予測を行います。観測の中でデータが欠損している場合、特徴間の関係を見つけることはより困難になります。データが欠損している場合、データを削除するか置き換えるかの意思決定は、観測の中で欠損している変数が見つかるかどうかに依存する場合があります。

機械学習のためにデータを準備するとき、欠損データの扱いについて、3つのオプションがあります:削除(観測値、または列全体)、置換、または何もせずにモデルに任せて処理を実行。そのオプションは、なぜ、そのデータが欠損しているのかによって決まります。

欠損データがランダムであるかどうかを確認するには、各変数を描画してパターンを探します。

欠損した値は、そのデータ型に従ってMATLABで表現されます。例えば、欠損した数値は NaN、日付時刻は NaT、カテゴリカルは <undefined>、欠損している文字列は <missing> と表示されます。

次の例では、3 つの列を持つ 500 件のアンケート回答 (SurveyAges) のテーブル内で欠損しているデータを探します。回答者 ID、年齢、および経験年数です。欠損値があるかどうかとその位置を確認しましょう。

欠損データの確認

A = SurveyAges(:,2)
Tf = ismissing(A)
G = sum(Tf)

この結果、1 と 0 の論理配列が得られ、1 はデータが欠損していることを意味します。この場合、G = 36; 不足している回答の総数です。

Syntax

Tf = ismissing(A)
Tf = ismissing(A,indicator)

Missing data, live task

一般的に、データがランダムに欠落している場合は削除しても問題ありません。この例のデータをプロットすると、欠損データがより高い年齢層でより多く発生していることがわかります。

欠損データがランダムではない場合(例えば、年配の従業員は年齢を開示したくない場合など)、そのデータを削除するとバイアスが発生する可能性があります。この場合は、生成されたデータでこれらを埋めることができます。これらの値を埋めるためにどの方法を使用するかは、データによって異なります。一般的な手法には、平均、中央値、モード、線形回帰、およびK最近傍があります。時系列データを使用している場合、追加の手法として、最後の観測値の前方への繰越、次の観測値の後方への繰越、線形補間があります。

MATLABには、欠損値を削除したり、埋めたりするために使用できる多くの関数があります。その中でも後述するfillmissingは、汎用性の高い関数です。

欠損データのクリーニング

列内の値がかなりの割合で欠損している場合は、データセットから列全体を削除するのが最善の方法かもしれません。

そのためには、ライブエディターのタスクを使用するのが簡単な手順です。他のタスクと同様に、ホームのツールストリップで 新規 ライブ スクリプト を選択します。

New Live Script example

ライブ エディター タブで click タスク をクリックし、 欠損データの削除 を選択します。

Live Task toolstrip example

これでユーザ・インターフェースが開きます。データを選択するために利用できるオプションは、ワークスペース内の変数によって異なります。

Clean missing data dialog

ドロップダウンメニューを使用して、検索したい欠損データを選択し、それらのエントリを埋めるか、削除するかを選択します。

section

外れ値の処理

外れ値の存在と頻度は、データの全体的な品質について多くのことを教えてくれます。外れ値が一様に分布しているか、クラスタ化されているか、あるいは他のパターンで存在するかは、それらをどのように対処するかに影響を及ぼします。外れ値がデータセットに占める割合が非常に小さく、不正確に見えたり、不適切なデータ収集の結果であったりする場合は、不良データとして取り除くのが無難かもしれません。しかし、いかなる場合においても、最初のステップはデータの中で外れ値を識別することです。

データの外れ値を見つけるために、多くの異なる統計モデルを適用することができます。一般的な方法としては、以下のようなものがあります。

  • グラブス検定
  • 中央値
  • 移動平均法
  • 四分位数

どの方法を使うにしても、データの最小値、最大値、平均値、標準偏差に慣れておく必要があります。

MATLABには、データ内の外れ値を見つけるために使用できる組み込み関数が多数あります。また、File Exchangeでは、データ系列内の外れ値を特定するためのテストなど、このタスクを簡略化するためのファイルも利用できます。

外れ値を除去することのリスクは高いですが、外れ値をそのままにしておくと、結果が大きく歪んでしまうことがあります。MATLABで外れ値を処理する方法は、プログラムでコマンド ラインを使用する方法、ライブエディターを使用して対話的に処理する方法、その他にも多くの方法があります。ここでは、それぞれの方法を簡単に説明します。

Outlier Detection Using Qunatile Regression

コマンドライン

MATLABのfilloutliers 関数は、外れ値を識別し、自動でそれらを置き換えるための便利なツールです。

外れ値を埋めるメソッド には、 'previous''linear'、および'spline'があります。

ここに簡単な例を示します。

Afill = filloutliers(Anoise,'next');
plot(t,Anoise,t,Afill)
axis tight
legend('Noisy Data with Outlier','Noisy Data with Filled
Outlier') 

Syntax

B = filloutliers(A,fillmethod)
B = filloutliers(A,fillmethod, findmethod)
B = filloutliers(A,fillmethod, 'percentiles', threshold)
B = filloutliers(A,fillmethod, movmethod, window)
B = filloutliers(___,dim)
B = filloutliers(___,Name,Value)
[B,TF,L,U,C] = filloutliers(___)

外れ値を埋めるための多くのアプローチがあることを考えると、機械学習のアルゴリズムで外れ値を埋めたデータを学習する前に、結果を視覚的に検査することが重要です。

前もってデータをきれいにしておくことで、後でアルゴリズムを微調整するのに費やす時間を減らすことができます。

Fill outlier graph

ライブ エディター タスク

外れ値が含まれたデータをクリーンアップするためにライブ エディター タスクを使用する便利な側面の1つは、検出方法を選択するたびに、ユーザー インターフェースが外れ値の数を更新することです。

これは、3つの検出方法を使用した同じデータです。グラブスと平均はどちらも100未満の外れ値を返しますが、四分位数は1103個の外れ値を返しており、これはエントリの4分の1をわずかに超えています。

外れ値を消去するには、クリーニング メソッドを選択します。これらのオプションは コマンドラインにあるものと同じです。

変更を加えるとスクリプトが実行されるので、挙動はすぐに確認できます。

使用する外れ値メソッドを前処理スクリプトに追加し、スクリプトを保存します。

section

正規化

正規化は、特徴量の値の範囲が異なるが、各特徴量を同等に考慮したい場合に便利な手法です。

予知保全モデルを作成したいケースを想像してみてください。故障の予測因子を特定するために、振動周波数と圧力を記録するセンサーを使用します。簡単に言えば、正常な範囲からの変化は問題を示しているかも知れませんし、またその距離は問題の深刻度を示しているかもしれません。振動周波数の正常範囲は10~800Hzで、圧力の正常範囲は10~30psiのように見えるかもしれません。これらの測定値のそれぞれから得られた特徴量を同じモデルで使用できるようにするには、データセットを正規化してそれぞれの特徴量が等しく扱われる状況を用意する必要があります。

いつデータを正規化すべきか? 一般的には、異なる変数の絶対値または範囲の桁が異なる場合です。しかし、分析のために特徴量の単位が必要かどうかにもよります。正規化されていないデータは、データを「推論」することができるため、他の前処理を行っている間に役に立ちます。正規化は、多くの場合、フィーチャー・エンジニアリングの前に行う最後のステップの1つです。

Syntax

N = normalize(A)
N = normalize(A,dim)
N = normalize(___, method)
N = normalize(___, method, methodtype)
N = normalize(___, 'DataVariables', datavars)