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

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

当ページのリンクには広告が含まれています。


目次


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


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


第75問目: サンプリング(ランダムにサンプリング)

P-075: 顧客データフレーム(df_customer)からランダムに1%のデータを抽出し、先頭から10件データを抽出せよ。

データフレームの行や列からランダムにデータを抽出する場合、sampleメソッドを使用します。

引数としてfracを用いて、ランダムに何%抽出するかを指定することができます。

random_stateは、乱数を制御するパラメータで、実行結果を常に同じにするための設定になります。特に指定がなければ任意の数値にすればOKです。

以下、サンプルコードです。

1
2
3
4
5
import pandas as pd

sample_data = list(range(100))
df = pd.DataFrame(sample_data)
df.sample(frac=0.1, random_state=0)
出力
1
2
3
4
5
6
7
8
9
10
11
12

0
26 26
86 86
2 2
55 55
75 75
93 93
16 16
73 73
54 54
95 95

この前提知識をもとに、本問を解いていきたいと思います。

今回は、ランダムに1%のデータを抽出するため、frac=0.01とします。

1
2
df_result = df_customer.sample(frac=0.01, random_state=0)
df_result.head(10)
出力
1
2
3
4
5
6
7
8
9
10
11
	customer_id	customer_name	gender_cd	gender	birth_day	age	postal_cd	address	application_store_cd	application_date	status_cd
13517 CS005513000263 大野 はるみ 1 女性 1959-02-13 60 165-0035 東京都中野区白鷺********** S13005 20170420 0-00000000-0
13442 CS026513000233 本上 愛梨 1 女性 1965-02-28 54 253-0022 神奈川県茅ヶ崎市松浪********** S14026 20150523 2-20090503-5
10188 CS009301000001 目黒 慶二 0 男性 1984-08-13 34 152-0035 東京都目黒区自由が丘********** S13009 20150323 0-00000000-0
13413 CS034612000080 成海 里奈 1 女性 1954-08-12 64 213-0013 神奈川県川崎市高津区末長********** S14034 20141208 0-00000000-0
21900 CS028314000040 堤 夏希 1 女性 1986-08-03 32 246-0038 神奈川県横浜市瀬谷区宮沢********** S14028 20151105 3-20080524-5
9066 CS034413000147 平尾 恵子 1 女性 1958-01-16 61 211-0013 神奈川県川崎市中原区上平間********** S14034 20160121 4-20080414-5
4934 CS001312000261 波多野 恵梨香 1 女性 1987-04-07 31 210-0022 神奈川県川崎市川崎区池田********** S13001 20160502 0-00000000-0
5129 CS030503000037 梅本 悟志 9 不明 1964-09-07 54 272-0823 千葉県市川市東菅野********** S12030 20150529 0-00000000-0
641 CS038705000005 加藤 芳正 0 男性 1940-03-18 79 279-0004 千葉県浦安市猫実********** S13038 20151130 0-00000000-0
16973 CS031414000049 大後 めぐみ 1 女性 1972-06-07 46 151-0071 東京都渋谷区本町********** S13031 20150427 C-20100827-E

これで完成です。

第76問目; サンプリング(層化)

P-076: 顧客データフレーム(df_customer)から性別(gender_cd)の割合に基づきランダムに10%のデータを層化抽出データし、性別ごとに件数を集計せよ。

層化抽出というのは、元のデータを同じ分布でランダムに抽出することを言います。

例えば、果物グループのデータがデータ全体の8割、野菜グループのデータがデータ全体の2割を締めていたとしましょう。

データからランダムに5つのデータを抽出する時に、果物グループのデータを4つ(8割)、野菜グループのデータを1つ(2割)抽出するようにするイメージです。

層化抽出は、sklearn.model_selection.train_test_split関数を使用します。

サンプルデータを用いて実際にコードを書きながら使い方を確認してみましょう。

まずはsampleメソッドを使用してランダムに抽出してみます。

1
2
3
4
5
6
7
import pandas as pd

columns = ['name', 'group']
data = [['banana', 0], ['apple', 0], ['mango', 0], ['grape', 0], ['tomato', 1], ['melon', 0], ['peach', 0], ['water-melon', 0], ['cherry', 0], ['broccoli', 1]]

