Python × Power BI について、データ準備編とビジュアル編に分けて取り上げたところですが、
やはり忘れてならないのは前処理の話です。
本記事は、Microsoft Power BI Advent Calendar 2018として、Power BI × Pythonの前処理、データ加工について少しだけ取り上げます。
データの前処理
データ分析を本業にする人にとって、前処理の過程は避けて通れません。
いわゆる政府が公開するオープンデータもこんな感じなケースは多々あります。
Vital Statistics_Vital statistics of Japan_Final data_Population_Yearly_2017
また、マイナスをゼロにするだけでなく、データの価値をプラスにする処理必要です。
機械学習で汎化性能の高いモデルを作るためのダミー化、正規化、欠損処理、
因子分析や主成分分析など、変数の生成・統合、
データの前処理は分析者にとって永遠の課題です。
前処理としてのPowerQuery
Power BI Desktopでは、Power Queryによるデータ加工が基本機能であり、大変高機能です。
Power Queryの詳細はこちら
https://support.office.com/ja-jp/article/microsoft-power-query-for-excel-%E3%81%AE%E6%A6%82%E8%A6%81-6e92e2f4-2079-4e1f-bad5-89f6269cd605
しかし、PowerQueryのみだと少し厄介な処理などは、RやPythonのライブラリに頼ることもできるかもしれません。
そこで、Pythonのpandas、sikit-learnライブラリを利用した利便性の高いデータ前処理を、いくつかPower BIで実践します。
Pythonによるデータ加工
Power BIでPythonによるデータ加工を行う場合、基本はクエリエディター上でPythonの実行処理を以下から行います。
ビジュアル作成と同じく、データモデルがdataset(pandas.DataFrame)
に格納されています。
加工後のデータフレームを何らかの変数に指定すれば処理後の内容をデータモデルにすることができる仕組みです。
ダミー変数化
カテゴリデータを0,1にフラグ化し、数量的に解析できるようにするダミー変数処理はデータ加工に欠かせません。
pandas
のライブラリに頼り処理してみます。
利用するデータセットは、UCI Machinelearning RepositoryのBankMarketing Datasetを利用します。
このデータフレームのjob
は12個の値をもっており、すべて文字列データであることが分かります。
クエリエディター上で、以下のようにPythonの処理をかませます。
※以下pandas
とsklearn
のインポートコードは省略しています。
new_df = pandas.get_dummies(dataset["job"])
pythonのライブラリを利用すれば、コード1行で面倒なダミー化も実行可能です。
ラベル作成
続いて、文字列データを数値に置き換えるラベルエンコーダーを試します。
Power BIは文字データも比較的高速ですし、解析には前述のダミー化のほうが利用価値が高いですが、
比較的面倒な処理をローコーディングで実現できます。
le = sklearn.preprocessing.LabelEncoder()
le.fit(bank["job"])
bank["new_job"] = le.transform(bank["job"])
欠損処理
データ加工において比較的ウェイトが高い課題が欠損処理です。
NULLを特定規則で置き換えるのみならPower BI単体で楽に実行可能ですが、
1レコードずつ、欠損個所の尤もらしい値を代入することは容易ではありません。
そこで、Pythonの機械学習ライブラリを頼り、回帰代入してしまおうということです。
※欠損処理については、Rを利用したほうがより推奨される多重代入という手法が利用できるので、わかるようであればそちらのほうがおススメされます。
※以下はあえてBankMarketingDatasetのbalance
カラムに欠損を生じさせたデータを利用しています。
regr = sklearn.linear_model.LinearRegression()
df = pd.get_dummies(dataset["job"])
df["age"] = dataset["age"]
df["balance"] = dataset["balance"]
df_1 = df.dropna(subset=['balance'])
df_2 = df[df["balance"].isnull()]
regr.fit(df_1.drop(["balance"],axis=1)
, df_1["balance"])
pred = regr.predict(df_2.drop(["balance"],axis=1))
df_2 = df_2.reset_index().drop("index",axis=1)
df_2["balance"] = pandas.Series(pred)
df = pd.concat([df_1,df_2],ignore_index=True)
無事、欠損値が推定されているのが確認できました。
おわりに
以上のように、Pythonを利用することで、ライブラリの恩恵を楽に受けることができます。
ただし、実行の重さや個々の実行環境に依存するため共有しずらいことなど、考慮して運用しなければならないのが現状です。