

データサイエンティスト協会の100本ノックがGitHubに公開しているデータとPythonコードを初心者にでも分かるように解説していきます。
今回は52~57本です。内容は主に、データから新たなデータを作成する「特徴量エンジニアリング」について解説していきます。
Pythonの環境設定は以下の記事を参考にして下さい。
【2021年最新】M1 mac でanacondaをインストールする方法
【2021年最新】WindowsでAnacondaをインストールする方法
- 特徴量エンジニアリング
- -052: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計の上、売上金額合計に対して2000円以下を0、2000円超を1に2値化し、顧客ID、売上金額合計とともに10件表示せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。
- P-053: 顧客データフレーム(df_customer)の郵便番号(postal_cd)に対し、東京(先頭3桁が100〜209のもの)を1、それ以外のものを0に2値化せよ。さらにレシート明細データフレーム(df_receipt)と結合し、全期間において買い物実績のある顧客数を、作成した2値ごとにカウントせよ。
- P-054: 顧客データデータフレーム(df_customer)の住所(address)は、埼玉県、千葉県、東京都、神奈川県のいずれかとなっている。都道府県毎にコード値を作成し、顧客ID、住所とともに抽出せよ。値は埼玉県を11、千葉県を12、東京都を13、神奈川県を14とすること。結果は10件表示させれば良い。
- P-055: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、その合計金額の四分位点を求めよ。その上で、顧客ごとの売上金額合計に対して以下の基準でカテゴリ値を作成し、顧客ID、売上金額と合計ともに表示せよ。カテゴリ値は上から順に1〜4とする。結果は10件表示させれば良い。
- P-056: 顧客データフレーム(df_customer)の年齢(age)をもとに10歳刻みで年代を算出し、顧客ID(customer_id)、生年月日(birth_day)とともに抽出せよ。ただし、60歳以上は全て60歳代とすること。年代を表すカテゴリ名は任意とする。先頭10件を表示させればよい。
- P-057: 前問題の抽出結果と性別(gender)を組み合わせ、新たに性別×年代の組み合わせを表すカテゴリデータを作成せよ。組み合わせを表すカテゴリの値は任意とする。先頭10件を表示させればよい。
特徴量エンジニアリング
まずは、以下からダウンロードして下さい。
-052: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計の上、売上金額合計に対して2000円以下を0、2000円超を1に2値化し、顧客ID、売上金額合計とともに10件表示せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。
import pandas as pd df_receipt = pd.read_csv("receipt.csv") df_52 = df_receipt.query("not customer_id.str.startswith('Z')",engine="python") df_52 = df_52[["customer_id","amount"]].groupby("customer_id").sum().reset_index() df_52["sales"] = df_52["amount"].apply(lambda x: 1 if x>2000 else 0) df_52.head(10)
“sales” という新たなデータができました。このデータは、”amount” が 2000以上なら1、2000 未満なら0となっています。
別のコードでも同じ出力結果になります。
import numpy as np df_52 = df_receipt.query("not customer_id.str.startswith('Z')",engine="python") df_52 = df_52[["customer_id","amount"]].groupby("customer_id").sum().reset_index() df_52["sales"] = np.where(df_52["amount"]>2000,1,0) df_52.head(10)
コードの解説は以下の通りです。
このコードでも “amount” の連続変数を2値変数に変換したデータを作成できます。
P-053: 顧客データフレーム(df_customer)の郵便番号(postal_cd)に対し、東京(先頭3桁が100〜209のもの)を1、それ以外のものを0に2値化せよ。さらにレシート明細データフレーム(df_receipt)と結合し、全期間において買い物実績のある顧客数を、作成した2値ごとにカウントせよ。
df_customer = pd.read_csv("customer.csv") df_53 = df_customer[["customer_id","postal_cd"]].copy() df_53["postal_flg"] = df_53["postal_cd"].\ apply(lambda x: 1 if 100<=int(x[0:3])<=209 else 0) pd.merge(df_53,df_receipt,how="inner",on="customer_id").\ groupby("postal_flg").agg({"customer_id":"nunique"})
出力:
前半のコードは、郵便番号の先頭が100~209であった場合は1、それ以外であった場合は0としたデータを作成しています。
後半のコードは、買い物実績のある顧客のデータ数をカウントしています。
P-054: 顧客データデータフレーム(df_customer)の住所(address)は、埼玉県、千葉県、東京都、神奈川県のいずれかとなっている。都道府県毎にコード値を作成し、顧客ID、住所とともに抽出せよ。値は埼玉県を11、千葉県を12、東京都を13、神奈川県を14とすること。結果は10件表示させれば良い。
pd.concat([df_customer[["customer_id","address"]], df_customer["address"].str[0:3].map({"埼玉県":"11", "千葉県":"12", "東京都":"13", "神奈川":"14"})],axis=1).head(10)
“address” の文字データを数値に変更した新たなデータとしています。
P-055: レシート明細データフレーム(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、その合計金額の四分位点を求めよ。その上で、顧客ごとの売上金額合計に対して以下の基準でカテゴリ値を作成し、顧客ID、売上金額と合計ともに表示せよ。カテゴリ値は上から順に1〜4とする。結果は10件表示させれば良い。
- 最小値以上第一四分位未満
- 第一四分位以上第二四分位未満
- 第二四分位以上第三四分位未満
- 第三四分位以上
df_55 = df_receipt[["customer_id","amount"]].groupby("customer_id").sum().reset_index() pct25 = np.quantile(df_55["amount"], 0.25) pct50 = np.quantile(df_55["amount"], 0.5) pct75 = np.quantile(df_55["amount"], 0.75) def pct_group(x): if x < pct25: return 1 elif pct25 <= x < pct50: return 2 elif pct50 <= x < pct75: return 3 elif pct75 <= x: return 4 df_55["pct_group"] = df_55["amount"].apply(lambda x: pct_group(x)) df_55.head(10)
売上(amount)のパーセンタイル値を確認してみましょう。
# 確認用 print("pct25:",pct25) print("pct50:",pct50) print("pct75:",pct75)
出力:
pct25: 548.5
pct50: 1478.0
pct75: 3651.0
“amount” の数値のパーセンタイルに応じた “pct_group” のデータになっていることが確認できます。
P-056: 顧客データフレーム(df_customer)の年齢(age)をもとに10歳刻みで年代を算出し、顧客ID(customer_id)、生年月日(birth_day)とともに抽出せよ。ただし、60歳以上は全て60歳代とすること。年代を表すカテゴリ名は任意とする。先頭10件を表示させればよい。
import math df_56 = pd.concat([df_customer[["customer_id","birth_day"]], df_customer["age"].apply(lambda x: min(math.floor(x/10)*10,60))], axis=1) df_56.head(10)
P-057: 前問題の抽出結果と性別(gender)を組み合わせ、新たに性別×年代の組み合わせを表すカテゴリデータを作成せよ。組み合わせを表すカテゴリの値は任意とする。先頭10件を表示させればよい。
df_56["era_gender"] = df_customer["gender_cd"].astype("str") + df_56["age"].astype("str") df_56.head(10)
データサイエンティスト協会の100本ノックを解説|ダウンロードから読み込みまで
データサイエンティスト協会の100本ノックを解説|データの抽出
データサイエンティスト協会の100本ノックを解説|変数の一部を使ってデータを抽出する
データサイエンティスト協会の100本ノックを解説|ソート(順序で整列)
データサイエンティスト協会の100本ノックを解説|グループ分け
コメント