勾配ブースティング (Gradient Boosting) について勉強する
はじめに
機械学習での回帰や分類問題に適用されるアルゴリズムで、勾配ブースティング (Gradient Boosting) とやらがなかなかよいらしいというのをいろんなところで見かけたのでちょっとお勉強。基本的には同じっぽいので、以下では回帰問題を前提にして考える。
なお、以下の記事が非常にわかりやすかったので、以下の記事を読んで理解できる方は私の記事を見る必要はありません。
woodyzootopia.github.io
勾配ブースティングを理解する上でのキーワード
- アンサンブル学習
- 回帰木
の二つ。
アンサンブル学習
アンサンブル学習は、複数の(あまり精度のよくない)学習器を組み合わせることで、全体として高い精度の学習器を作り出す仕組みのことです。詳細は以下などをご覧ください。
アンサンブル学習には、その組み合わせ方によりいくつかの手法があるようです。勾配ブースティングはその名の通り、アンサンブル学習の中のブースティングという手法を用います。ブースティングではまずある学習器で学習をやった後、残った誤差に対して、新たな学習を行う、というのが基本的な流れ。
勾配ブースティングでは、誤差の勾配にフィットさせるような学習器を作った後に、勾配降下法的な流れで繰り返し学習させていくようです。
回帰木
勾配ブースティングの基本的な基本的な考え方では、使用する学習器は任意のものを使うことができるようですが、ほとんどのケースで回帰木を使うようです。
回帰木の説明も世の中にたくさんありますが、以下のようなPythonコードを参考にするとわかりやすいかもしれませんね。
https://fisproject.jp/2016/07/regression-tree-in-python/
で、上記2点を踏まえた上で、以下を読んでみると非常に面白いですヨ
Pythonのloggingでログが重複して困った話 [fbprophet]
Pythonでログが重複する話は比較的よくある模様。
自分で作ったLoggerでログが重複してしまったのであれば以下のようなものも参考になるが・・・。
uyamazak.hatenablog.com
今回はいろいろ調査した挙句、インポートして使っているライブラリであるfbprophetに原因があった。
github.com
このライブラリは以下のようにLoggerを初期化していたのです。
github.com
basicConfigを見てみると、、、Root Loggerが生成されます。
docs.python.org
自分でロガーを別途生成して制御していたのにもかかわらず、ライブラリで勝手にRoot Loggerを作るため、自分で作ったLoggerへのログ出力も重複してしまうことになったのです。。。
そういう時は、先回りしてLoggerを殺して(もしくは自分の仕様にあったLoggerを生成して)あげましょう。
Pythonのloggingか階層構造を持っているから、とも言えます。
qiita.com
ちなみに、fbprophetでは、内部的にpystanも使っており、pystanも同様のコードでLoggerを初期化してるので要注意。
Root Loggerが勝手に作られる処理を殺したければ以下のようなコードでどうぞ♪(この場合は、当然、fbprophetからログが出なくなるので、出力したい場合は適切なHandlerを設定してください。)
logging.getLogger('fbprophet').addHandler(logging.NullHandler()) logging.getLogger('pystan').addHandler(logging.NullHandler())
以上
C#でのAzure Functionsの呼び出しにはまった
Azure Functions(HttpTrigger)で何らかのFunctionsを追加すると、通常は、
https://xxxxxx.azurewebsites.net/api/xxxxx的なURLが作成されます。
で、以下のコードを書きました。
WebClient wc = new WebClient(); string url = "https://xxxxxx.azurewebsites.net/api/xxxxx"; Stream st = wc.OpenRead(url); Encoding enc = Encoding.GetEncoding("utf-8"); StreamReader sr = new StreamReader(st, enc); string html = sr.ReadToEnd(); sr.Close(); st.Close(); Console.WriteLine(html);
そうると、、、、呼び出し時にエラーとなります。
>bin\Debug\ConsoleApplication1.exe ハンドルされていない例外: System.Net.WebException: 接続が切断されました: 送信時に、予期しないエラーが発生しました。。 ---> System.IO.IOException: 転送接続からデータを読み取れません: 既存の接続はリモート ホストに強制的に切断されました。。 ---> System.Net.Sockets.SocketException: 既存の接続はリモート ホストに強制的に切断されました。 場所 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) : :
Functionsの何か書き方がまずいのかとか、、、半日くらいいろいろ試行錯誤しました。
一晩寝たところ、なんと https を http に変えたら動くんじゃないかという神のお告げが。。。。
そして見事動きました!
でも何か悶々としていて、数日後にググってみると、今のページへめぐり逢い。。。。
fullvirtue.com
ちなみにHttpClientでも同様なようです。
qiita.com
なんと、一行追加するだけで動きましたとさ。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; WebClient wc = new WebClient(); string url = "https://xxxxxx.azurewebsites.net/api/xxxxx"; Stream st = wc.OpenRead(url); Encoding enc = Encoding.GetEncoding("utf-8"); StreamReader sr = new StreamReader(st, enc); string html = sr.ReadToEnd(); sr.Close(); st.Close(); Console.WriteLine(html);
めでたしめでたし。