統計学で使うデータは大きく分けると「質的変数」と「量的変数」に分かれます。
-
- 質的変数:データがカテゴリで示されるもの
- 名義尺度:男女、電話番号(単に区別するだけ)
- 順序尺度:優、良、可など順位(大小関係に意味がある)
- 量的変数:データが数値で示されるもの
- 間隔尺度:値の順序に意味があり、さらに値の間隔が「等間隔」である尺度、気温など(数字の差に意味がある)
- 比例尺度:順序、等間隔という性質を持つ間隔尺度のうち、原点0が絶対的・自然数な意味で「無」という意味を持つ尺度。時間、密度、音量、身長、体重、年齢、製品シェア、収入額(数字の比が意味を持つ)
Pandasにはカテゴリ型という特別な型が存在します。 今回はPandasのカテゴリ型について学習します。
スタースキーマの活用
Pandasではデータベースで使われる手法がうまく使える仕組みになっています。 カテゴリ型もそうで、DWHにおけるスタースキーマの手法が使えます。つまりディメンジョンテーブルを活用することで計算効率を上げることを考慮しています。
スタースキーマとは
Pandasのカテゴリ型を使用しないで質的変数を取り扱う例
unique()関数
Seriesデータを作成
import numpy as np import pandas as pd values = pd.DataFrame({'天気':np.random.choice(['晴','曇り','雨'],10), '販売数':np.random.randint(10,100,10)}) values
結果
天気 | 販売数 | |
---|---|---|
0 | 晴 | 94 |
1 | 雨 | 27 |
2 | 晴 | 49 |
3 | 晴 | 30 |
4 | 晴 | 22 |
5 | 曇り | 64 |
6 | 雨 | 35 |
7 | 雨 | 80 |
8 | 曇り | 80 |
9 | 曇り | 54 |
引数に配列を指定すると、ユニークな値の配列を返します。
pd.unique(values)
結果
array([‘晴’, ‘雨’, ‘曇り’], dtype=object)
value_count()
配列の値の数を個別の数量を返します。
pd.value_counts(values)
結果
晴 4
雨 3
曇り 3
Name: 天気, dtype: int64
ディメンションテーブルを考慮
ディメンションテーブルを考慮したPandasのSeriesデータを作成します。
values = pd.DataFrame({'天気':np.random.randint(0,3,10), '販売数':np.random.randint(10,100,10)}) values
結果
天気 | 販売数 | |
---|---|---|
0 | 2 | 39 |
1 | 0 | 44 |
2 | 0 | 87 |
3 | 2 | 77 |
4 | 1 | 92 |
5 | 0 | 86 |
6 | 0 | 85 |
7 | 1 | 24 |
8 | 2 | 32 |
9 | 2 | 42 |
dim = pd.Series(['晴','曇り','雨']) dim
結果
0 晴
1 曇り
2 雨
dtype: object
take関数で元の文字列に変換
dimがディメンションテーブルと考えるとtakeメソッドでvaluesの値を簡単にディメンションの値に変換できます。
val = dim.take(values['天気']) val
結果
2 雨
0 晴
0 晴
2 雨
1 曇り
0 晴
0 晴
1 曇り
2 雨
2 雨
dtype: object
DataFrame型の活用
簡単なデータフレーム型のデータを例にカテゴリ型の活用を考えます。
例として単純なデータフレームを作成します。
values = pd.DataFrame({'天気':np.random.choice(['晴','曇り','雨'],10), '販売数':np.random.randint(10,100,10)}) values
結果
天気 | 販売数 | |
---|---|---|
0 | 雨 | 89 |
1 | 晴 | 14 |
2 | 晴 | 36 |
3 | 晴 | 30 |
4 | 晴 | 94 |
5 | 雨 | 19 |
6 | 曇り | 24 |
7 | 曇り | 15 |
8 | 雨 | 26 |
9 | 雨 | 87 |
astype()でPandasカテゴリ型に変換
astype()を使用して’language’列をカテゴリ型に変換します。
values['天気'] = values['天気'].astype('category') values['天気']
結果
0 雨
1 晴
2 晴
3 晴
4 晴
5 雨
6 曇り
7 曇り
8 雨
9 雨
Name: 天気, dtype: category
Categories (3, object): [晴, 曇り, 雨]
通常の列表示と同じ結果ですが、追加で、Categories (2, object): [Apple, Orange] の項目が表示されます。
複数の値があっても、実はAppleとOrangeというカテゴリ(ユニークな値)でできていることがわかります。
categoriesプロパティとcodesプロパティ
categoriesプロパティとcodesプロパティで「カテゴリ名」と「カテゴリ番号」を返してくれます。
このことを活用するとカテゴリ変数のエンコーディング を行うことも可能になります。
weater_dim = values['天気'].values type(weater_dim)
結果
pandas.core.arrays.categorical.Categorical
weater_dim.categories
結果
Index([‘晴’, ‘曇り’, ‘雨’], dtype=’object’)
values['天気_num'] = weater_dim.codes values
結果
天気 | 販売数 | 天気_num | |
---|---|---|---|
0 | 雨 | 89 | 2 |
1 | 晴 | 14 | 0 |
2 | 晴 | 36 | 0 |
3 | 晴 | 30 | 0 |
4 | 晴 | 94 | 0 |
5 | 雨 | 19 | 2 |
6 | 曇り | 24 | 1 |
7 | 曇り | 15 | 1 |
8 | 雨 | 26 | 2 |
9 | 雨 | 87 | 2 |
カテゴリ型を用いたヒント
例えばタイタニックの問題で’Sex’列を数値化して新しい列の’sex_num’に入れる場合、次のようにすることができます。
train['sex_num'] = train['Sex'].astype('category').values.codes
ただ変換するだけで良いのなら、これをもっとスマートに行うには、Pandasのfactorize()関数を使えば簡単です。
train['sex_num'], _ = pd.factorize(train['Sex'])
機械学習的には、One-Hotエンコーディング化でPandasのget_dummies()を使う場合が多いと思いますが、Pandasのカテゴリ型の仕組みを理解しておくことは、柔軟にデータを組み直すことができる指針になるかもしれません。
参考になった書籍
Pandasを使いこなすための必携の本。Pandasの作者自ら書いた本でNumpyやPandasの使い方が詳細に書かれている。
今回の内容はこの本の後半にあるPandas応用編を参考にしています。
Pythonサンプルのダウンロード
ここでダウンロードする「pandas_categori.ipynb」ファイルは、このPandas動画で使用したものです。
コメントを投稿するにはログインしてください。