【初心者】特徴量エンジニアリングについて調べてみた

# 背景・目的
私は、現在データエンジニアリングを生業としています。普段は、データ基盤の構築や、パフォーマンスチューニングなどビックデータに関する業務に従事しています。
ビックデータの収集や、蓄積、分析などの環境構築の経験はそこそこありますが、機械学習による予測や分類などのスキルは持ち合わせていませんでした。
今まで機械学習を避け続けてきましたが、一念発起し学ぼうと思います。

学び方としては、AWS Certified Machine Learning – Specialty（以降、ML試験という。）の勉強を通して、理解を深めていきます。
ML試験のガイドの第２分野に、探索的データ解析が登場しましたのでそこから学びたいと思います。

過去に以下について、学習を進めてきました。今回は特徴量エンジニアリングについて学びたいと思います。

- 2.探索的データ分析関連
- 2.1.モデリング用のデータをサニタイズおよび準備する
    - [【初心者】探索的データ解析とは何かを調べてみた](https://qiita.com/zumax/items/52c97307bf18f407bb6e)
    - [【初心者】データのスケーリングを調べてみた](https://qiita.com/zumax/items/ca7184dcf4e7fd242128)
    - [【初心者】データの拡張を調べてみた](https://qiita.com/zumax/items/0727e329f3322897d3e7)
    - [【初心者】データアノテーションを調べてみた](https://qiita.com/zumax/items/d0da86b68b05b99cb23e)

# まとめ
- 特徴量とは、分析対象データの中の、予測の手掛かりとなる変数のこと。特徴量の選択によりモデルの性能が大きく変わる。
- 特徴量エンジニアリングは、オリジナルデータから機械学習モデル（AIモデル）に有用な説明変数（特徴量）を作成する作業
- 特徴量エンジニアリングは、奥が深く経験値や知識が必要である。

# 概要
## そもそも、特徴量とは？
特徴量エンジニアリングの特徴量が分かっていません。

こちらの[「機械学習で「超重要な」特徴量とは何か？ 設計方法などについてわかりやすく解説する」](https://www.sbbit.jp/article/cont1/76066)を参考にしました。助かりました。

> 　機械学習とは人工知能（AI）の手法の1つであり、大量な学習データをもとに法則やパターンを見出すことです。
　学習が完了した機械学習プログラムは学習済みモデルと呼びます。では、学習済みモデルの理想的な姿とはどんなものでしょうか？
その答えは、「汎用的なパターンを習得できて、新しいデータに対して、満足できる精度で予測を行える」ことです。
上記でいう「汎用的なパターン」を大量のデータから見つけ出す際に、データのどのような特徴に着目すべきか、を表す変数が「特徴量」です。機械学習モデルを構築するために、特徴量を人が指定しなければいけません。

- 学習済みモデルに求められる要件は、「汎用的なパターンを習得できて、新しいデータに対して、満足できる精度で予測を行える」こと。この汎用的なパターンを大量のデータから見つけ出す際に、**データのどのような特徴に着目すべきか？を表す変数を特徴量**という。

もう少し噛み砕くと、**分析対象データの中の、予測の手掛かりとなる変数（説明変数）**　とのことです。

### 契約予測のモデルを例に考える

ある人が、あるサービスを契約するかを予測する際に、以下のような情報が特徴量として利用できそうな変数と考えられる。

- 年齢
- 性別
- 年収
- 家族人数
- 姻族年数

### 構造化データの特徴量
構造化データは縦横の表で表せるデータで、CSVやExcel、RDBのテーブルなどが代表例です。
構造化データの中で、よく利用されるのが売上履歴データであり、売上予測の中で、分析担当者が特徴量として指定しうる項目として、以下のようなものが考えられます。

- 曜日
- 祝日か平日か
- 気温
- 湿度
- 割引有無
- クーポン

これらの特徴量をモデルに学習させて、来月に関する変数を同じ変数をモデルにインプットすることで、来月の売上を予測することが可能になります。

### 非構造化データの特徴量
非構造化データは、一般的に、音声、画像、文章などがあげられ、構造化データとは異なり表形式では無く扱いが難しいです。
しかし、最近のデータの傾向としては非構造化データが大量に生成されていて、非構造化データを扱う技術が重要になっている。
非構造化データでは、ニューラルネットワークを用いることが多く、ニューラルネットワークでは、データのどこを特徴量として学習すべきかを、人間が指定すること無く、自らがそれを選択することを特徴とする機械学習の手法です。

## 特徴量エンジニアリングとは？



AWSの「[特徴量エンジニアリング](https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/machine-learning-lens/feature-engineering.html)」のドキュメントを見ると以下の記載がありました。
> 視覚化と分析を通じてデータを調査し、理解したところで、今度は特徴量エンジニアリングを実行します。固有のデータ属性は、すべて特微と見なされます。たとえば、顧客離れを予測するという問題の解決策を設計するには、一定期間にわたって収集した顧客データから始めます。顧客データは、顧客の所在地、年齢、所得水準、最近の購入などの特微 (属性としても知られています) をキャプチャします。

- 視覚化、分析を通してデータの調査後に行う作業。
- 固有のデータ属性を全て特徴とみなす。

> 特徴量エンジニアリングとは、機械学習や統計的モデリングを用いて予測モデルを作成するときに、変数を選択して変換するプロセスです。通常、特徴量エンジニアリングには、特徴作成、特徴変換、特徴抽出、および特徴選択が含まれます。
　

- 特徴量エンジニアリングとは、変数を選択して変換するプロセスを指すようです。
- 特徴量エンジニアリングに含まれるプロセスについては、以降に記載します。
    - 特徴作成
        - 目下の問題に関連するデータセット内の特徴を特定します。
    - 特徴変換
        - 欠落している特徴、または無効な特徴の置き換えを管理します。
        - 手法
            - 特徴のデカルト積の形成
            - 非線形変換 (数値変数のカテゴリへのビン分割など)
            - ドメイン固有の特徴の作成
    - 特徴抽出
        - 既存の特徴から新しい特徴を作成するプロセス
        - 通常は特徴の次元を削減することを目的としている
    - 特徴選択
        - データセットからの無関係な特徴、または冗長な特徴のフィルタリング
        - 通常、これはバリアンスまたは相関のしきい値を観察して削除する特徴を判断することによって行われます。

うーん。ここまで読んでもわかりませんでした。

こちらの「[特徴量エンジニアリングとは](https://www.varista.ai/knowledge/what-is-feature-enginnering/)」の記事にわかりやすい説明がありました。助かりました。

> 特徴量エンジニアリング(Feature Engineering)とは、今あるデータの特徴量からドメイン知識などを生かして新しくデータの特徴量を作成する作業のことをいいます。
特徴量エンジニアリングの目的は、データの質を上げ機械学習モデルの予測性能、すなわち汎化性能を向上させることです。

> 顧客ID、商品価格、商品数量、ブランドを組み合わると 消費金額の合計 を新たな特徴として生成することができます。

どうやら、既存のデータから、モデルのインプットに必要なデータを新たに生成することを特徴量データエンジニアリングというようです。

> 特徴量エンジニアリングの流れ
> 1.どのような特徴があるといいか仮説を立てる
> 2.特徴量を作成する
> 3.モデルを作成し、汎化性能を確認し求める制度ではない場合は再度1に戻ります。

特徴量の流れとして、仮説→特徴量の作成→モデル作成し検証する。があり、これを特徴量エンジニアリングと呼ぶようです。


## 特徴量エンジニアリングの重要性
> 汎化性能を向上させるには、アルゴリズムのハイパーパラメータ最適化なども行われますが、多くのケースでそれ以上に特徴量エンジニアリングの方が汎化性能に与える影響が大きくなります。

モデルの性能において、特徴量の選択や作成が重要な位置づけであるということですね。

## 特徴量エンジニアリングの難しさ
こちらの「[今あらためて考える特徴量エンジニアリング　～予測精度をあと一歩改善するテクニック](https://www.imagazine.co.jp/%E4%BB%8A%E3%81%82%E3%82%89%E3%81%9F%E3%82%81%E3%81%A6%E8%80%83%E3%81%88%E3%82%8B%E7%89%B9%E5%BE%B4%E9%87%8F%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%EF%BD%9E%E4%BA%88/)」に、特徴量エンジニアリングの難しさについて記載がありました。
奥が深いということが分かりました。

> 特徴量エンジニアリングでは、データサイエンティストの業務知識や経験を元に有用な特徴量を作成するが、とくに初級?中級データサイエンティストはその経験が少なく、またある程度の経験があるデータサイエンティストであっても意外な特徴量を着想しにくいという悩みがある。

> また、集計・数値変換・コード化などのさまざまな手法を適用してデータを変換するが、このデータの変換方法は無限に存在するため、その作成に要する時間や計算資源というリソース問題、また大量に作成された特徴量から有用なものを絞り込む特徴選択が煩雑になるという悩みもある（図表2）。

初級、中級のデータサイエンティストなど経験が浅い場合、特徴量の着想しにくいとのことです。
また、データ変換の方法は無限にあるため、有用な特徴量を見極める経験値、または計算リソースを大量に使用するなどの課題もあるようです。

## AWSにはどのようなソリューションがあるのか？
### SageMaker
- 特徴のエンジニアリングを実施し、データを変換するために使用できる、Spark と scikit-learn のプリプロセッサを備えた Jupyter ノートブック環境を提供している。
- GlueやEMRなどのETLサービスを利用し、特徴抽出と変換ジョブを実行することも可能
- SageMaker Inference Pipelineを使用し、既存のデータ処理機能を再利用することも可能

### SageMaker Processing
- Amazon SageMaker が提供するセキュリティおよびコンプライアンス機能のすべてを備えた完全マネージド型環境です。
- 特徴量エンジニアリング (およびモデル評価) のための分析ジョブを大規模に実行することが可能。
- SageMaker Processing を使用することにより、組み込みのデータ処理コンテナを使用する、または独自のコンテナを持ち込んで、マネージドインフラストラクチャで実行するためのカスタムジョブを送信する柔軟性が実現されます。
- ジョブが送信されると、SageMaker がコンピューティングインスタンスを起動し、入力データの処理と分析を行って、それらが完了した時点でリソースを解放します。 
- SageMaker上で簡単に行うためのPython SDK
- コンテナを用意して、実行したい処理を記述して実行するインスタンスタイプを指定し、ジョブを実行することができる。

# 考察
特徴量と特徴量エンジニアリングについて、言っていることは理解できました。ただし、手法などは未だ理解できていません。
今後は、どのような手法があるかを学ぶ。また、手を動かして理解していく予定です。

# 参考
https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/machine-learning-lens/feature-engineering.html

https://www.varista.ai/knowledge/what-is-feature-enginnering/

https://www.sbbit.jp/article/cont1/76066#head1

https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/machine-learning-lens/phases-of-ml-workloads.html

https://aws.amazon.com/jp/blogs/news/amazon-sagemaker-processin-fully-managed-data-processing-and-model-evaluation/

https://aws.amazon.com/jp/blogs/news/rapids-on-amazon-sagemaker-processing/

https://sagemaker.readthedocs.io/en/stable/amazon_sagemaker_processing.html

https://www.imagazine.co.jp/%E4%BB%8A%E3%81%82%E3%82%89%E3%81%9F%E3%82%81%E3%81%A6%E8%80%83%E3%81%88%E3%82%8B%E7%89%B9%E5%BE%B4%E9%87%8F%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%EF%BD%9E%E4%BA%88/