【解説】データサイエンス100本ノック【問77〜78 回答】

【解説】データサイエンス100本ノック【問77〜78 回答】



目次


データサイエンス100本ノックの始め方は、以下の記事を参考にしていただければと思います。


>>データサイエンス100本ノックの始め方を確認する


第77問目: 外れ値・異常値(外れ値除外)

外れ値とは、他の値から大きく外れた値のことです。

外れ値を検出する手順は以下の2stepです

  1. 標準化する
  2. 平均値からある閾値以上離れたデータを抽出する

本問を解きながら具体的な流れを確認しましょう。

まずは、df_receiptの売上金額(amount)を顧客ID(customer_id)ごとに合計したデータを代入します。

文字の前方一致(カラム名.str.startswith)について確認する

groupbyメソッドを確認する

1
2
df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').agg({'amount':'sum'}).reset_index()
df_sales_amount.head(10)
出力
1
2
3
4
5
6
7
8
9
10
11
customer_id	amount
0 CS001113000004 1298
1 CS001114000005 626
2 CS001115000010 3044
3 CS001205000004 1988
4 CS001205000006 3337
5 CS001211000025 456
6 CS001212000027 448
7 CS001212000031 296
8 CS001212000046 228
9 CS001212000070 456

標準化を行います。

標準化はStandardScalerクラスを使用して行います。

1
2
3
4
scaler = preprocessing.StandardScaler()
scaler.fit(df_sales_amount[['amount']])
df_sales_amount['amount_ss'] = scaler.transform(df_sales_amount[['amount']])
df_sales_amount
1
2
3
4
5
6
7
8
9
10
11
12
13
	customer_id	amount	amount_ss
0 CS001113000004 1298 -0.459378
1 CS001114000005 626 -0.706390
2 CS001115000010 3044 0.182413
3 CS001205000004 1988 -0.205749
4 CS001205000006 3337 0.290114
... ... ... ...
8301 CS051212000001 336 -0.812988
8302 CS051513000004 551 -0.733959
8303 CS051515000002 265 -0.839086
8304 CS052212000002 192 -0.865919
8305 CS052514000001 178 -0.871065
8306 rows × 3 columns

問題の指定通り、平均から3σ以上離れたものを10件抽出します。

1
df_sales_amount.query('abs(amount_ss) >= 3').head(10)
出力
1
2
3
4
5
6
7
8
9
10
11
	customer_id	amount	amount_ss
332 CS001605000009 18925 6.019921
1755 CS006415000147 12723 3.740202
1817 CS006515000023 18372 5.816651
1833 CS006515000125 12575 3.685800
1841 CS006515000209 11373 3.243972
1870 CS007115000006 11528 3.300946
1941 CS007514000056 13293 3.949721
1943 CS007514000094 15735 4.847347
1951 CS007515000107 11188 3.175970
1997 CS007615000026 11959 3.459372

これで完了です。

第78問目: 外れ値・異常値(四分位点範囲を利用した外れ値判定)

P-078: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客単位に合計し、合計した売上金額の外れ値を抽出せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。なお、ここでは外れ値を第一四分位と第三四分位の差であるIQRを用いて、「第一四分位数-1.5×IQR」よりも下回るもの、または「第三四分位数+1.5×IQR」を超えるものとする。結果は10件表示させれば良い。

四分位点とは、データを4分の1に分割する分位点のことです。

四分位数については、以下の記事で詳しく説明しています。

>> 【解説】四分位点を学ぶ | データサイエンス100本ノック【問55 回答】 - omathin blog

外れ値を判定する際に、IQR(四分位範囲)を利用する方法があります。

IQRとは、第一四分位Q1と第三四分位Q3の差を取ったものです。

一般的に、このIQRを使用して「第一四分位数-1.5×IQR」より下回るものと「第三四分位数+1.5×IQR」を超えるものを外れ値として考えます。

実際に本問を解きながら外れ値の算出をしてみたいと思います。

まずは、df_receiptの売上金額(amount)を顧客ID(customer_id)ごとに合計したデータをsf_sales_amountに代入します。

1
2
df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').agg({'amount':'sum'}).reset_index()
df_sales_amount.head(10)
出力
1
2
3
4
5
6
7
8
9
10
11
	customer_id	amount
0 CS001113000004 1298
1 CS001114000005 626
2 CS001115000010 3044
3 CS001205000004 1988
4 CS001205000006 3337
5 CS001211000025 456
6 CS001212000027 448
7 CS001212000031 296
8 CS001212000046 228
9 CS001212000070 456

第一四分位数と第三四分位数を求めます。

1
2
3
4
pct75 = np.percentile(df_sales_amount['amount'], q=75)
pct25 = np.percentile(df_sales_amount['amount'], q=25)
print("第三四分位数:" , pct75)
print("第一四分位数:" , pct25)
出力
1
2
3
4
5
6
7
8
9
10
11
	customer_id	amount
98 CS001414000048 8584
332 CS001605000009 18925
549 CS002415000594 9568
1180 CS004414000181 9584
1558 CS005415000137 8734
1733 CS006414000001 9156
1736 CS006414000029 9179
1752 CS006415000105 10042
1755 CS006415000147 12723
1757 CS006415000157 10648

これで完成です。

まとめ: データサイエンス100本ノック【問77〜78 回答】で外れ値・異常値判定を学びました

本記事で紹介した方法を元にデータサイエンティストとしての知見を深めていただければと思います。

なお、データサイエンティストに必要な知識は、Udemyを活用した学習が効率的です。30日間の返金保証、および一流講師へのQ&Aシステムが整ったオンライン学習プラットフォームです。

不定期で90%以上の割引セールも行っているので無料会員登録だけでも実施しておくといいと思います。

世界で34万人が受講した以下の講座をご確認ください。

【世界で34万人が受講】データサイエンティストを目指すあなたへ〜データサイエンス25時間ブートキャンプ〜

コメント