df = pd.DataFrame(data, columns=columns)
df.sample(frac=0.5, random_state=0)
出力
1
2
3
4
5
6
	name	group
2 mango 0
8 cherry 0
4 tomato 1
9 broccoli 1
1 apple 0

このように元データと同じ分布でランダムに抽出ができません。

次に層化抽出を行ってみます。

1
2
_, df_tmp = train_test_split(df, test_size=0.5, stratify=df['group'], random_state=0)
df_tmp
出力
1
2
3
4
5
6
	name	group
5 melon 0
0 banana 0
6 peach 0
9 broccoli 1
3 grape 0

この層化抽出は、機械学習を行う際の訓練データとテストデータに分ける際によく使用されます。

例えば、訓練データとしてdf_train, テストデータとしてdf_testというデータフレームに分けたい場合は以下のような具合になります。

1
2
df_train, df_test = train_test_split(df, test_size=0.5, stratify=df['group'], random_state=0)
df_train
出力
1
2
3
4
5
6
	name	group
2 mango 0
8 cherry 0
4 tomato 1
7 water-melon 0
1 apple 0
1
df_test
出力
1
2
3
4
5
6
	name	group
5 melon 0
0 banana 0
6 peach 0
9 broccoli 1
3 grape 0

ここまでの前提知識を踏まえて問題を解いていきましょう。

1
2
_, df_tmp = train_test_split(df_customer, test_size=0.1, stratify=df_customer['gender_cd'], random_state=0)
df_tmp
出力
1
2
3
4
5
6
7
8
9
10
11
12
13
14

customer_id customer_name gender_cd gender birth_day age postal_cd address application_store_cd application_date status_cd
1345 CS016513000124 緒方 薫 1 女性 1959-05-14 59 184-0014 東京都小金井市貫井南町********** S13016 20150313 7-20100118-9
5763 CS040402000021 越智 輝信 0 男性 1975-10-12 43 226-0016 神奈川県横浜市緑区霧が丘********** S14040 20151113 0-00000000-0
14039 CS004313000451 保坂 涼 1 女性 1985-02-05 34 165-0032 東京都中野区鷺宮********** S13004 20170630 0-00000000-0
9631 CS014515000248 亀山 恵梨香 1 女性 1962-09-30 56 264-0035 千葉県千葉市若葉区東寺山町********** S12014 20170801 0-00000000-0
2374 CS005412000415 西谷 コウ 1 女性 1970-06-24 48 166-0001 東京都杉並区阿佐谷北********** S13005 20180121 7-20100419-8
... ... ... ... ... ... ... ... ... ... ... ...
306 CS027213000025 米倉 朝香 1 女性 1978-11-11 40 167-0021 東京都杉並区井草********** S14027 20150707 0-00000000-0
1786 CS011511000019 永井 佳乃 1 女性 1959-04-07 59 211-0013 神奈川県川崎市中原区上平間********** S14011 20150314 3-20101004-3
16819 CS012613000093 塩田 美帆 1 女性 1956-09-06 62 231-0826 神奈川県横浜市中区本牧荒井********** S14012 20160212 3-20100802-3
3832 CS009315000193 小沼 さやか 1 女性 1985-01-06 34 158-0096 東京都世田谷区玉川台********** S13009 20170307 0-00000000-0
753 CS031501000026 真鍋 耕司 0 男性 1965-10-02 53 150-0013 東京都渋谷区恵比寿********** S13031 20180227 0-00000000-0
2198 rows × 11 columns

問題文より、性別ごとに件数を集計します。

性別ごとの集計は、groupbyメソッドとaggメソッドでcountを指定すれば集計できます。

1
df_tmp.groupby('gender_cd').agg({'customer_id' : 'count'})
出力
1
2
3
4
5
6

customer_id
gender_cd
0 298
1 1793
9 107

これで集計完了です。

まとめ: データサイエンス100本ノック【問75〜76 回答】でサンプリングを学びました

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

なお、データサイエンティストに必要な知識は、TechAcademyのデータサイエンスコースでの学習がおすすめです。

コメント