Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゼロから作るアンサンブル学習 第2回資料

9b68af6c519bd08da4eb0fa367c73ace?s=47 tatamiya
April 25, 2019

ゼロから作るアンサンブル学習 第2回資料

9b68af6c519bd08da4eb0fa367c73ace?s=128

tatamiya

April 25, 2019
Tweet

Transcript

  1. ゼロから作るアンサンブル学習 ~OSSに学ぶ機械学習の実装~ 第2回 scikit-learnの中⾝を読む たみや@tatatatatamiya

  2. このセミナーについて u ⽬的 u アルゴリズムの理解 u OSSから良い実装を学ぶ u スケジュール u

    第1回(3/28) : 決定⽊・ランダムフォレストの理解と実装 u 第2回(4/25 本⽇) : scikit-learnの読解 u 第3回(5⽉下旬) : 勾配ブースティング〜XGBoost, LightGBM
  3. ⾃⼰紹介 名前︓たみや 現職︓受託データ分析ベンチャー新卒2年⽬ 仕事内容︓データ加⼯・変換,時系列データ予測,画像解析ほか 使⽤⾔語︓Python, C⾔語 最近の興味︓Cython, デザインパターン, AWS, Docker

    + k8s, Vim
  4. ⽬次 u sklearnレポジトリの辿り⽅ u 決定⽊ u 全体の構成 u アルゴリズム u

    Node : ⽊構造をどう持つか︖ u splitter : 最適な分割の探索⽅法 u ランダムフォレスト u 全体の構成 u fit部分のアルゴリズム
  5. sklearnレポジトリの辿り⽅

  6. sklearnを使う u `pip install sklearn` u 種類 u 予測・分類 u

    前処理・特徴量選択など u 基本的な使い⽅ u インスタンスを作成する u パラメータ・オプションの設定 u fitで学習, predictで予測 u ほかにも,transform, predict_proba, fit_transform
  7. GitHubレポジトリの構成 u GitHub https://github.com/scikit-learn/scikit-learn u sklearn以下に全部⼊っている u 例︓線形回帰 u sklearn/linear_model/以下

    u コード⾃体はbase.py u この中の367⾏⽬ LinearRegressionクラスを呼び出している u `from sklearn.linear_model import LinearRegression`で読み込めるのは,__init__.pyの中で `__all__`に含めているから。 u 今回扱うもの u 決定⽊︓sklearn/tree/tree.py u ランダムフォレスト︓sklearn/ensemble/forest.py
  8. コードの基本的な構成 u 例︓LinearRegression … fit, predict, score u class LinearRegression内で直接記述されているメソッド

    u fit (503⾏⽬でnumpyのlinalgを呼び出す) u 継承元のクラス u LinearModel … predict u BaseEstimator … set_params, get_params u RegressorMixin … score u MultiOutputMixin
  9. 決定⽊

  10. 全体の構成︓ u 基本的な使い⽅ u DecisionTreeClassifierとDecisionTreeRegressor u 場所 u sklearn/tree/以下(全13種のファイル) u

    メインはtree.py u .pyx, .pxd -> Cythonファイル
  11. 全体の構成︓ファイル構成 u DecisionTreeClassifier, DecisionTreeRegressorともにtree.pyの中 u ともにBaseDecisionTreeを継承している u ほかにも,ExtraTreeClassifier/Regressorというものもある(⽤途不明) u 多くの処理がCythonで書かれている

    u _tree.pyx u _splitter.pyx u _criterion.pyx u _utils.pyx ← メモリ管理等
  12. 全体の構成︓ ClassifierとRegressor u ClassifierとRegressorの設計上の違い u Classifier専⽤のメソッド︓predict_proba, predict_log_proba u 継承しているクラス︓ClassifierMixin /

    RegressorMixin u /sklearn/base.pyの中にある u これにより,scoreメソッドの⽤いるmetricsが異なっている。 u BaseTree内でClassifierかRegressorかをチェックしている u 141⾏⽬(fit関数内) : `is_classification = is_classifier(self)` u /sklearn/base.py内のis_classification関数 u 継承元のMixinで定義した”_estimator_type”をチェックして分岐している
  13. 全体の構成︓ ClassifierとRegressor u ClassifierとRegressorで異なる処理 u 153⾏⽬︓出⼒値の形式 u classificationでは正解ラベルのencodingもここで⾏う u 341⾏⽬︓学習指標criterion

    u 冒頭(59~61⾏⽬)で定義した辞書から選択している(引数criterionをkeyに)
  14. 全体の構成︓メインとなる処理 u 340⾏⽬ Build Tree以降 u 別ファイルで定義した関数(Cython)を順次呼び出している u 中核は,380⾏⽬ `builder.build(self.tree_,

    X, y, sample_weight, X_idx_sorted)` u buildまでの流れ u criterionの定義(前⾴) -> self._criterion.pyx u splitterの選択(Best / Random) -> self._splitter.pyx u self.tree_インスタンスの作成 -> self._tree.pyx内のTreeクラス u builderの選択(Depth / Best) -> self._tree.pyx内のDepth/BestFirstTreeBuilderクラス
  15. アルゴリズム︓⽊構造 u ⾃分の実装 u Nodeクラスを作成 u scikit-learnの実装 u _tree.pxdの中で構造体として定義されている。 u

    アルゴリズム中では,ポインタのアドレス指定で値を⼊れている︖
  16. アルゴリズム︓splitter u ⾃分の実装 u 最適分割探索関数`find_optimal_division`を定義 u numpyのapply_along_axis関数を使ってデータの各列に適⽤ u scikit-learnの実装 u

    Cythonでfor⽂回して記述(_splitter.pyx) u 全探索はしない u impurityが下がらないとわかった特徴量はそれ以降調べない
  17. ランダムフォレスト

  18. 全体の構成︓関連ファイル u 基本的な使い⽅ u RandomForestClassifierとRandomForestRegressor u feature_importanceというプロパティ u 場所 u

    sklearn/ensemble/forest.py内 u 決定⽊と異なり,forest.pyだけでほぼ完結 u iforest.pyというのもあるがこれは…︖ u → 外れ値検出アルゴリズムらしいです https://blog.amedama.jp/entry/2019/04/20/124220
  19. 全体の構成︓構造 u 基底クラスからの流れ u BaseForest -> ForestClassifier/Regressor -> RandomForestClassifier/Regressor u

    基本的には,BaseForestがほぼ全ての処理を⾏っている u ForestClassifier/Regressor u RandomForestClassifier/Regressor : インターフェイス部分を整えるの み︖
  20. アルゴリズム︓fit部分 u BaseForestのfitメソッド(125⾏⽬〜) u 315⾏⽬︓複数の決定⽊インスタンスを作成 u 継承元クラスBaseEnsembleの_make_estimatorメソッドを使⽤ u bese_estimator_をcloneしてestimatorsにappendしていく u

    base_estimator⾃体は,__init__で引数としてとる u RandomForestClassifier/Regressorをみると, DecisionTreeClassifier/Regressor()を⼊れている︕ u 325⾏⽬︓ u joblibを使った並列化 u _parallel_build_treesメソッドで → 94⾏⽬