カテゴリデータの処理
Contents
カテゴリデータの処理#
本節ではpandasを利用したカテゴリデータの処理方法を学びます。
データ(変数)は質的変数(カテゴリ変数)、量的変数(連続変数)に分類されます。
量的変数は数や量で測れる変数で、間隔尺度と比例尺度に分類されます。
- 間隔尺度
気温や順位など、和や差に意味があるが比率には意味がない尺度(0の意味がない)
- 比例尺度
身長や重さなど、和や差、比率に意味がある尺度
質的変数は離散的な値をとり、数値では表現できない変数で、名義尺度と順序尺度に分類されます。
- 名義尺度
血液型や性別など、和や差、比率に意味がなく、比較ができない尺度
- 順序尺度
震度や企業格付など、比較できるが、和や差、比率に意味がない尺度
import pandas as pd
import plotly.express as px
tips = px.data.tips()
tips.head()
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
Category型#
tips
オブジェクトの「sex」列、「smoker」列は名義尺度のため、カテゴリ変数として扱います。Seriesではカテゴリ変数を扱うCategory型が利用できます。
sex = tips.loc[:, "sex"].astype("category")
sex.dtype
CategoricalDtype(categories=['Female', 'Male'], ordered=False)
smoker = tips.loc[:, "smoker"].astype("category")
smoker.dtype
CategoricalDtype(categories=['No', 'Yes'], ordered=False)
tips
オブジェクトの「day」列は名義尺度のため、カテゴリ変数として扱います。Category型の生成時に順序を付けられます。
day_of_week = pd.CategoricalDtype(
categories=["Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"],
ordered=True
)
day = tips.loc[:, "day"].astype(day_of_week)
day
0 Sun
1 Sun
2 Sun
3 Sun
4 Sun
...
239 Sat
240 Sat
241 Sat
242 Sat
243 Thur
Name: day, Length: 244, dtype: category
Categories (7, object): ['Sun' < 'Mon' < 'Tue' < 'Wed' < 'Thur' < 'Fri' < 'Sat']
順序が付いたCategory型のSeriesは sort_value
メソッドによるソートが行えます。
day.sort_values()
0 Sun
172 Sun
173 Sun
174 Sun
175 Sun
...
64 Sat
65 Sat
66 Sat
56 Sat
57 Sat
Name: day, Length: 244, dtype: category
Categories (7, object): ['Sun' < 'Mon' < 'Tue' < 'Wed' < 'Thur' < 'Fri' < 'Sat']
カテゴリデータの変数変換#
機械学習などのモデルによっては、質的変数を数値に変換する必要があります。 get_dummies
関数では文字列やカテゴリデータを数値に変換します。
pd.get_dummies(smoker)
No | Yes | |
---|---|---|
0 | 1 | 0 |
1 | 1 | 0 |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 1 | 0 |
... | ... | ... |
239 | 1 | 0 |
240 | 0 | 1 |
241 | 0 | 1 |
242 | 1 | 0 |
243 | 1 | 0 |
244 rows × 2 columns
pd.get_dummies(day)
Sun | Mon | Tue | Wed | Thur | Fri | Sat | |
---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
... | ... | ... | ... | ... | ... | ... | ... |
239 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
240 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
241 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
242 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
243 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
244 rows × 7 columns
pd.get_dummies(tips.loc[:, "time"])
Dinner | Lunch | |
---|---|---|
0 | 1 | 0 |
1 | 1 | 0 |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 1 | 0 |
... | ... | ... |
239 | 1 | 0 |
240 | 1 | 0 |
241 | 1 | 0 |
242 | 1 | 0 |
243 | 1 | 0 |
244 rows × 2 columns
pd.get_dummies(tips.loc[:, ["sex", "smoker"]])
sex_Female | sex_Male | smoker_No | smoker_Yes | |
---|---|---|---|---|
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 1 | 0 |
2 | 0 | 1 | 1 | 0 |
3 | 0 | 1 | 1 | 0 |
4 | 1 | 0 | 1 | 0 |
... | ... | ... | ... | ... |
239 | 0 | 1 | 1 | 0 |
240 | 1 | 0 | 0 | 1 |
241 | 0 | 1 | 0 | 1 |
242 | 0 | 1 | 1 | 0 |
243 | 1 | 0 | 1 | 0 |
244 rows × 4 columns
カテゴリデータの分析#
質的変数を数値に変換することで、回帰分析などの分析が行えます。
次のコードでは散布図行列に可視化し、2変数の関係を可視化しています。
tips_converted = pd.concat(
[
tips.select_dtypes(include=["int", "float"]),
pd.get_dummies(tips.select_dtypes(exclude=["int", "float"]))
],
axis=1
)
px.scatter_matrix(tips_converted, height=1200)
/home/vscode/.local/lib/python3.11/site-packages/plotly/express/_core.py:279: FutureWarning:
iteritems is deprecated and will be removed in a future version. Use .items instead.
tips_converted.corr()
total_bill | tip | size | sex_Female | sex_Male | smoker_No | smoker_Yes | day_Fri | day_Sat | day_Sun | day_Thur | time_Dinner | time_Lunch | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
total_bill | 1.000000 | 0.675734 | 0.598315 | -0.144877 | 0.144877 | -0.085721 | 0.085721 | -0.086168 | 0.054919 | 0.122953 | -0.138174 | 0.183118 | -0.183118 |
tip | 0.675734 | 1.000000 | 0.489299 | -0.088862 | 0.088862 | -0.005929 | 0.005929 | -0.055463 | -0.002790 | 0.125114 | -0.095879 | 0.121629 | -0.121629 |
size | 0.598315 | 0.489299 | 1.000000 | -0.086195 | 0.086195 | 0.133178 | -0.133178 | -0.142184 | -0.041121 | 0.193054 | -0.072598 | 0.103411 | -0.103411 |
sex_Female | -0.144877 | -0.088862 | -0.086195 | 1.000000 | -1.000000 | 0.002816 | -0.002816 | 0.071060 | -0.053957 | -0.168106 | 0.194445 | -0.205231 | 0.205231 |
sex_Male | 0.144877 | 0.088862 | 0.086195 | -1.000000 | 1.000000 | -0.002816 | 0.002816 | -0.071060 | 0.053957 | 0.168106 | -0.194445 | 0.205231 | -0.205231 |
smoker_No | -0.085721 | -0.005929 | 0.133178 | 0.002816 | -0.002816 | 1.000000 | -1.000000 | -0.244316 | -0.155744 | 0.181624 | 0.128534 | -0.054921 | 0.054921 |
smoker_Yes | 0.085721 | 0.005929 | -0.133178 | -0.002816 | 0.002816 | -1.000000 | 1.000000 | 0.244316 | 0.155744 | -0.181624 | -0.128534 | 0.054921 | -0.054921 |
day_Fri | -0.086168 | -0.055463 | -0.142184 | 0.071060 | -0.071060 | -0.244316 | 0.244316 | 1.000000 | -0.216319 | -0.195451 | -0.169608 | -0.058159 | 0.058159 |
day_Sat | 0.054919 | -0.002790 | -0.041121 | -0.053957 | 0.053957 | -0.155744 | 0.155744 | -0.216319 | 1.000000 | -0.500682 | -0.434480 | 0.462709 | -0.462709 |
day_Sun | 0.122953 | 0.125114 | 0.193054 | -0.168106 | 0.168106 | 0.181624 | -0.181624 | -0.195451 | -0.500682 | 1.000000 | -0.392566 | 0.418071 | -0.418071 |
day_Thur | -0.138174 | -0.095879 | -0.072598 | 0.194445 | -0.194445 | 0.128534 | -0.128534 | -0.169608 | -0.434480 | -0.392566 | 1.000000 | -0.917996 | 0.917996 |
time_Dinner | 0.183118 | 0.121629 | 0.103411 | -0.205231 | 0.205231 | -0.054921 | 0.054921 | -0.058159 | 0.462709 | 0.418071 | -0.917996 | 1.000000 | -1.000000 |
time_Lunch | -0.183118 | -0.121629 | -0.103411 | 0.205231 | -0.205231 | 0.054921 | -0.054921 | 0.058159 | -0.462709 | -0.418071 | 0.917996 | -1.000000 | 1.000000 |
px.imshow(
tips_converted.corr().values,
x=tips_converted.corr().columns,
y=tips_converted.corr().index,
text_auto=True,
width=800,
height=800
)