xfeatのaggregationで自作の関数を使いたい - 2月 28, 2021 こんにちは、ぐぐりら(@guglilac)です。 特徴量作成のライブラリであるxfeatの集約特徴量を計算してくれるaggregationがとても便利で最近よく使っています。(xfeatはaggregation以外にも様々な機能があります。詳しくはこちらの記事などが参考になると思います。) [特徴量エンジニアリングのライブラリ xfeat を使ってみて便利だったこと - Taste of Tech Topics](https://acro-engineer.hatenablog.com/entry/2020/12/15/120000) 今回はタイトルの通り、xfeatのaggregtionの集約関数として自作の関数を使いたいときにどうするか、という内容について書いてみます。 ## aggregationの基本的な使い方 まずは自作関数を渡す前に、xfeatのaggregationの基本的な使い方をみてみます。 先ほど紹介した記事から引用したコードですが、以下のように書くと「性別ごとのAge,Pclassの平均、最大」が取得できます。 ```python from xfeat import aggregation aggregated_df, aggregated_cols = aggregation(train_df, group_key="Sex", group_values=["Age", "Pclass"], agg_methods=["mean", "max"] ) ``` と書くと |Sex|agg_mean_Age_grpby_Sex|agg_max_Age_grpby_Sex|agg_mean_Pclass_grpby_Sex|agg_max_Pclass_grpby_Sex| |----|----|----|----|----| |Male|xxx|xxx|xxx|xxx| |FeMale|xxx|xxx|xxx|xxx| のようなdataframeともとのdataframeをSexカラムでjoinしたdataframeが返ってきます。 カラム名は`agg_{agg_method}_{col}_grpby_{group_key}`という形式で決まるようです。 参考: [xfeat/helper.py at master · pfnet-research/xfeat · GitHub](https://github.com/pfnet-research/xfeat/blob/master/xfeat/helper.py#L28) ## 自作関数を渡す(そのまま渡すver) 次に、aggregationのagg_methodsに自作の関数を渡してみましょう。 先ほど紹介した基本的な使い方では、agg_methodsには ```python agg_methods=["mean", "max"] ``` のように文字列で集約関数を指定していました。 xfeatのaggregationの中ではdataframeのaggメソッドでagg_methodsで渡されたリストの中身が順番に入れられているようなので([xfeat/helper.py at master · pfnet-research/xfeat · GitHub](https://github.com/pfnet-research/xfeat/blob/master/xfeat/helper.py#L35))、dataframeのaggメソッドと同じく自作の関数を入れることができそうです。 以下のコードでは、集約関数として最大値と最小値の差を用いています。 ```python def max_min(x): return max(x)-min(x) agg_methods=["mean", "max", max_min] ``` これでaggregationを行うと、正しく実行はできるのですが、集約関数に自作関数を使った部分のカラム名がおかしくなってしまいます。 具体的には `agg__Age_grpby_Sex` のようなカラム名になってしまいます。 これは、先ほど書いたカラム名を決めている部分が `f"agg_{agg_method}_{col}_grpby_{group_key}"`となっているので、agg_methodに関数オブジェクトをいれると特殊メソッドの`__str__`が呼ばれているのが原因です。 さすがにカラム名がこれでは気持ちが悪いので、次のような方法で解決しました。 ## 自作関数を渡す(カラム名いいかんじver) ようするに、自作関数をprintしたときに自分の関数名を返してくれるようにすればよいので、`__str__`をいじればよいのでは、と考えたのですが、Pythonのclassではなくfunctionの`__str__`ってどうやっていじればいいんだ?となりました。 classの時のように書いてみましたが、結果は変わりませんでした。 ```python def max_min(x): def __str__(self,x): return "max_min" return max(x)-min(x) print(max_min) # => ``` ちゃんと調べたら関数の`__str__`もいじれるのかもしれないですが、よくわからなかったので次のように書いて解決しました。 ```python class MaxMin: def __call__(self, x): return max(x)-min(x) def __str__(self): return "max_min" # これをagg_methodsに渡す aggregated_df, aggregated_cols = aggregation(train_df, group_key="Sex", group_values=["Age", "Pclass"], agg_methods=["mean", "max", "MaxMin"] ) ``` classなら`__str__`をいじって表示名を変えることができたので、MaxMinクラスを作り、その`__call__`メソッドをいじることで ```python MaxMin(x) ``` のように関数のように呼び出せるようにしたところ、うまくカラム名もいい感じに`agg_max_min_Age_grpby_Sex`なりました。 ## おわりに 今回はxfeatのaggregationに渡す集約関数として、自作関数を指定する際にカラム名がわかりづらくなることを回避するtipsを書きました。 他にもいい方法があるかもしれないですが、とりあえずこれでも問題なさそうなのでこれを使っています。 以上になります。最後までお読みいただきありがとうございました。 この記事をシェアする Twitter Facebook Google+ B!はてブ Pocket Feedly コメント
コメント
コメントを投稿