PRML 7. Sparse Kernel Machines (Classification with SVM)
- PRML本の7章でサポートベクターマシンを使った分類アルゴリズム。
- 機械学習等は勉強中で、内容に誤りがある可能性が十分にあります。指摘していただけると嬉しいです
- 作者: C.M.ビショップ,元田浩,栗田多喜夫,樋口知之,松本裕治,村田昇
- 出版社/メーカー: 丸善出版
- 発売日: 2012/04/05
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 33回
- この商品を含むブログ (18件) を見る
概要
- 分類の境界線から一番違い要素との距離を最大化するように最適化を行う。
- 2クラスの分類を扱うが、多クラスへの応用はストレートにできる。
- 最大化問題をラグランジュ未定乗数法を用いて双対問題を作り、双対問題を解く。
- 予測時に一部の学習データのみを用いる。それらをサポートベクターと呼ぶ。
- 式変形は単純なので、メモなし。
図7.2の再現
sigmaによる結果への影響について。
- 今回、Gaussianカーネルを使っているので、sigmaは各学習用データがその周りに与える影響の大きさを表している。
- 小さすぎるとサブセットの周りを囲むような境界線になってしまい、汎用性がさがる。
- 逆に大きくするとデータから遠いところが大雑把になりそう。
外れ値
- ナイーブに最大化問題を解くと、外れ値に対応できない。
- アルゴリズム上、すべての学習データを正しく分類する。汎用性が低くなる可能性がある。
- そこで、スラック変数を導入して、誤って分類させることを許し、そのかわりにペナルティを与えるようにする。
- スラック変数導入前は、左下の青い一点を囲むような境界ができていたが、導入後は左下の青い点は間違った分類(赤)になったままになった。
Python
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import minimize import math class DualRepresentation: def __init__(self, x, t, sigma, c): self.x = x self.t = t.flatten() self.sigma = sigma self.a = None self.b = 0 self.c = c def kernel(self, xn, xm): return math.exp(- 0.5 * np.linalg.norm(xn - xm) ** 2 / (self.sigma ** 2)) def __call__(self, input): n = self.t.shape[0] a = np.array(input).flatten() k = np.array([self.kernel(xn, xm) for xn in self.x for xm in self.x]).reshape(n, n) v = np.sum(a) for i in range(n): for j in range(n): v -= 0.5 * a[i] * a[j] * self.t[i] * self.t[j] * k[i][j] return -v def set(self, a): n = self.t.shape[0] self.a = a idx = np.where(a != 0) ns = idx[0].shape[0] k = np.array([self.kernel(xn, xm) for xn in self.x for xm in self.x]).reshape(n, n) b = 0.0 for i in idx[0]: b += self.t[i] for j in idx[0]: b -= a[j] * self.t[j] * k[i][j] self.b = b / ns def learn(self): n = self.t.shape[0] a0 = np.random.uniform(0, 1, n) cons = ({'type': 'ineq', 'fun': lambda a: a}, {'type': 'eq', 'fun': lambda a: np.sum(self.t * a) - 1}, {'type': 'ineq', 'fun': lambda a: self.c - a}) res = minimize(self, a0, method='SLSQP', tol=1e-6, constraints=cons) a = np.array([x if x > 1e-12 else 0.0 for x in res.x]) self.set(a) return a def predict(self, x): n = self.t.shape[0] k = np.array([self.kernel(x, xm) for xm in self.x]) return np.sum(self.a * self.t * k) + self.b def plot72(x, t, sigma, c=1e+16, do_save=None): n = data.shape[0] f = DualRepresentation(data[:, 0:2], t, sigma, c) a = f.learn() n_plot = 100 axis_x0 = np.linspace(np.min(x[:, 0]), np.max(x[:, 0]), n_plot) axis_x1 = np.linspace(np.min(x[:, 1]), np.max(x[:, 1]), n_plot) boundary = np.array([f.predict(np.array([x0, x1])) for x0 in axis_x0 for x1 in axis_x1]).reshape(n_plot, n_plot) idx = np.where(a != 0.0) plt.clf() plt.scatter(x[idx, 0], x[idx, 1], c='w', marker='o', s=100) plt.scatter(x[:, 0], x[:, 1], c=t, marker='+', s=60) plt.contour(axis_x0, axis_x1, boundary.T, np.array([-1, 0, 1])) if do_save is None: plt.show() else: plt.savefig(do_save) if __name__ == '__main__': data = np.genfromtxt('dataset/classification_7_2.csv', delimiter=',').astype(np.float32) plot72(x=data[:, 0:2], t=data[:, 2], sigma=0.1, do_save='img/f7.2_0.1.png') plot72(x=data[:, 0:2], t=data[:, 2], sigma=0.2, do_save='img/f7.2_0.2.png') plot72(x=data[:, 0:2], t=data[:, 2], sigma=0.5, do_save='img/f7.2_0.5.png') data = np.vstack([data, np.array([[0.15, 0.35, -1]])]) plot72(x=data[:, 0:2], t=data[:, 2], sigma=0.2, do_save='img/f7.2_0.2_outlier.png') plot72(x=data[:, 0:2], t=data[:, 2], sigma=0.2, c=1, do_save='img/f7.2_0.2_outlier_slack.png')
- 作者: C.M.ビショップ,元田浩,栗田多喜夫,樋口知之,松本裕治,村田昇
- 出版社/メーカー: 丸善出版
- 発売日: 2012/04/05
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 33回
- この商品を含むブログ (18件) を見る
2017年の目標
今年は去年より勉強に使える時間が増えそうなので、がっつり勉強したい。転職時に1ヶ月程度間を入れてじっくりと学べるかな。
(1) 機械学習を学ぶ
クオンツからデータアナリストに変わろうと思う。統計等は学部時代に勉強していたけど、機械学習はさらっとライブラリの使い方解説本を読んだ程度。プロとして最低限のレベルに達したい。
(2) 分析経験を積む
「いかに使うか」が重要なので、経験値を積みたい。業務で使用するだろうけど、幅広く色々分析したいので、ちょっと意識してデータを分析していく。
- 1ヶ月に1つ程度、データを分析して、その過程をブログにアップする。
(3) その他
教養がないので、世界史や生物学の本を読もうと思う。何がいいのかわからないけど、本やで適当に探そう。あと、インプットだけでなくアウトプットをしっかりと出していきたい。
- 1ヶ月に1冊読んで、感想をブログに書く。
- ブログを続ける
変化のある年に
10年近く勉強してきたクオンツ業界から離れることを決意したので、節目の年になる。新しい分野でしっかりと結果を出していきたい。
Jenkinsメモ
github, jenkins, aws
git
submodule
- Reference
- Git submodule の基礎
- git submoduleを今風な感じで削除する
jenkins
plugin
- Reference
- How to install a plugin in Jenkins manually?
- MSBuild Plugin
- After installation, there is setting form in "Global Tool Configuration".
job
- Reference
- Hudson/JenkinsでVisual Studioプロジェクトのビルドをする
- JenkinsとMSBuild PluginでVisual Studioのプロジェクトをビルドしてみたよ
- example
- MSBuild sample.sln /t:Build /p:VisualStudioVersion=14;Configuration=Debug;Platform=x86
with google test
job flow
使い方のメモ。
githubからコードを入手
https://github.com/Excel-DNA
ExcelDna\Sourceにあるソリューションを開いてでビルドする。
ExcelDna\Build\build.batを実行。
新しいC#プロジェクトを作成。
ExcelDna\DistributionにあるExcelDna.Integrationを参照に追加。
namespace Excel { public class Export { public static double Add(double x, double y) { return x + y; } } }
ExcelDna.dnaを編集
<DnaLibrary RuntimeVersion="v4.0"> <ExternalLibrary Path="Excel.dll" /> </DnaLibrary>
ExcelDna.xllを開いて、新しいbookを作成し、Addを呼んでみる。
動いた!
Rangeを返す。
public static object[] ReturnArray(int n) { object[] array = new object[n]; for (int i = 0; i < n; ++i) { array[i] = i; } return array; } public static object[,] ReturnMatrix(int n) { object[,] array = new object[n, n]; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { array[i, j] = i + j; } } return array; }
Rangeを受け取る
public static string UpdateRange(object[,] range) { for (int i = 0; i < range.GetLength(0); ++i) { for (int j = 0; j < range.GetLength(1); ++j) { range[i, j] = i + j; } } return "success!!"; }
ん?? 更新できない・・・
できないことはないようだが、推奨されていないみたい。
https://groups.google.com/forum/#!topic/exceldna/SCPBnuw7Cl8
tupleを展開して、関数の引数にする。
したいこと。
int main() { auto x = std::make_tuple(1, 2.0, "three"); auto f = [](auto a, auto b, auto c) { std::cout << typeid(a).name() << std::endl; std::cout << typeid(b).name() << std::endl; std::cout << typeid(c).name() << std::endl; }; apply(f, x); return 0; }
上記のようにapplyに関数とtupleを渡した時に、下記のように関数を評価したい。
f(1, 2.0, "three");
variadic templateを再帰的に呼び出すことによって、tupleの中身を順次Args&... argsに貯める。最後に関数fに渡す。
template <int N> struct Expand { template <typename F, typename Tuple, typename... Args> static void apply(F& f, Tuple& t, Args&... args) { Expand<N - 1>::apply(f, t, std::get<N - 1>(t), args...); } }; template <> struct Expand<0> { template <typename F, typename Tuple, typename... Args> static void apply(F& f, Tuple& t, Args&... args) { f(args...); } }; template <typename F, typename Tuple> void apply(F& f, Tuple& t) { Expand<std::tuple_size<Tuple>::value>::apply(f, t); }
実行イメージ
Expand<3>::apply(f, x)
Expand<2>::apply(f, x, "three")
Expand<1>::apply(f, x, 2.0, "three")
Expand<0>::apply(f, x, 1, 2.0, "three")
f(1, 2.0, "three")
C++でC#のクエリのようなものを作る。
最近、C#を勉強していてlinqのクエリ(?)がすごく便利だと感じたので、C++でそれっぽいのを作ろう。
進捗は
- select
- select_with_index
- select_unzip
- where
- where_with_index
- skip
- take
- zip
を作成。
使い方は下記の通り。
コードは
GitHub - nishiba/query: c++ code like c# query
int main() { std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7 }; std::vector<int> y = { 0, 1, 2, 3, 4, 5, 6, 7 }; for (auto& x : where(v, [](int x) -> bool {return (x % 2) == 0; })) { std::cout << x << std::endl; } std::cout << std::endl; for (auto& x : where_with_index(v, [](int x, std::size_t index) -> bool {return (index < 4); })) { std::cout << x << std::endl; } std::cout << std::endl; for (auto& x : skip(v, 1).where([](int x) {return x < 6; })) { std::cout << x << std::endl; } std::cout << std::endl; for (auto x : skip(v, 1).select([](int x) {return x < 6; })) { std::cout << x << std::endl; } std::cout << std::endl; for (auto& x : zip(v, y).take(2)) { std::cout << x.get<0>() << "," << x.get<1>() << std::endl; } std::cout << std::endl; for (auto&& x : select_unzip(zip(v, y), [](auto& x, auto& y) {return x + y; })) { std::cout << x << std::endl; } std::cout << std::endl; for (auto& x : skip(v, 1).take(3)) { std::cout << x << std::endl; } return 0; }
C#からExcelを開く
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Office.Interop; using Excel = Microsoft.Office.Interop.Excel; using System.IO; using System.Runtime.InteropServices; namespace excel_starter { class Program { static void Main(string[] args) { try { var app = new Excel.Application(); // Make the object visible. app.Visible = true; // Load My Addin //app.RegisterXLL(Directory.GetCurrentDirectory() + "\\addin.xll"); // Open My Workbook Excel.Workbooks wbks = app.Workbooks; wbks.Open(Directory.GetCurrentDirectory() + "\\addin1.xlam"); Excel.Workbook wbk = wbks.Open(Directory.GetCurrentDirectory() + "\\example.xlsx"); // Release COM-Objects Marshal.ReleaseComObject(wbk); Marshal.ReleaseComObject(wbks); Marshal.ReleaseComObject(app); } catch (Exception e) { Console.WriteLine(e.Message); } } } }