【解説】正規化(z-score, Min-Max normalization)を実装 | データサイエンス100本ノック【問59〜60 回答】
当ページのリンクには広告が含まれています。
この記事の対象者
・ 正規化とはなにかをコードを書きながら理解したい人
以降はデータサイエンス100本ノックの問題を題材にしながら学んでいきます。
データサイエンス100本ノックの始め方は、以下の記事を参考にしていただければと思います。
第59問目: 標準化
P-059: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、合計した売上金額を平均0、標準偏差1に標準化して顧客ID、売上金額合計とともに表示せよ。標準化に使用する標準偏差は、不偏標準偏差と標本標準偏差のどちらでも良いものとする。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。結果は10件表示させれば良い。
まず「標準偏差」とは何かを解説します。
標準偏差とは、偏差の2乗の合計値の平均に平方根を取った値です。
???と思った方のために分かりやすい例で解説します。
A | B | C | D | 合計 | |
---|---|---|---|---|---|
長さ | 5 | 12 | 11 | 17 | 45 |
偏差(長さ-長さの平均) 長さの平均=11.25 |
-6.25 | 0.75 | -0.25 | 5.75 | 0 |
偏差の2乗 | 39.0625 | 0.5625 | 0.0625 | 33.0625 | 72.75 |
このようなデータフレームがあった場合、A、B、C、Dの長さの標準偏差は72.75を4で割った値(18.1875)の平方根をとった、4.26となります。
この値が何を表しているかというと、「AからDまでの値がどれだけバラバラなのか」を定量的に示しているのです。
このとき、平均値が0、標準偏差が1になるようにデータを変換することを、標準化(z-score normalization)と呼びます。
数式で書くと以下となります。(µは平均、σは標準偏差です。)
なんのために標準化をするのかというと、異なる種類のデータを1つの尺度にまとめるためです。
これを正規化といいます。
ここで扱うz-score normalizationというのは正規化の手法の1つといえます。
Pythonで標準化を行うにはsklearn.preprocessing.StandardScalerクラスを使用します。
早速本問を解きながら使い方を学んでいきましょう。
まずはdf_receipt
の構造を確認します。
1 | df_receipt.head(5) |
1 | sales_ymd sales_epoch store_cd receipt_no receipt_sub_no customer_id product_cd quantity amount |
問題文より、df_receiptのcustomer_id
で”Z”から始まるものをqueryメソッドを用いて除外し、groupbyメソッドを用いてcustomer_idごとの売上金額(amount
)の合計を算出します。
engine='pytnon'
とreset_index
の付与を忘れずに行いましょう。
1 | df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').agg({'amount':'sum'}).reset_index() |
1 |
|
標準化を行うためにSrtandardScalerクラスのインスタンスを作成します。
1 | scaler = preprocessing.StandardScaler() |
作成したインスタンスを用いて標準化を行います。処理の方法は以下のコードのように、標準化に変換するインスタンス(変換モデル)にdf_sales_amount[['amount]]
のデータを用いて学習させます。
学習はfit
を使用します。
1 | scaler.fit(df_sales_amount[['amount']]) |
変換モデルに基づいて標準化処理を行い、標準化したデータを新たに作成するamount_ss
というカラムに格納します。
1 | df_sales_amount['amount_ss'] = scaler.transform(df_sales_amount[['amount']]) |
1 | customer_id amount amount_ss |
これで完了です。
第60問目: Min-Max正規化
P-060: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、合計した売上金額を最小値0、最大値1に正規化して顧客ID、売上金額合計とともに表示せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。結果は10件表示させれば良い。
最小値を0、最大値を1となるようにデータを変換することをMin-Max正規化と言います。
Min-Max正規化を行う場合は、sklearn.preprocessing.MinMaxScalerクラスを使用します。
数式で表現すると以下のようになります。
本問を解きながら使い方を学んでいきましょう。
まずは顧客IDがZから始まるものを除外し、売上金額(amount
)を顧客ID(customer_id
)ごとに合計したデータ算出します。
1 | df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').agg({'amount':'sum'}).reset_index() |
1 | customer_id amount |
MinMaxScalerクラスのインスタンスを生成します。
1 | scaler = preprocessing.MinMaxScaler() |
作成したインスがん(変換モデル)をamountデータを用いて学習させます。
1 | scaler.fit(df_sales_amount[['amount']]) |
MinMax正規化したデータを”amount_mm”というカラムに代入します。
1 | df_sales_amount['amount_mm'] = scaler.transform(df_sales_amount[['amount']]) |
1 | customer_id amount amount_mm |
これで完成です。
まとめ: 正規化を学びました
本記事は、「【Python】正規化(z-score, Min-Max normalization)を実装 | データサイエンス100本ノック【問59〜60 回答】」というテーマでまとめました。
本記事で紹介した方法を元にデータサイエンティストとしての知見を深めていただければと思います。
なお、データサイエンティストに必要な知識は、TechAcademyのデータサイエンスコースでの学習がおすすめです。