private:
QNetworkAccessManager manager;
struct Data {
+ Data() : first(0), last(0), score(0) {}
float first;
float last;
float score;
{
QObject::connect(&manager, &QNetworkAccessManager::finished, [this](QNetworkReply *reply) {
QJubatusAnomaly anomaly;
- anomaly.setTimeout(60);
+ bool hasError = false;
+ connect(&anomaly, &QJubatusAnomaly::error, [&hasError](const QString &message) { hasError = true; });
+
QStringList lines = QTextCodec::codecForName("Shift-JIS")->toUnicode(reply->readAll()).split(QStringLiteral("\r\n"));
foreach (const QString &line, lines) {
QStringList columns = line.split(QStringLiteral(","));
params.insert("first", d.first * 100);
params.insert("last", d.last * 100);
params.insert("diff", (d.last - d.first) * 100);
- QJubatusAnomaly::IdAndScore ret = anomaly.add(params);
- d.score = ret.score;
+ if (!hasError) {
+ QJubatusAnomaly::IdAndScore ret = anomaly.add(params);
+ d.score = ret.score;
+ }
data.append(d);
}
}
return ret;
}
-static QList<QJubatusClassifier::TrainData> makeTrainData(const QString &label, const Ui::Widget *ui)
+static QList<QJubatusClassifier::LabeledDatum> makeTrainData(const QString &label, const Ui::Widget *ui)
{
- QList<QJubatusClassifier::TrainData> ret;
- QJubatusClassifier::TrainData data;
- data.first = label;
- data.second = makeDatum(ui);
+ QList<QJubatusClassifier::LabeledDatum> ret;
+ QJubatusClassifier::LabeledDatum data;
+ data.label = label;
+ data.data = makeDatum(ui);
ret.append(data);
return ret;
}
: QDialog(parent)
, ui(new Ui::Widget)
{
- classifier.setTimeout(10.0);
classifier.setName(QStringLiteral("test"));
+ connect(&classifier, &QJubatusClassifier::error, [this](const QString &message) {
+ QMessageBox::warning(this, tr("Error"), message);
+ });
ui->setupUi(this);
connect(ui->male, &QPushButton::clicked, [&] {
TEMPLATE = subdirs
-SUBDIRS += anomaly classifier
+SUBDIRS += anomaly classifier recommender
--- /dev/null
+長野久義,巨人,0.301,144,653,574,173,14,60,20,75,1,100,2,5,0.432,0.382,0.815,6.45,6.2
+大島洋平,中日,0.31,144,631,555,172,1,13,32,46,13,80,17,7,0.368,0.376,0.744,5.13,4.91
+鳥谷敬,阪神,0.262,144,624,515,135,8,59,15,94,2,91,5,12,0.375,0.373,0.748,5.28,5.33
+坂本勇人,巨人,0.311,144,619,557,173,14,69,16,39,6,90,12,5,0.456,0.359,0.815,6.29,6.06
+中田翔,日本ハム,0.239,144,606,547,131,24,77,5,50,5,101,0,8,0.42,0.307,0.727,4.44,4.54
+李大浩,オリックス,0.286,144,601,525,150,24,91,0,64,7,85,0,18,0.478,0.368,0.846,5.99,5.95
+陽岱鋼,日本ハム,0.287,144,599,533,153,7,55,17,37,6,123,18,10,0.398,0.337,0.735,4.7,4.59
+糸井嘉男,日本ハム,0.304,134,597,510,155,9,48,22,75,11,86,0,9,0.41,0.404,0.813,6.47,6.26
+聖澤諒,楽天,0.27,138,595,523,141,4,45,54,49,7,104,12,4,0.331,0.338,0.669,4.55,4.54
+田中浩康,ヤクルト,0.274,139,593,486,133,2,40,1,54,9,60,40,15,0.323,0.354,0.677,3.89,3.86
+和田一浩,中日,0.285,144,586,508,145,9,63,2,71,1,72,0,14,0.409,0.37,0.78,5.57,5.47
+根元俊一,ロッテ,0.279,133,584,512,143,9,41,6,31,1,98,40,7,0.396,0.322,0.718,4.16,4.01
+ヘルマン,西武,0.27,144,583,507,137,3,60,41,57,4,75,10,20,0.343,0.346,0.689,4.06,4.05
+井口資仁,ロッテ,0.255,140,578,505,129,11,60,3,53,16,99,0,11,0.384,0.343,0.727,4.73,4.7
+村田修一,巨人,0.252,144,575,516,130,12,58,1,36,15,85,2,16,0.374,0.316,0.69,3.83,3.89
+梵英心,広島,0.244,137,575,499,122,10,52,14,50,1,70,19,7,0.359,0.311,0.67,3.77,3.85
+バルディリス,オリックス,0.264,143,574,503,133,10,55,1,54,14,76,0,13,0.394,0.35,0.744,4.9,4.8
+荒木雅博,中日,0.251,129,569,510,128,3,31,12,19,2,65,36,4,0.314,0.28,0.593,2.93,2.89
+内川聖一,ソフトバンク,0.3,138,567,523,157,7,53,6,31,6,36,0,12,0.392,0.342,0.734,4.81,4.73
+中島裕之,西武,0.311,136,567,499,155,13,74,7,52,9,76,1,10,0.451,0.382,0.833,6.29,6.14
+明石健志,ソフトバンク,0.254,135,567,508,129,1,27,25,33,2,98,23,2,0.299,0.301,0.601,3.21,3.21
+サブロー,ロッテ,0.239,137,560,476,114,7,52,0,78,2,105,0,12,0.342,0.346,0.689,4.29,4.32
+阿部慎之助,巨人,0.34,138,556,467,159,27,104,0,69,9,47,2,11,0.565,0.429,0.994,9,8.79
+堂林翔太,広島,0.242,144,554,488,118,14,45,5,44,14,150,5,8,0.395,0.321,0.716,4.4,4.42
+井端弘和,中日,0.284,140,553,489,139,2,35,4,52,3,58,8,14,0.331,0.356,0.687,4.18,4.06
+荒波翔,DeNA,0.268,141,550,504,135,1,25,24,23,5,90,16,2,0.333,0.305,0.639,3.59,3.52
+小谷野栄一,日本ハム,0.228,134,550,478,109,3,39,6,27,4,72,40,8,0.293,0.275,0.567,2.48,2.47
+後藤光尊,オリックス,0.242,131,546,520,126,4,43,3,14,5,74,1,8,0.306,0.266,0.572,2.6,2.69
+ミレッジ,ヤクルト,0.3,125,546,476,143,21,65,9,57,6,79,3,11,0.485,0.379,0.865,6.46,6.34
+本多雄一,ソフトバンク,0.246,123,536,480,118,0,31,34,37,1,65,14,6,0.294,0.299,0.593,3.26,3.3
+角中勝也,ロッテ,0.312,128,525,477,149,3,61,8,38,5,68,1,9,0.415,0.366,0.782,5.67,5.43
+平野恵一,阪神,0.245,134,519,458,112,1,24,6,42,4,61,15,4,0.271,0.313,0.584,3.12,3.13
+ペーニャ,ソフトバンク,0.28,130,507,461,129,21,76,2,35,8,130,0,11,0.49,0.339,0.829,5.8,5.68
+川端慎吾,ヤクルト,0.298,125,507,453,135,4,49,3,35,2,56,13,7,0.38,0.348,0.728,4.82,4.72
+田中賢介,日本ハム,0.3,114,505,457,137,3,32,13,35,2,36,8,2,0.363,0.35,0.713,4.81,4.7
+ラミレス,DeNA,0.3,137,504,476,143,19,76,0,18,7,60,0,18,0.473,0.333,0.806,5.26,5.13
+今江敏晃,ロッテ,0.253,136,501,446,113,6,47,0,19,5,37,23,15,0.354,0.287,0.641,2.98,3.08
+中村紀洋,DeNA,0.274,126,500,442,121,11,61,1,50,2,72,0,14,0.407,0.346,0.753,4.86,4.87
+中村剛也,西武,0.231,123,498,432,100,27,79,2,56,9,125,0,11,0.461,0.331,0.792,5.04,5.16
+稲葉篤紀,日本ハム,0.29,127,497,449,130,10,61,0,32,5,70,8,3,0.421,0.342,0.762,5.38,5.22
+畠山和洋,ヤクルト,0.266,121,497,455,121,13,55,2,37,2,64,1,13,0.402,0.323,0.725,4.39,4.35
+森野将彦,中日,0.249,124,494,434,108,6,50,1,49,3,68,4,13,0.348,0.327,0.674,3.87,3.89
+新井貴浩,阪神,0.25,122,493,460,115,9,52,1,30,1,85,0,12,0.363,0.296,0.659,3.43,3.4
+フェルナンデス,楽天,0.243,129,489,440,107,3,51,2,44,2,67,0,11,0.311,0.313,0.624,3.25,3.28
+銀次,楽天,0.28,126,485,432,121,4,45,8,22,4,37,23,4,0.354,0.318,0.672,3.98,3.94
+川端崇義,オリックス,0.266,125,484,429,114,2,27,6,22,9,59,24,8,0.317,0.315,0.632,3.36,3.25
+岡田幸文,ロッテ,0.262,131,482,431,113,0,18,23,18,6,47,25,4,0.288,0.3,0.587,2.82,2.85
+長谷川勇也,ソフトバンク,0.278,126,473,403,112,4,37,16,40,9,87,16,4,0.36,0.352,0.712,4.77,4.76
+マートン,阪神,0.26,121,473,453,118,5,38,2,18,1,56,0,14,0.342,0.29,0.632,3.01,2.96
+栗山巧,西武,0.289,103,467,394,114,2,33,3,52,6,62,12,4,0.353,0.378,0.731,5.28,5.18
+浅村栄斗,西武,0.245,114,459,404,99,7,37,13,34,4,63,13,9,0.376,0.307,0.683,3.79,3.84
+谷繁元信,中日,0.228,134,458,386,88,5,32,0,52,4,67,14,15,0.303,0.324,0.627,3.11,3.16
+秋山翔吾,西武,0.293,107,450,403,118,4,37,10,28,3,70,15,7,0.404,0.343,0.747,4.82,4.63
+筒香嘉智,DeNA,0.218,108,446,386,84,10,45,1,51,2,102,2,4,0.352,0.309,0.661,3.8,3.98
+高橋由伸,巨人,0.239,130,442,368,88,8,56,2,61,8,77,1,14,0.351,0.356,0.707,4.23,4.32
+里崎智也,ロッテ,0.244,120,439,385,94,9,41,0,33,4,80,14,11,0.345,0.308,0.654,3.38,3.46
+松井稼頭央,楽天,0.266,106,433,402,107,9,43,14,26,1,55,3,6,0.408,0.312,0.72,4.58,4.45
+大引啓次,オリックス,0.224,110,432,352,79,6,20,6,46,3,74,28,8,0.315,0.317,0.632,3.33,3.44
+牧田明久,楽天,0.225,123,425,378,85,9,53,5,23,9,49,10,11,0.331,0.283,0.613,2.68,2.86
+バレンティン,ヤクルト,0.272,106,422,353,96,31,81,1,64,3,92,0,14,0.572,0.386,0.958,7.34,7.35
+炭谷銀仁朗,西武,0.194,139,414,360,70,0,23,0,17,1,74,35,9,0.233,0.232,0.466,1.17,1.23
+金本知憲,阪神,0.258,126,406,356,92,6,30,3,49,0,54,0,2,0.36,0.347,0.707,4.78,4.74
+T-岡田,オリックス,0.28,103,404,378,106,10,56,4,22,4,81,0,5,0.418,0.327,0.745,4.87,4.7
+天谷宗一郎,広島,0.265,108,397,359,95,6,25,12,32,3,64,2,3,0.373,0.329,0.702,4.33,4.25
+宮本慎也,ヤクルト,0.267,110,394,356,95,3,23,1,16,5,38,16,9,0.306,0.307,0.613,3.08,3.05
+松田宣浩,ソフトバンク,0.3,95,390,360,108,9,56,16,27,1,63,0,7,0.492,0.349,0.84,5.87,5.59
+新井良太,阪神,0.28,110,370,322,90,11,32,1,38,6,73,3,7,0.438,0.365,0.803,5.77,5.65
+スケールズ,オリックス,0.262,85,362,305,80,5,23,4,47,8,103,0,3,0.384,0.373,0.757,5.6,5.54
+ブランコ,中日,0.248,96,359,311,77,24,65,2,40,5,84,0,5,0.511,0.34,0.851,6.06,6.22
+小久保裕紀,ソフトバンク,0.239,103,357,331,79,4,34,0,20,0,67,3,6,0.308,0.28,0.588,2.8,2.89
+鉄平,楽天,0.251,121,355,315,79,1,33,8,11,6,45,18,7,0.302,0.285,0.586,2.62,2.75
+大和,阪神,0.257,128,349,311,80,0,26,17,15,4,46,19,3,0.318,0.3,0.618,3.19,3.1
+今宮健太,ソフトバンク,0.238,126,343,307,73,2,14,8,10,3,75,21,2,0.29,0.267,0.557,2.44,2.51
+丸佳浩,広島,0.247,106,339,283,70,4,22,14,46,2,59,5,4,0.353,0.353,0.707,4.62,4.7
+廣瀬純,広島,0.241,102,337,294,71,6,33,0,24,11,55,7,3,0.347,0.321,0.668,4.02,4.02
+金城龍彦,DeNA,0.238,129,331,294,70,3,18,2,26,6,37,3,1,0.306,0.311,0.617,3.58,3.65
+鶴岡慎也,日本ハム,0.266,116,328,289,77,0,25,3,14,1,41,23,11,0.308,0.302,0.61,2.68,2.61
+ホフパワー,日本ハム,0.247,109,325,296,73,14,37,1,25,3,81,0,3,0.432,0.311,0.743,4.74,4.77
+嶋基宏,楽天,0.291,91,316,265,77,1,8,3,33,4,51,13,5,0.332,0.376,0.708,4.53,4.47
+金子誠,日本ハム,0.227,103,311,277,63,0,22,1,15,0,53,17,2,0.292,0.265,0.558,2.3,2.31
+石川雄洋,DeNA,0.285,80,304,263,75,1,14,7,24,3,49,13,3,0.342,0.351,0.693,4.21,4.11
+平田良介,中日,0.216,91,301,269,58,11,32,1,28,1,59,1,9,0.361,0.29,0.651,3.26,3.47
+大崎雄太朗,西武,0.269,107,298,260,70,1,22,1,17,7,27,10,4,0.346,0.326,0.673,4.06,4.04
+ガルシア,楽天,0.227,77,296,269,61,7,30,0,23,2,65,0,6,0.349,0.291,0.64,3.27,3.38
+ブラゼル,阪神,0.233,98,295,275,64,12,43,0,18,2,72,0,16,0.404,0.285,0.688,3.15,3.21
+清田育宏,ロッテ,0.281,87,292,253,71,3,29,5,34,0,46,3,5,0.391,0.363,0.755,5,4.9
+枡田慎太郎,楽天,0.295,79,290,254,75,5,32,1,19,5,56,7,2,0.433,0.35,0.783,5.55,5.51
+内村賢介,DeNA,0.237,77,289,236,56,0,18,18,31,0,40,21,4,0.263,0.325,0.587,3.19,3.22
+森岡良介,ヤクルト,0.249,100,282,245,61,1,18,1,11,5,44,19,1,0.318,0.293,0.611,3.16,3.17
+東出輝裕,広島,0.247,91,282,247,61,0,6,1,13,3,22,19,3,0.279,0.293,0.572,2.62,2.57
+藤村大介,巨人,0.252,109,279,238,60,0,10,14,15,0,35,26,2,0.298,0.296,0.595,2.84,2.79
+大松尚逸,ロッテ,0.198,89,275,258,51,5,22,0,9,2,46,3,7,0.291,0.228,0.519,1.7,1.91
+ホワイトセル,ロッテ,0.309,63,257,223,69,9,43,0,29,4,75,0,2,0.489,0.397,0.886,7.37,7.16
+谷佳知,巨人,0.258,89,255,229,59,3,22,1,14,0,48,11,5,0.319,0.299,0.618,2.97,2.97
+梶谷隆幸,DeNA,0.179,80,252,223,40,2,11,5,21,1,61,7,4,0.256,0.253,0.509,1.48,1.64
+エルドレッド,広島,0.262,65,251,225,59,11,35,0,20,3,67,0,3,0.453,0.327,0.78,5.29,5.38
+石原慶幸,広島,0.24,77,250,217,52,1,22,0,22,1,37,9,7,0.323,0.311,0.634,3.11,2.99
+中村悠平,ヤクルト,0.254,91,249,209,53,1,15,1,28,2,31,8,10,0.292,0.344,0.636,3.23,3.25
+赤松真人,広島,0.242,76,246,207,50,3,15,18,18,4,33,16,4,0.314,0.313,0.627,3.62,3.65
+相川亮二,ヤクルト,0.245,72,244,220,54,1,28,0,20,1,33,1,7,0.295,0.309,0.604,2.98,3
+岩本貴裕,広島,0.268,71,242,239,64,6,27,1,2,0,43,1,5,0.406,0.274,0.68,3.63,3.5
+菊池涼介,広島,0.229,63,234,201,46,2,12,4,6,1,42,25,5,0.294,0.254,0.547,1.99,2.04
+片岡易之,西武,0.225,52,231,204,46,2,19,8,15,1,30,7,6,0.294,0.277,0.571,2.19,2.44
+森本稀哲,DeNA,0.244,108,230,201,49,3,18,0,20,3,44,4,6,0.323,0.32,0.643,3.27,3.34
+鶴岡一成,DeNA,0.189,102,229,201,38,1,15,0,19,0,39,8,4,0.254,0.258,0.512,1.87,1.94
+松本哲也,巨人,0.258,83,229,198,51,0,11,12,17,0,34,12,4,0.313,0.313,0.626,3.5,3.5
+藤井彰人,阪神,0.248,81,228,210,52,1,10,0,9,2,39,7,3,0.286,0.285,0.571,2.59,2.54
+寺内崇幸,巨人,0.241,103,225,191,46,1,5,11,16,3,43,13,6,0.293,0.307,0.6,2.97,3.06
+上本博紀,阪神,0.254,62,224,197,50,1,7,13,19,5,46,2,3,0.345,0.333,0.679,4.26,4.18
+多村仁志,ソフトバンク,0.25,79,218,200,50,4,20,0,18,0,43,0,7,0.365,0.312,0.677,3.57,3.53
+細川亨,ソフトバンク,0.157,92,217,185,29,2,13,0,8,1,50,21,1,0.205,0.194,0.399,0.72,0.98
+福地寿樹,ヤクルト,0.255,83,216,188,48,0,19,12,16,4,29,6,3,0.335,0.324,0.659,4.17,4.1
+山崎武司,中日,0.209,90,215,191,40,1,13,1,18,4,44,0,5,0.293,0.288,0.582,2.72,2.79
+オーティズ,西武,0.286,64,214,199,57,9,21,0,14,1,38,0,8,0.462,0.336,0.799,5,4.91
+渡辺直人,DeNA,0.224,70,213,174,39,0,10,2,24,10,27,5,1,0.247,0.351,0.598,3.35,3.44
+柳田悠岐,ソフトバンク,0.246,68,212,195,48,5,18,6,10,5,56,2,2,0.385,0.3,0.685,4.14,4.05
+高須洋介,楽天,0.244,58,212,176,43,0,9,2,24,2,15,8,5,0.284,0.338,0.622,3.47,3.53
+ボウカー,巨人,0.196,69,204,184,36,3,10,2,16,2,54,2,3,0.31,0.267,0.577,2.64,2.66
+ニック,広島,0.238,52,204,181,43,9,24,0,22,1,42,0,4,0.431,0.324,0.754,4.78,4.79
+福浦和也,ロッテ,0.25,84,199,180,45,0,25,0,15,1,27,1,3,0.267,0.308,0.575,2.92,3.03
+伊藤光,オリックス,0.205,66,197,176,36,0,10,0,5,0,48,12,2,0.256,0.222,0.477,1.49,1.7
+エドガー,巨人,0.236,57,190,174,41,4,19,0,13,1,46,1,6,0.374,0.291,0.665,3.17,3.19
+藤田一也,楽天,0.308,63,188,172,53,0,15,5,4,0,10,11,4,0.378,0.322,0.7,4.05,3.84
+荻野貴司,ロッテ,0.224,61,187,165,37,1,8,13,11,5,17,6,0,0.273,0.293,0.566,3.11,3.14
+堂上直倫,中日,0.21,116,182,167,35,0,11,1,5,1,34,8,6,0.257,0.236,0.493,1.39,1.42
+江川智晃,ソフトバンク,0.244,56,175,160,39,4,18,1,8,0,37,4,3,0.388,0.275,0.662,3.5,3.7
+上田剛史,ヤクルト,0.257,50,173,148,38,0,12,8,12,0,30,13,2,0.318,0.313,0.63,3.23,3.15
+小宮山慎二,阪神,0.148,72,171,149,22,1,4,0,11,2,32,9,4,0.174,0.216,0.391,0.53,0.69
+堂上剛裕,中日,0.282,85,166,156,44,4,17,1,8,0,36,1,4,0.41,0.315,0.725,4.3,4.19
+坂口智隆,オリックス,0.228,40,165,158,36,0,8,2,5,0,13,2,0,0.253,0.252,0.505,1.96,2.01
+松中信彦,ソフトバンク,0.221,65,164,136,30,4,13,1,26,2,26,0,1,0.324,0.354,0.677,4.6,4.69
+倉義和,広島,0.195,70,160,133,26,1,15,1,14,5,20,8,6,0.263,0.296,0.559,2.23,2.28
+鈴木大地,ロッテ,0.274,62,160,135,37,0,11,0,13,1,23,10,1,0.326,0.34,0.666,4.07,4
+大野奨太,日本ハム,0.171,70,159,140,24,2,11,0,8,2,30,9,2,0.243,0.227,0.47,1.2,1.35
+北川博敏,オリックス,0.221,59,159,140,31,1,11,0,17,0,23,0,3,0.286,0.302,0.588,2.95,3.12
+柴田講平,阪神,0.234,73,157,128,30,0,2,4,16,1,23,11,1,0.273,0.322,0.595,3.03,3.12
+小池正晃,DeNA,0.192,88,155,130,25,3,19,0,10,8,31,6,5,0.292,0.289,0.581,2.43,2.63
+西川遥輝,日本ハム,0.239,71,155,134,32,2,13,7,14,0,34,7,0,0.343,0.311,0.654,4.18,4.11
+雄平,ヤクルト,0.28,47,153,143,40,0,8,2,7,0,19,3,0,0.308,0.313,0.621,3.4,3.31
+スレッジ,日本ハム,0.232,47,152,138,32,5,23,0,12,2,47,0,2,0.406,0.303,0.708,4.22,4.22
+下園辰哉,DeNA,0.252,90,150,139,35,0,14,0,10,0,21,1,6,0.324,0.302,0.626,2.93,2.77
+松井淳,ヤクルト,0.287,46,150,143,41,5,15,1,6,1,26,0,5,0.462,0.32,0.782,4.79,4.6
+野中信吾,オリックス,0.217,74,149,120,26,0,7,12,11,2,20,16,2,0.275,0.293,0.568,2.4,2.44
+古城茂幸,巨人,0.209,65,149,129,27,0,8,2,12,0,28,6,5,0.256,0.273,0.529,1.96,2.07
--- /dev/null
+#include "dialog.h"
+#include "ui_dialog.h"
+
+#include <QtCore>
+#include <QtJubatus>
+
+class Dialog::Private
+{
+public:
+ Private(Dialog *parent);
+
+private:
+ void playerChanged(const QString &id);
+
+private:
+ Dialog *q;
+ Ui::Dialog ui;
+ QJubatusRecommender recommender;
+};
+
+Dialog::Private::Private(Dialog *parent)
+ : q(parent)
+{
+ ui.setupUi(q);
+
+ recommender.setName("npb-similar-player");
+ recommender.setTimeout(10);
+
+ bool learn = recommender.getAllRows().isEmpty();
+
+ QFile file(":/baseball.csv");
+ file.open(QFile::ReadOnly | QFile::Text);
+ QTextStream stream(&file);
+ QStringList fields = QStringList() << "チーム" << "打率" << "試合数" << "打席" << "打数" << "安打" << "本塁打" << "打点" << "盗塁" << "四球" << "死球" << "三振" << "犠打" << "併殺打" << "長打率" << "出塁率" << "OPS" << "RC27" << "XR27";
+
+ while (!stream.atEnd()) {
+ QStringList list = stream.readLine().split(",");
+ QString id = list.takeFirst();
+ if (learn) {
+ QVariantMap data;
+ data.insert(fields.at(0), list.at(0));
+ for(int i = 1; i < fields.length(); i++) {
+ data.insert(fields.at(i), list.at(i).toFloat());
+ }
+ recommender.updateRow(id, data);
+ }
+ ui.player->addItem(id);
+ }
+ file.close();
+
+ connect(ui.buttonBox, &QDialogButtonBox::rejected, q, &QDialog::close);
+
+ connect(ui.player, &QComboBox::currentTextChanged, [this](const QString &id) {
+ playerChanged(id);
+ });
+ playerChanged(ui.player->currentText());
+}
+
+void Dialog::Private::playerChanged(const QString &id)
+{
+ QStringList results;
+ QList<QJubatusRecommender::IdWithScore> list = recommender.similarRowFromId(id, 10);
+ foreach (const QJubatusRecommender::IdWithScore idWithScore, list) {
+ if (idWithScore.id == id) continue;
+ results.append(QString("%1 (%2)").arg(idWithScore.id).arg(idWithScore.score));
+ }
+ ui.result->setPlainText(results.join(QStringLiteral("\n")));
+}
+
+Dialog::Dialog(QWidget *parent)
+ : QDialog(parent)
+ , d(new Private(this))
+{
+ connect(this, &QObject::destroyed, [this]() { delete d; });
+}
--- /dev/null
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include <QDialog>
+
+class Dialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit Dialog(QWidget *parent = 0);
+
+private:
+ class Private;
+ Private *d;
+};
+
+#endif // DIALOG_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>npb_similar_player</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QComboBox" name="player"/>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="result"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#include <QtWidgets>
+
+#include "dialog.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ Dialog dialog;
+ dialog.show();
+
+ return app.exec();
+}
--- /dev/null
+{
+ "method": "inverted_index",
+ "converter": {
+ "string_filter_types": {},
+ "string_filter_rules": [],
+ "num_filter_types": {},
+ "num_filter_rules": [],
+ "string_types": {},
+ "string_rules": [],
+ "num_types": {},
+ "num_rules": [
+ {"key" : "*", "type" : "num"}
+ ]
+ },
+ "parameter": {}
+}
--- /dev/null
+TEMPLATE = app
+TARGET = jubatus-npb-similar-player
+QT = core network gui widgets jubatus
+CONFIG += c++11
+SOURCES = main.cpp \
+ dialog.cpp
+
+OTHER_FILES += npb_similar_player
+
+RESOURCES += \
+ npb_similar_player.qrc
+
+FORMS += \
+ dialog.ui
+
+HEADERS += \
+ dialog.h
--- /dev/null
+<RCC>
+ <qresource prefix="/">
+ <file>baseball.csv</file>
+ </qresource>
+</RCC>
--- /dev/null
+TEMPLATE = subdirs
+SUBDIRS += npb_similar_player
TEMPLATE = subdirs
-SUBDIRS += classifier
+SUBDIRS += classifier recommender
--- /dev/null
+長野久義,巨人,0.301,144,653,574,173,14,60,20,75,1,100,2,5,0.432,0.382,0.815,6.45,6.2
+大島洋平,中日,0.31,144,631,555,172,1,13,32,46,13,80,17,7,0.368,0.376,0.744,5.13,4.91
+鳥谷敬,阪神,0.262,144,624,515,135,8,59,15,94,2,91,5,12,0.375,0.373,0.748,5.28,5.33
+坂本勇人,巨人,0.311,144,619,557,173,14,69,16,39,6,90,12,5,0.456,0.359,0.815,6.29,6.06
+中田翔,日本ハム,0.239,144,606,547,131,24,77,5,50,5,101,0,8,0.42,0.307,0.727,4.44,4.54
+李大浩,オリックス,0.286,144,601,525,150,24,91,0,64,7,85,0,18,0.478,0.368,0.846,5.99,5.95
+陽岱鋼,日本ハム,0.287,144,599,533,153,7,55,17,37,6,123,18,10,0.398,0.337,0.735,4.7,4.59
+糸井嘉男,日本ハム,0.304,134,597,510,155,9,48,22,75,11,86,0,9,0.41,0.404,0.813,6.47,6.26
+聖澤諒,楽天,0.27,138,595,523,141,4,45,54,49,7,104,12,4,0.331,0.338,0.669,4.55,4.54
+田中浩康,ヤクルト,0.274,139,593,486,133,2,40,1,54,9,60,40,15,0.323,0.354,0.677,3.89,3.86
+和田一浩,中日,0.285,144,586,508,145,9,63,2,71,1,72,0,14,0.409,0.37,0.78,5.57,5.47
+根元俊一,ロッテ,0.279,133,584,512,143,9,41,6,31,1,98,40,7,0.396,0.322,0.718,4.16,4.01
+ヘルマン,西武,0.27,144,583,507,137,3,60,41,57,4,75,10,20,0.343,0.346,0.689,4.06,4.05
+井口資仁,ロッテ,0.255,140,578,505,129,11,60,3,53,16,99,0,11,0.384,0.343,0.727,4.73,4.7
+村田修一,巨人,0.252,144,575,516,130,12,58,1,36,15,85,2,16,0.374,0.316,0.69,3.83,3.89
+梵英心,広島,0.244,137,575,499,122,10,52,14,50,1,70,19,7,0.359,0.311,0.67,3.77,3.85
+バルディリス,オリックス,0.264,143,574,503,133,10,55,1,54,14,76,0,13,0.394,0.35,0.744,4.9,4.8
+荒木雅博,中日,0.251,129,569,510,128,3,31,12,19,2,65,36,4,0.314,0.28,0.593,2.93,2.89
+内川聖一,ソフトバンク,0.3,138,567,523,157,7,53,6,31,6,36,0,12,0.392,0.342,0.734,4.81,4.73
+中島裕之,西武,0.311,136,567,499,155,13,74,7,52,9,76,1,10,0.451,0.382,0.833,6.29,6.14
+明石健志,ソフトバンク,0.254,135,567,508,129,1,27,25,33,2,98,23,2,0.299,0.301,0.601,3.21,3.21
+サブロー,ロッテ,0.239,137,560,476,114,7,52,0,78,2,105,0,12,0.342,0.346,0.689,4.29,4.32
+阿部慎之助,巨人,0.34,138,556,467,159,27,104,0,69,9,47,2,11,0.565,0.429,0.994,9,8.79
+堂林翔太,広島,0.242,144,554,488,118,14,45,5,44,14,150,5,8,0.395,0.321,0.716,4.4,4.42
+井端弘和,中日,0.284,140,553,489,139,2,35,4,52,3,58,8,14,0.331,0.356,0.687,4.18,4.06
+荒波翔,DeNA,0.268,141,550,504,135,1,25,24,23,5,90,16,2,0.333,0.305,0.639,3.59,3.52
+小谷野栄一,日本ハム,0.228,134,550,478,109,3,39,6,27,4,72,40,8,0.293,0.275,0.567,2.48,2.47
+後藤光尊,オリックス,0.242,131,546,520,126,4,43,3,14,5,74,1,8,0.306,0.266,0.572,2.6,2.69
+ミレッジ,ヤクルト,0.3,125,546,476,143,21,65,9,57,6,79,3,11,0.485,0.379,0.865,6.46,6.34
+本多雄一,ソフトバンク,0.246,123,536,480,118,0,31,34,37,1,65,14,6,0.294,0.299,0.593,3.26,3.3
+角中勝也,ロッテ,0.312,128,525,477,149,3,61,8,38,5,68,1,9,0.415,0.366,0.782,5.67,5.43
+平野恵一,阪神,0.245,134,519,458,112,1,24,6,42,4,61,15,4,0.271,0.313,0.584,3.12,3.13
+ペーニャ,ソフトバンク,0.28,130,507,461,129,21,76,2,35,8,130,0,11,0.49,0.339,0.829,5.8,5.68
+川端慎吾,ヤクルト,0.298,125,507,453,135,4,49,3,35,2,56,13,7,0.38,0.348,0.728,4.82,4.72
+田中賢介,日本ハム,0.3,114,505,457,137,3,32,13,35,2,36,8,2,0.363,0.35,0.713,4.81,4.7
+ラミレス,DeNA,0.3,137,504,476,143,19,76,0,18,7,60,0,18,0.473,0.333,0.806,5.26,5.13
+今江敏晃,ロッテ,0.253,136,501,446,113,6,47,0,19,5,37,23,15,0.354,0.287,0.641,2.98,3.08
+中村紀洋,DeNA,0.274,126,500,442,121,11,61,1,50,2,72,0,14,0.407,0.346,0.753,4.86,4.87
+中村剛也,西武,0.231,123,498,432,100,27,79,2,56,9,125,0,11,0.461,0.331,0.792,5.04,5.16
+稲葉篤紀,日本ハム,0.29,127,497,449,130,10,61,0,32,5,70,8,3,0.421,0.342,0.762,5.38,5.22
+畠山和洋,ヤクルト,0.266,121,497,455,121,13,55,2,37,2,64,1,13,0.402,0.323,0.725,4.39,4.35
+森野将彦,中日,0.249,124,494,434,108,6,50,1,49,3,68,4,13,0.348,0.327,0.674,3.87,3.89
+新井貴浩,阪神,0.25,122,493,460,115,9,52,1,30,1,85,0,12,0.363,0.296,0.659,3.43,3.4
+フェルナンデス,楽天,0.243,129,489,440,107,3,51,2,44,2,67,0,11,0.311,0.313,0.624,3.25,3.28
+銀次,楽天,0.28,126,485,432,121,4,45,8,22,4,37,23,4,0.354,0.318,0.672,3.98,3.94
+川端崇義,オリックス,0.266,125,484,429,114,2,27,6,22,9,59,24,8,0.317,0.315,0.632,3.36,3.25
+岡田幸文,ロッテ,0.262,131,482,431,113,0,18,23,18,6,47,25,4,0.288,0.3,0.587,2.82,2.85
+長谷川勇也,ソフトバンク,0.278,126,473,403,112,4,37,16,40,9,87,16,4,0.36,0.352,0.712,4.77,4.76
+マートン,阪神,0.26,121,473,453,118,5,38,2,18,1,56,0,14,0.342,0.29,0.632,3.01,2.96
+栗山巧,西武,0.289,103,467,394,114,2,33,3,52,6,62,12,4,0.353,0.378,0.731,5.28,5.18
+浅村栄斗,西武,0.245,114,459,404,99,7,37,13,34,4,63,13,9,0.376,0.307,0.683,3.79,3.84
+谷繁元信,中日,0.228,134,458,386,88,5,32,0,52,4,67,14,15,0.303,0.324,0.627,3.11,3.16
+秋山翔吾,西武,0.293,107,450,403,118,4,37,10,28,3,70,15,7,0.404,0.343,0.747,4.82,4.63
+筒香嘉智,DeNA,0.218,108,446,386,84,10,45,1,51,2,102,2,4,0.352,0.309,0.661,3.8,3.98
+高橋由伸,巨人,0.239,130,442,368,88,8,56,2,61,8,77,1,14,0.351,0.356,0.707,4.23,4.32
+里崎智也,ロッテ,0.244,120,439,385,94,9,41,0,33,4,80,14,11,0.345,0.308,0.654,3.38,3.46
+松井稼頭央,楽天,0.266,106,433,402,107,9,43,14,26,1,55,3,6,0.408,0.312,0.72,4.58,4.45
+大引啓次,オリックス,0.224,110,432,352,79,6,20,6,46,3,74,28,8,0.315,0.317,0.632,3.33,3.44
+牧田明久,楽天,0.225,123,425,378,85,9,53,5,23,9,49,10,11,0.331,0.283,0.613,2.68,2.86
+バレンティン,ヤクルト,0.272,106,422,353,96,31,81,1,64,3,92,0,14,0.572,0.386,0.958,7.34,7.35
+炭谷銀仁朗,西武,0.194,139,414,360,70,0,23,0,17,1,74,35,9,0.233,0.232,0.466,1.17,1.23
+金本知憲,阪神,0.258,126,406,356,92,6,30,3,49,0,54,0,2,0.36,0.347,0.707,4.78,4.74
+T-岡田,オリックス,0.28,103,404,378,106,10,56,4,22,4,81,0,5,0.418,0.327,0.745,4.87,4.7
+天谷宗一郎,広島,0.265,108,397,359,95,6,25,12,32,3,64,2,3,0.373,0.329,0.702,4.33,4.25
+宮本慎也,ヤクルト,0.267,110,394,356,95,3,23,1,16,5,38,16,9,0.306,0.307,0.613,3.08,3.05
+松田宣浩,ソフトバンク,0.3,95,390,360,108,9,56,16,27,1,63,0,7,0.492,0.349,0.84,5.87,5.59
+新井良太,阪神,0.28,110,370,322,90,11,32,1,38,6,73,3,7,0.438,0.365,0.803,5.77,5.65
+スケールズ,オリックス,0.262,85,362,305,80,5,23,4,47,8,103,0,3,0.384,0.373,0.757,5.6,5.54
+ブランコ,中日,0.248,96,359,311,77,24,65,2,40,5,84,0,5,0.511,0.34,0.851,6.06,6.22
+小久保裕紀,ソフトバンク,0.239,103,357,331,79,4,34,0,20,0,67,3,6,0.308,0.28,0.588,2.8,2.89
+鉄平,楽天,0.251,121,355,315,79,1,33,8,11,6,45,18,7,0.302,0.285,0.586,2.62,2.75
+大和,阪神,0.257,128,349,311,80,0,26,17,15,4,46,19,3,0.318,0.3,0.618,3.19,3.1
+今宮健太,ソフトバンク,0.238,126,343,307,73,2,14,8,10,3,75,21,2,0.29,0.267,0.557,2.44,2.51
+丸佳浩,広島,0.247,106,339,283,70,4,22,14,46,2,59,5,4,0.353,0.353,0.707,4.62,4.7
+廣瀬純,広島,0.241,102,337,294,71,6,33,0,24,11,55,7,3,0.347,0.321,0.668,4.02,4.02
+金城龍彦,DeNA,0.238,129,331,294,70,3,18,2,26,6,37,3,1,0.306,0.311,0.617,3.58,3.65
+鶴岡慎也,日本ハム,0.266,116,328,289,77,0,25,3,14,1,41,23,11,0.308,0.302,0.61,2.68,2.61
+ホフパワー,日本ハム,0.247,109,325,296,73,14,37,1,25,3,81,0,3,0.432,0.311,0.743,4.74,4.77
+嶋基宏,楽天,0.291,91,316,265,77,1,8,3,33,4,51,13,5,0.332,0.376,0.708,4.53,4.47
+金子誠,日本ハム,0.227,103,311,277,63,0,22,1,15,0,53,17,2,0.292,0.265,0.558,2.3,2.31
+石川雄洋,DeNA,0.285,80,304,263,75,1,14,7,24,3,49,13,3,0.342,0.351,0.693,4.21,4.11
+平田良介,中日,0.216,91,301,269,58,11,32,1,28,1,59,1,9,0.361,0.29,0.651,3.26,3.47
+大崎雄太朗,西武,0.269,107,298,260,70,1,22,1,17,7,27,10,4,0.346,0.326,0.673,4.06,4.04
+ガルシア,楽天,0.227,77,296,269,61,7,30,0,23,2,65,0,6,0.349,0.291,0.64,3.27,3.38
+ブラゼル,阪神,0.233,98,295,275,64,12,43,0,18,2,72,0,16,0.404,0.285,0.688,3.15,3.21
+清田育宏,ロッテ,0.281,87,292,253,71,3,29,5,34,0,46,3,5,0.391,0.363,0.755,5,4.9
+枡田慎太郎,楽天,0.295,79,290,254,75,5,32,1,19,5,56,7,2,0.433,0.35,0.783,5.55,5.51
+内村賢介,DeNA,0.237,77,289,236,56,0,18,18,31,0,40,21,4,0.263,0.325,0.587,3.19,3.22
+森岡良介,ヤクルト,0.249,100,282,245,61,1,18,1,11,5,44,19,1,0.318,0.293,0.611,3.16,3.17
+東出輝裕,広島,0.247,91,282,247,61,0,6,1,13,3,22,19,3,0.279,0.293,0.572,2.62,2.57
+藤村大介,巨人,0.252,109,279,238,60,0,10,14,15,0,35,26,2,0.298,0.296,0.595,2.84,2.79
+大松尚逸,ロッテ,0.198,89,275,258,51,5,22,0,9,2,46,3,7,0.291,0.228,0.519,1.7,1.91
+ホワイトセル,ロッテ,0.309,63,257,223,69,9,43,0,29,4,75,0,2,0.489,0.397,0.886,7.37,7.16
+谷佳知,巨人,0.258,89,255,229,59,3,22,1,14,0,48,11,5,0.319,0.299,0.618,2.97,2.97
+梶谷隆幸,DeNA,0.179,80,252,223,40,2,11,5,21,1,61,7,4,0.256,0.253,0.509,1.48,1.64
+エルドレッド,広島,0.262,65,251,225,59,11,35,0,20,3,67,0,3,0.453,0.327,0.78,5.29,5.38
+石原慶幸,広島,0.24,77,250,217,52,1,22,0,22,1,37,9,7,0.323,0.311,0.634,3.11,2.99
+中村悠平,ヤクルト,0.254,91,249,209,53,1,15,1,28,2,31,8,10,0.292,0.344,0.636,3.23,3.25
+赤松真人,広島,0.242,76,246,207,50,3,15,18,18,4,33,16,4,0.314,0.313,0.627,3.62,3.65
+相川亮二,ヤクルト,0.245,72,244,220,54,1,28,0,20,1,33,1,7,0.295,0.309,0.604,2.98,3
+岩本貴裕,広島,0.268,71,242,239,64,6,27,1,2,0,43,1,5,0.406,0.274,0.68,3.63,3.5
+菊池涼介,広島,0.229,63,234,201,46,2,12,4,6,1,42,25,5,0.294,0.254,0.547,1.99,2.04
+片岡易之,西武,0.225,52,231,204,46,2,19,8,15,1,30,7,6,0.294,0.277,0.571,2.19,2.44
+森本稀哲,DeNA,0.244,108,230,201,49,3,18,0,20,3,44,4,6,0.323,0.32,0.643,3.27,3.34
+鶴岡一成,DeNA,0.189,102,229,201,38,1,15,0,19,0,39,8,4,0.254,0.258,0.512,1.87,1.94
+松本哲也,巨人,0.258,83,229,198,51,0,11,12,17,0,34,12,4,0.313,0.313,0.626,3.5,3.5
+藤井彰人,阪神,0.248,81,228,210,52,1,10,0,9,2,39,7,3,0.286,0.285,0.571,2.59,2.54
+寺内崇幸,巨人,0.241,103,225,191,46,1,5,11,16,3,43,13,6,0.293,0.307,0.6,2.97,3.06
+上本博紀,阪神,0.254,62,224,197,50,1,7,13,19,5,46,2,3,0.345,0.333,0.679,4.26,4.18
+多村仁志,ソフトバンク,0.25,79,218,200,50,4,20,0,18,0,43,0,7,0.365,0.312,0.677,3.57,3.53
+細川亨,ソフトバンク,0.157,92,217,185,29,2,13,0,8,1,50,21,1,0.205,0.194,0.399,0.72,0.98
+福地寿樹,ヤクルト,0.255,83,216,188,48,0,19,12,16,4,29,6,3,0.335,0.324,0.659,4.17,4.1
+山崎武司,中日,0.209,90,215,191,40,1,13,1,18,4,44,0,5,0.293,0.288,0.582,2.72,2.79
+オーティズ,西武,0.286,64,214,199,57,9,21,0,14,1,38,0,8,0.462,0.336,0.799,5,4.91
+渡辺直人,DeNA,0.224,70,213,174,39,0,10,2,24,10,27,5,1,0.247,0.351,0.598,3.35,3.44
+柳田悠岐,ソフトバンク,0.246,68,212,195,48,5,18,6,10,5,56,2,2,0.385,0.3,0.685,4.14,4.05
+高須洋介,楽天,0.244,58,212,176,43,0,9,2,24,2,15,8,5,0.284,0.338,0.622,3.47,3.53
+ボウカー,巨人,0.196,69,204,184,36,3,10,2,16,2,54,2,3,0.31,0.267,0.577,2.64,2.66
+ニック,広島,0.238,52,204,181,43,9,24,0,22,1,42,0,4,0.431,0.324,0.754,4.78,4.79
+福浦和也,ロッテ,0.25,84,199,180,45,0,25,0,15,1,27,1,3,0.267,0.308,0.575,2.92,3.03
+伊藤光,オリックス,0.205,66,197,176,36,0,10,0,5,0,48,12,2,0.256,0.222,0.477,1.49,1.7
+エドガー,巨人,0.236,57,190,174,41,4,19,0,13,1,46,1,6,0.374,0.291,0.665,3.17,3.19
+藤田一也,楽天,0.308,63,188,172,53,0,15,5,4,0,10,11,4,0.378,0.322,0.7,4.05,3.84
+荻野貴司,ロッテ,0.224,61,187,165,37,1,8,13,11,5,17,6,0,0.273,0.293,0.566,3.11,3.14
+堂上直倫,中日,0.21,116,182,167,35,0,11,1,5,1,34,8,6,0.257,0.236,0.493,1.39,1.42
+江川智晃,ソフトバンク,0.244,56,175,160,39,4,18,1,8,0,37,4,3,0.388,0.275,0.662,3.5,3.7
+上田剛史,ヤクルト,0.257,50,173,148,38,0,12,8,12,0,30,13,2,0.318,0.313,0.63,3.23,3.15
+小宮山慎二,阪神,0.148,72,171,149,22,1,4,0,11,2,32,9,4,0.174,0.216,0.391,0.53,0.69
+堂上剛裕,中日,0.282,85,166,156,44,4,17,1,8,0,36,1,4,0.41,0.315,0.725,4.3,4.19
+坂口智隆,オリックス,0.228,40,165,158,36,0,8,2,5,0,13,2,0,0.253,0.252,0.505,1.96,2.01
+松中信彦,ソフトバンク,0.221,65,164,136,30,4,13,1,26,2,26,0,1,0.324,0.354,0.677,4.6,4.69
+倉義和,広島,0.195,70,160,133,26,1,15,1,14,5,20,8,6,0.263,0.296,0.559,2.23,2.28
+鈴木大地,ロッテ,0.274,62,160,135,37,0,11,0,13,1,23,10,1,0.326,0.34,0.666,4.07,4
+大野奨太,日本ハム,0.171,70,159,140,24,2,11,0,8,2,30,9,2,0.243,0.227,0.47,1.2,1.35
+北川博敏,オリックス,0.221,59,159,140,31,1,11,0,17,0,23,0,3,0.286,0.302,0.588,2.95,3.12
+柴田講平,阪神,0.234,73,157,128,30,0,2,4,16,1,23,11,1,0.273,0.322,0.595,3.03,3.12
+小池正晃,DeNA,0.192,88,155,130,25,3,19,0,10,8,31,6,5,0.292,0.289,0.581,2.43,2.63
+西川遥輝,日本ハム,0.239,71,155,134,32,2,13,7,14,0,34,7,0,0.343,0.311,0.654,4.18,4.11
+雄平,ヤクルト,0.28,47,153,143,40,0,8,2,7,0,19,3,0,0.308,0.313,0.621,3.4,3.31
+スレッジ,日本ハム,0.232,47,152,138,32,5,23,0,12,2,47,0,2,0.406,0.303,0.708,4.22,4.22
+下園辰哉,DeNA,0.252,90,150,139,35,0,14,0,10,0,21,1,6,0.324,0.302,0.626,2.93,2.77
+松井淳,ヤクルト,0.287,46,150,143,41,5,15,1,6,1,26,0,5,0.462,0.32,0.782,4.79,4.6
+野中信吾,オリックス,0.217,74,149,120,26,0,7,12,11,2,20,16,2,0.275,0.293,0.568,2.4,2.44
+古城茂幸,巨人,0.209,65,149,129,27,0,8,2,12,0,28,6,5,0.256,0.273,0.529,1.96,2.07
--- /dev/null
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Silk nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlComponent>
+#include <QtQuick/QQuickItem>
+#include <QtQuick/QQuickView>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QUrl url = QUrl(QStringLiteral("qrc:/npb_similar_player.qml"));
+
+ QQmlEngine engine;
+ QObject::connect(&engine, SIGNAL(quit()), &app, SLOT(quit()));
+ QQmlComponent *component = new QQmlComponent(&engine);
+ component->loadUrl(url);
+ QObject *object = component->create();
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
+ QQuickView *view = 0;
+ if (!window) {
+ QQuickItem *item = qobject_cast<QQuickItem *>(object);
+ if (item) {
+ view = new QQuickView(&engine, NULL);
+ window = view;
+ view->setResizeMode(QQuickView::SizeRootObjectToView);
+ view->setContent(url, component, item);
+ }
+ }
+
+ if (window) {
+ window->show();
+ }
+
+ return app.exec();
+}
--- /dev/null
+{
+ "method": "AROW",
+ "converter": {
+ "num_filter_types": {},
+ "num_filter_rules": [],
+ "string_filter_types": {},
+ "string_filter_rules": [],
+ "num_types": {},
+ "num_rules": [
+ { "key": "*", "type": "num"}
+ ],
+ "string_types": {
+ },
+ "string_rules": [
+ { "key": "*", "type": "str", "sample_weight": "bin", "global_weight": "bin" }
+ ]
+ },
+ "parameter": {
+ "regularization_weight" : 1.0
+ }
+}
--- /dev/null
+TEMPLATE = app
+TARGET = jubatus-npb-similar-player-quick
+QT = quick jubatus
+
+SOURCES = main.cpp
+
+RESOURCES += \
+ npb_similar_player.qrc
+
+OTHER_FILES += npb_similar_player.qml npb_similar_player.json
--- /dev/null
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Silk nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import QtQuick 2.0
+import QtJubatus 0.1 as Jubatus
+
+Rectangle {
+ id: root
+ width: 600
+ height: 400
+
+ Jubatus.Recommender {
+ id: recommender
+ name: 'npb-similar-player'
+ timeout: 10
+ property bool hasError: false
+ onError: {
+ console.debug(message)
+ hasError = true
+ }
+ }
+
+ ListView {
+ id: playerView
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: parent.width / 2
+ model: ListModel {
+ id: playerModel
+ }
+
+ delegate: Text {
+ text: model.id
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ similarPlayerModel.clear()
+ if (!recommender.hasError) {
+ var results = recommender.similarRowFromId(model.id, 10)
+ results.shift()
+ for (var i in results) {
+ similarPlayerModel.append(results[i])
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ListView {
+ id: similar_players
+ anchors.left: playerView.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ model: ListModel {
+ id: similarPlayerModel
+ }
+ delegate: Text {
+ text: '%1(%2)'.arg(model.id).arg(model.score)
+ }
+ }
+
+ Component.onCompleted: {
+ var request = new XMLHttpRequest
+ request.onreadystatechange = function() {
+ switch (request.readyState) {
+ case XMLHttpRequest.DONE:
+ var learn = recommender.getAllRows().length === 0
+ var lines = request.responseText.split('\n')
+ var fields = ["打率", "試合数", "打席", "打数", "安打", "本塁打", "打点", "盗塁", "四球", "死球", "三振", "犠打", "併殺打", "長打率", "出塁率", "OPS", "RC27", "XR27"]
+ for (var i in lines) {
+ if (lines[i] === '') continue
+ var columns = lines[i].split(',')
+ var id = columns.shift()
+ playerModel.append({'id': id})
+ if (learn && !recommender.hasError) {
+ var data = new Object
+ data["チーム"] = columns.shift()
+ for (var j = 0; j < fields.length; j++) {
+ data[fields[j]] = parseFloat(columns[j])
+ }
+ recommender.updateRow(id, data)
+ }
+ }
+
+ break
+ }
+ }
+
+ request.open("GET", "qrc:/baseball.csv");
+ request.send();
+ }
+}
--- /dev/null
+<RCC>
+ <qresource prefix="/">
+ <file>baseball.csv</file>
+ <file>npb_similar_player.qml</file>
+ </qresource>
+</RCC>
--- /dev/null
+TEMPLATE = subdirs
+SUBDIRS += npb_similar_player
+
CONFIG += exceptions
-SOURCES += main.cpp
+SOURCES += main.cpp \
+ qmljubatusclassifier.cpp \
+ qmljubatusrecommender.cpp
load(qml_plugin)
OTHER_FILES = plugins.qmltypes qmldir
+
+HEADERS += \
+ qmljubatusclassifier.h \
+ qmljubatusrecommender.h
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <QtCore/QDebug>
#include <QtQml/QQmlExtensionPlugin>
#include <QtQml/qqml.h>
-#include <QtJubatus/QJubatusClassifier>
-
-#include <string>
-#include <vector>
-
-#include <jubatus/client.hpp>
-
-class QmlJubatusClassifier : public QJubatusClassifier
-{
- Q_OBJECT
-public:
- QmlJubatusClassifier(QObject *parent = 0) : QJubatusClassifier(parent) {}
-
- using QJubatusClassifier::train;
- Q_INVOKABLE void train(const QVariantList &data);
- Q_INVOKABLE void train(const QString &label, const QVariantMap &data);
- using QJubatusClassifier::classify;
- Q_INVOKABLE QVariantList classify(const QVariantList &data);
- Q_INVOKABLE QVariantList classify(const QVariantMap &data);
-};
-
-void QmlJubatusClassifier::train(const QVariantList &data)
-{
- std::vector<jubatus::classifier::labeled_datum> train_data;
- foreach (const QVariant &v, data) {
- switch (v.type()) {
- case QVariant::List: {
- QVariantList list = v.toList();
- if (!list.isEmpty()) {
- QString name = list.takeFirst().toString();
- foreach (const QVariant &v2, list) {
- train_data.push_back(jubatus::classifier::labeled_datum(name.toStdString(), convert(v2.toMap())));
- }
- }
- break; }
- default:
- qDebug() << Q_FUNC_INFO << __LINE__ << v.type();
- break;
- }
- }
- train(train_data);
-}
-
-void QmlJubatusClassifier::train(const QString &label, const QVariantMap &data)
-{
- std::vector<jubatus::classifier::labeled_datum> train_data;
- train_data.push_back(jubatus::classifier::labeled_datum(label.toStdString(), convert(data)));
- train(train_data);
-}
-
-QVariantList QmlJubatusClassifier::classify(const QVariantList &data)
-{
- QVariantList ret;
-
- std::vector<jubatus::client::common::datum> test_data;
- foreach (const QVariant &v, data) {
- test_data.push_back(convert(v.toMap()));
- }
-
- std::vector<std::vector<jubatus::classifier::estimate_result> > results = classify(test_data);
-
- for (size_t i = 0; i < results.size(); ++i) {
- QVariantList list;
- for (size_t j = 0; j < results[i].size(); ++j) {
- const jubatus::classifier::estimate_result& jr = results[i][j];
- QVariantMap qr;
- qr.insert(QStringLiteral("label"), QString::fromStdString(jr.label));
- qr.insert(QStringLiteral("score"), jr.score);
- list.append(qr);
- }
- ret.append(QVariant(list));
- }
- return ret;
-}
-
-QVariantList QmlJubatusClassifier::classify(const QVariantMap &data)
-{
- QVariantList ret;
-
- std::vector<jubatus::client::common::datum> test_data;
- test_data.push_back(convert(data));
-
- std::vector<std::vector<jubatus::classifier::estimate_result> > results = classify(test_data);
-
- for (size_t i = 0; i < results[0].size(); ++i) {
- const jubatus::classifier::estimate_result& jr = results[0][i];
- QVariantMap qr;
- qr.insert(QStringLiteral("label"), QString::fromStdString(jr.label));
- qr.insert(QStringLiteral("score"), jr.score);
- ret.append(qr);
- }
- return ret;
-}
+#include "qmljubatusclassifier.h"
+#include "qmljubatusrecommender.h"
class QmlJubatusPlugin : public QQmlExtensionPlugin
{
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtJubatus"));
- // @uri QtFluentd
+ // @uri QtJubatus
qmlRegisterType<QmlJubatusClassifier>(uri, 0, 1, "Classifier");
+ qmlRegisterType<QmlJubatusRecommender>(uri, 0, 1, "Recommender");
}
};
--- /dev/null
+#include "qmljubatusclassifier.h"
+
+QmlJubatusClassifier::QmlJubatusClassifier(QObject *parent) :
+ QJubatusClassifier(parent)
+{
+}
+
+void QmlJubatusClassifier::train(const QString &label, const QVariantMap &data)
+{
+ LabeledDatum datum;
+ datum.label = label;
+ datum.data = data;
+ QJubatusClassifier::train(QList<QJubatusClassifier::LabeledDatum>() << datum);
+}
+
+QVariantList QmlJubatusClassifier::classify(const QVariantMap &data)
+{
+ QVariantList ret;
+ QList<QList<QJubatusClassifier::EstimateResult> > result = QJubatusClassifier::classify(QList<QVariantMap>() << data);
+ if (!result.isEmpty())
+ ret = convert(result.first());
+ return ret;
+}
+
+QVariantMap QmlJubatusClassifier::convert(const QJubatusClassifier::EstimateResult &data) const
+{
+ QVariantMap ret;
+ ret.insert(QStringLiteral("label"), data.label);
+ ret.insert(QStringLiteral("score"), data.score);
+ return ret;
+}
+
+QVariantList QmlJubatusClassifier::convert(const QList<QJubatusClassifier::EstimateResult> &data) const
+{
+ QVariantList ret;
+ foreach (const QJubatusClassifier::EstimateResult &datum, data) {
+ ret.append(convert(datum));
+ }
+ return ret;
+}
--- /dev/null
+#ifndef QMLJUBATUSCLASSIFIER_H
+#define QMLJUBATUSCLASSIFIER_H
+
+#include <QtJubatus/QJubatusClassifier>
+
+class QmlJubatusClassifier : public QJubatusClassifier
+{
+ Q_OBJECT
+public:
+ QmlJubatusClassifier(QObject *parent = 0);
+
+ Q_INVOKABLE void train(const QString &label, const QVariantMap &data);
+ Q_INVOKABLE QVariantList classify(const QVariantMap &data);
+
+protected:
+ using QJubatusClassifier::convert;
+ QVariantMap convert(const QJubatusClassifier::EstimateResult &data) const;
+ QVariantList convert(const QList<QJubatusClassifier::EstimateResult> &data) const;
+};
+
+#endif // QMLJUBATUSCLASSIFIER_H
--- /dev/null
+#include "qmljubatusrecommender.h"
+
+QmlJubatusRecommender::QmlJubatusRecommender(QObject *parent) :
+ QJubatusRecommender(parent)
+{
+}
+
+QVariantList QmlJubatusRecommender::similarRowFromId(const QString &id, uint size)
+{
+ return convert(QJubatusRecommender::similarRowFromId(id, size));
+}
+
+QVariantList QmlJubatusRecommender::similarRowFromDatum(const QVariantMap &data, uint size)
+{
+ return convert(QJubatusRecommender::similarRowFromDatum(data, size));
+}
+
+QVariantMap QmlJubatusRecommender::convert(const QJubatusRecommender::IdWithScore &data) const
+{
+ QVariantMap ret;
+ ret.insert(QStringLiteral("id"), data.id);
+ ret.insert(QStringLiteral("score"), data.score);
+ return ret;
+}
+
+QVariantList QmlJubatusRecommender::convert(const QList<QJubatusRecommender::IdWithScore> &data) const
+{
+ QVariantList ret;
+ foreach (const IdWithScore &idWithScore, data) {
+ ret.append(convert(idWithScore));
+ }
+ return ret;
+}
--- /dev/null
+#ifndef QMLJUBATUSRECOMMENDER_H
+#define QMLJUBATUSRECOMMENDER_H
+
+#include <QtJubatus/QJubatusRecommender>
+
+class QmlJubatusRecommender : public QJubatusRecommender
+{
+ Q_OBJECT
+public:
+ explicit QmlJubatusRecommender(QObject *parent = 0);
+
+ Q_INVOKABLE QVariantList similarRowFromId(const QString &id, uint size);
+ Q_INVOKABLE QVariantList similarRowFromDatum(const QVariantMap &data, uint size);
+
+protected:
+ QVariantMap convert(const IdWithScore &data) const;
+ QVariantList convert(const QList<IdWithScore> &data) const;
+};
+
+#endif // QMLJUBATUSRECOMMENDER_H
#include <jubatus/client/anomaly_client.hpp>
-class QJubatusAnomaly::Private
-{
-public:
- Private();
- ~Private();
-
- jubatus::anomaly::client::anomaly *client;
-};
-
-QJubatusAnomaly::Private::Private()
- : client(0)
-{
-}
-
-QJubatusAnomaly::Private::~Private()
-{
- delete client;
-}
-
QJubatusAnomaly::QJubatusAnomaly(QObject *parent)
: QJubatusClient(parent)
- , d(new Private)
{
- connect(this, &QJubatusAnomaly::destroyed, [this](){ delete d; });
- auto deleteClient = [this]() { delete d->client; d->client = 0; };
- connect(this, &QJubatusAnomaly::hostChanged, deleteClient);
- connect(this, &QJubatusAnomaly::portChanged, deleteClient);
- connect(this, &QJubatusAnomaly::nameChanged, deleteClient);
- connect(this, &QJubatusAnomaly::timeoutChanged, deleteClient);
}
bool QJubatusAnomaly::clearRow(const QString &id)
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
- return d->client->clear_row(id.toStdString());
+ bool ret = false;
+ EXEC_JUBATUS_COMMAND( ret = client()->clear_row(convert(id)); )
+ return ret;
}
QJubatusAnomaly::IdAndScore QJubatusAnomaly::add(const QVariantMap &data)
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
- jubatus::anomaly::id_with_score id_with_score = d->client->add(convert(data));
- IdAndScore ret;
- ret.id = QString::fromStdString(id_with_score.id);
- ret.score = id_with_score.score;
+ QJubatusAnomaly::IdAndScore ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->add(convert(data))); )
return ret;
}
float QJubatusAnomaly::update(const QString &id, const QVariantMap &data)
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
- return d->client->update(id.toStdString(), convert(data));
+ float ret = 0.0;
+ EXEC_JUBATUS_COMMAND( ret = client()->update(convert(id), convert(data)); )
+ return ret;
}
float QJubatusAnomaly::overwrite(const QString &id, const QVariantMap &data)
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
- return d->client->overwrite(id.toStdString(), convert(data));
+ float ret = 0.0;
+ EXEC_JUBATUS_COMMAND( client()->overwrite(convert(id), convert(data)); )
+ return ret;
}
float QJubatusAnomaly::calcScore(const QVariantMap &data)
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
- return d->client->calc_score(convert(data));
+ float ret = 0.0;
+ EXEC_JUBATUS_COMMAND( ret = client()->calc_score(convert(data)); )
+ return ret;
}
QStringList QJubatusAnomaly::getAllRows()
{
- if (!d->client) {
- d->client = new jubatus::anomaly::client::anomaly(host().toStdString(), port(), name().toStdString(), timeout());
- }
QStringList ret;
- foreach (std::string id, d->client->get_all_rows())
- ret.append(QString::fromStdString(id));
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->get_all_rows()); )
+ return ret;
+}
+
+jubatus::anomaly::id_with_score QJubatusAnomaly::convert(const QJubatusAnomaly::IdAndScore &data) const
+{
+ jubatus::anomaly::id_with_score ret;
+ ret.id = convert(data.id);
+ ret.score = data.score;
+ return ret;
+}
+
+QJubatusAnomaly::IdAndScore QJubatusAnomaly::convert(const jubatus::anomaly::id_with_score &data) const
+{
+ IdAndScore ret;
+ ret.id = convert(data.id);
+ ret.score = data.score;
return ret;
}
+jubatus::anomaly::client::anomaly *QJubatusAnomaly::client()
+{
+ return QJubatusClient::client<jubatus::anomaly::client::anomaly>();
+}
namespace jubatus {
namespace anomaly {
struct id_with_score;
+ namespace client {
+ class anomaly;
+ }
}
}
explicit QJubatusAnomaly(QObject *parent = 0);
struct IdAndScore {
+ IdAndScore() : score(0.0) {}
QString id;
float score;
};
float calcScore(const QVariantMap &data);
QStringList getAllRows();
+protected:
+ using QJubatusClient::convert;
+ jubatus::anomaly::id_with_score convert(const IdAndScore &data) const;
+ IdAndScore convert(const jubatus::anomaly::id_with_score &data) const;
+
private:
- class Private;
- Private *d;
+ jubatus::anomaly::client::anomaly *client();
};
#endif // QJUBATUSANOMALY_H
#include <jubatus/client/classifier_client.hpp>
-class QJubatusClassifier::Private
+QJubatusClassifier::QJubatusClassifier(QObject *parent)
+ : QJubatusClient(parent)
{
-public:
- Private();
- ~Private();
-
- jubatus::classifier::client::classifier *client;
-};
+}
-QJubatusClassifier::Private::Private()
- : client(0)
+void QJubatusClassifier::train(const QList<QJubatusClassifier::LabeledDatum> &data)
{
+ EXEC_JUBATUS_COMMAND( client()->train(convert(data)); )
}
-QJubatusClassifier::Private::~Private()
+QList<QList<QJubatusClassifier::EstimateResult> > QJubatusClassifier::classify(const QList<QVariantMap> &data)
{
- delete client;
+ QList<QList<QJubatusClassifier::EstimateResult> > ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->classify(convert(data))); )
+ return ret;
}
-QJubatusClassifier::QJubatusClassifier(QObject *parent)
- : QJubatusClient(parent)
- , d(new Private)
+jubatus::classifier::labeled_datum QJubatusClassifier::convert(const QJubatusClassifier::LabeledDatum &data) const
{
- connect(this, &QJubatusClassifier::destroyed, [this](){ delete d; });
- auto deleteClient = [this]() { delete d->client; d->client = 0; };
- connect(this, &QJubatusClassifier::hostChanged, deleteClient);
- connect(this, &QJubatusClassifier::portChanged, deleteClient);
- connect(this, &QJubatusClassifier::nameChanged, deleteClient);
- connect(this, &QJubatusClassifier::timeoutChanged, deleteClient);
+ jubatus::classifier::labeled_datum ret;
+ ret.label = convert(data.label);
+ ret.data = convert(data.data);
+ return ret;
}
-void QJubatusClassifier::train(const QList<QJubatusClassifier::TrainData> &data)
+std::vector<jubatus::classifier::labeled_datum> QJubatusClassifier::convert(const QList<QJubatusClassifier::LabeledDatum> &data) const
{
- std::vector<jubatus::classifier::labeled_datum> train_data;
- foreach (const TrainData &v, data) {
- train_data.push_back(jubatus::classifier::labeled_datum(v.first.toStdString(), convert(v.second)));
+ std::vector<jubatus::classifier::labeled_datum> ret;
+ foreach (const QJubatusClassifier::LabeledDatum &datum, data) {
+ ret.push_back(convert(datum));
}
- train(train_data);
+ return ret;
}
-void QJubatusClassifier::train(const std::vector<jubatus::classifier::labeled_datum> &data)
+QJubatusClassifier::EstimateResult QJubatusClassifier::convert(const jubatus::classifier::estimate_result &data) const
{
- if (!d->client) {
- d->client = new jubatus::classifier::client::classifier(host().toStdString(), port(), name().toStdString(), timeout());
- }
- d->client->train(data);
+ QJubatusClassifier::EstimateResult ret;
+ ret.label = convert(data.label);
+ ret.score = data.score;
+ return ret;
}
-QList<QList<QJubatusClassifier::EstimateResult>> QJubatusClassifier::classify(const QList<QVariantMap> &data)
+QList<QJubatusClassifier::EstimateResult> QJubatusClassifier::convert(const std::vector<jubatus::classifier::estimate_result> &data) const
{
- QList<QList<EstimateResult>> ret;
-
- std::vector<jubatus::client::common::datum> test_data;
- foreach (const QVariant &v, data) {
- test_data.push_back(convert(v.toMap()));
- }
-
- std::vector<std::vector<jubatus::classifier::estimate_result> > results = classify(test_data);
-
- for (size_t i = 0; i < results.size(); ++i) {
- QList<EstimateResult> list;
- for (size_t j = 0; j < results[i].size(); ++j) {
- const jubatus::classifier::estimate_result& jr = results[i][j];
- EstimateResult qr;
- qr.label = QString::fromStdString(jr.label);
- qr.score = jr.score;
- list.append(qr);
- }
- ret.append(list);
+ QList<QJubatusClassifier::EstimateResult> ret;
+ for (auto it = data.begin(); it != data.end(); ++it) {
+ ret.append(convert(*it));
}
return ret;
}
-std::vector<std::vector<jubatus::classifier::estimate_result>> QJubatusClassifier::classify(const std::vector<jubatus::client::common::datum> &data)
+QList<QList<QJubatusClassifier::EstimateResult>> QJubatusClassifier::convert(const std::vector<std::vector<jubatus::classifier::estimate_result>> &data) const
{
- if (!d->client) {
- d->client = new jubatus::classifier::client::classifier(host().toStdString(), port(), name().toStdString(), timeout());
+ QList<QList<QJubatusClassifier::EstimateResult>> ret;
+ for (auto it = data.begin(); it != data.end(); ++it) {
+ ret.append(convert(*it));
}
- return d->client->classify(data);
+ return ret;
}
-
+jubatus::classifier::client::classifier *QJubatusClassifier::client()
+{
+ return QJubatusClient::client<jubatus::classifier::client::classifier>();
+}
namespace classifier {
struct estimate_result;
struct labeled_datum;
+ namespace client {
+ class classifier;
+ }
}
}
public:
explicit QJubatusClassifier(QObject *parent = 0);
+ struct LabeledDatum {
+ QString label;
+ QVariantMap data;
+ };
+
struct EstimateResult {
QString label;
double score;
typedef QPair<QString, QVariantMap> TrainData;
- void train(const QList<QJubatusClassifier::TrainData> &data);
- QList<QList<QJubatusClassifier::EstimateResult>> classify(const QList<QVariantMap> &data);
+ Q_INVOKABLE void train(const QList<QJubatusClassifier::LabeledDatum> &data);
+ Q_INVOKABLE QList<QList<QJubatusClassifier::EstimateResult>> classify(const QList<QVariantMap> &data);
protected:
- void train(const std::vector<jubatus::classifier::labeled_datum> &data);
- std::vector<std::vector<jubatus::classifier::estimate_result>> classify(const std::vector<jubatus::client::common::datum> &data);
+ using QJubatusClient::convert;
+ jubatus::classifier::labeled_datum convert(const QJubatusClassifier::LabeledDatum &data) const;
+ std::vector<jubatus::classifier::labeled_datum> convert(const QList<QJubatusClassifier::LabeledDatum> &data) const;
+ QJubatusClassifier::EstimateResult convert(const jubatus::classifier::estimate_result &data) const;
+ QList<QJubatusClassifier::EstimateResult> convert(const std::vector<jubatus::classifier::estimate_result> &data) const;
+ QList<QList<QJubatusClassifier::EstimateResult>> convert(const std::vector<std::vector<jubatus::classifier::estimate_result>> &data) const;
private:
- class Private;
- Private *d;
+ jubatus::classifier::client::classifier *client();
};
#endif // QJUBATUSCLASSIFIER_H
#include <QtCore/QDebug>
+#include <jubatus/client/common/client.hpp>
#include <jubatus/client/common/datum.hpp>
class QJubatusClient::Private
QJubatusClient::QJubatusClient(QObject *parent)
: QObject(parent)
, d(new Private())
+ , m_client(0)
{
connect(this, &QJubatusClient::destroyed, [this](){ delete d; });
+ auto deleteClient = [this]() { delete m_client; m_client = 0; };
+ connect(this, &QJubatusClient::hostChanged, deleteClient);
+ connect(this, &QJubatusClient::portChanged, deleteClient);
+ connect(this, &QJubatusClient::nameChanged, deleteClient);
+ connect(this, &QJubatusClient::timeoutChanged, deleteClient);
}
const QString &QJubatusClient::host() const
emit timeoutChanged(timeout);
}
+std::string QJubatusClient::convert(const QString &data) const
+{
+ return data.toStdString();
+}
+
+QString QJubatusClient::convert(const std::string &data) const
+{
+ return QString::fromStdString(data);
+}
+
+std::vector<std::string> QJubatusClient::convert(const QStringList &data) const
+{
+ std::vector<std::string> ret;
+ foreach (const QString &str, data) {
+ ret.push_back(convert(str));
+ }
+ return ret;
+}
+
+QStringList QJubatusClient::convert(const std::vector<std::string> &data) const
+{
+ QStringList ret;
+ for (auto it = data.begin(); it != data.end(); ++it) {
+ ret.append(convert(*it));
+ }
+ return ret;
+}
+
jubatus::client::common::datum QJubatusClient::convert(const QVariantMap &data) const
{
jubatus::client::common::datum ret;
foreach (const QString &key, data.keys()) {
QVariant value = data.value(key);
- switch (value.type()) {
+ switch (static_cast<int>(value.type())) {
case QVariant::String:
- ret.string_values.push_back(make_pair(key.toStdString(), value.toString().toStdString()));
+ ret.add_string(key.toStdString(), value.toString().toStdString());
break;
case QVariant::Int:
- ret.num_values.push_back(make_pair(key.toStdString(), value.toInt()));
+ ret.add_number(key.toStdString(), value.toInt());
break;
case QMetaType::Float:
- ret.num_values.push_back(make_pair(key.toStdString(), value.toFloat()));
+ ret.add_number(key.toStdString(), value.toFloat());
break;
case QVariant::Double:
- ret.num_values.push_back(make_pair(key.toStdString(), value.toDouble()));
+ ret.add_number(key.toStdString(), value.toDouble());
break;
default:
qDebug() << Q_FUNC_INFO << __LINE__ << value.type() << value << "not supported.";
return ret;
}
+
+QVariantMap QJubatusClient::convert(const jubatus::client::common::datum &data) const
+{
+ QVariantMap ret;
+ for (auto it = data.num_values.begin(); it != data.num_values.end(); ++it) {
+ ret.insert(convert(it->first), it->second);
+ }
+ for (auto it = data.string_values.begin(); it != data.string_values.end(); ++it) {
+ ret.insert(convert(it->first), convert(it->second));
+ }
+ return ret;
+}
+
+std::vector<jubatus::client::common::datum> QJubatusClient::convert(const QList<QVariantMap> &data) const
+{
+ std::vector<jubatus::client::common::datum> ret;
+ foreach (const QVariantMap &datum, data) {
+ ret.push_back(convert(datum));
+ }
+ return ret;
+}
+QList<QVariantMap> QJubatusClient::convert(const std::vector<jubatus::client::common::datum> &data) const
+{
+ QList<QVariantMap> ret;
+ for (auto it = data.begin(); it != data.end(); ++it) {
+ ret.append(convert(*it));
+ }
+ return ret;
+}
namespace client {
namespace common {
struct datum;
+ class client;
}
}
}
void nameChanged(const QString &name);
void timeoutChanged(double timeout);
+ void error(const QString &message);
+
protected:
+ template <class T>
+ T *client() {
+ if (!m_client) {
+ m_client = new T(convert(host()), port(), convert(name()), timeout());
+ }
+ return static_cast<T *>(m_client);
+ }
+
+ std::string convert(const QString &data) const;
+ QString convert(const std::string &data) const;
+ std::vector<std::string> convert(const QStringList &data) const;
+ QStringList convert(const std::vector<std::string> &data) const;
jubatus::client::common::datum convert(const QVariantMap &data) const;
+ QVariantMap convert(const jubatus::client::common::datum &data) const;
+ std::vector<jubatus::client::common::datum> convert(const QList<QVariantMap> &data) const;
+ QList<QVariantMap> convert(const std::vector<jubatus::client::common::datum> &data) const;
private:
class Private;
Private *d;
+
+ jubatus::client::common::client *m_client;
};
+#define EXEC_JUBATUS_COMMAND(COMMAND) \
+ try { \
+ for (int i = 0; i < 3; i++) { \
+ try { \
+ COMMAND; \
+ break; \
+ } catch (msgpack::rpc::connection_closed_error &e) { \
+ client()->get_client().close(); \
+ } catch (msgpack::rpc::system_error &e) { \
+ client()->get_client().close(); \
+ } catch (msgpack::rpc::timeout_error &e) { \
+ client()->get_client().close(); \
+ } \
+ ::sleep(1); \
+ } \
+ } catch(msgpack::rpc::rpc_error &e) { \
+ emit error(QString::fromUtf8(e.what())); \
+ }
+
#endif // QJUBATUSCLIENT_H
CONFIG += link_pkgconfig
PKGCONFIG += jubatus-client
+CONFIG += exception
+
DEFINES += JUBATUS_LIBRARY
HEADERS += \
jubatus_global.h
include(./client/client.pri)
include(./anomaly/anomaly.pri)
include(./classifier/classifier.pri)
+include(./recommender/recommender.pri)
--- /dev/null
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Silk nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qjubatusrecommender.h"
+
+#include <QtCore/QDebug>
+
+#include <vector>
+
+#include <jubatus/client/recommender_client.hpp>
+
+QJubatusRecommender::QJubatusRecommender(QObject *parent)
+ : QJubatusClient(parent)
+{
+}
+
+bool QJubatusRecommender::clearRow(const QString &id)
+{
+ bool ret = false;
+ EXEC_JUBATUS_COMMAND( ret = client()->clear_row(convert(id)); )
+ return ret;
+}
+
+bool QJubatusRecommender::updateRow(const QString &id, const QVariantMap &data)
+{
+ bool ret = false;
+ EXEC_JUBATUS_COMMAND( ret = client()->update_row(convert(id), convert(data)); )
+ return ret;
+}
+
+QVariantMap QJubatusRecommender::completeRowFromId(const QString &id)
+{
+ QVariantMap ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->complete_row_from_id(convert(id))); )
+ return ret;
+}
+
+QVariantMap QJubatusRecommender::completeRowFromDatum(const QVariantMap &data)
+{
+ QVariantMap ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->complete_row_from_datum(convert(data))); )
+ return ret;
+}
+
+QList<QJubatusRecommender::IdWithScore> QJubatusRecommender::similarRowFromId(const QString &id, uint size)
+{
+ QList<QJubatusRecommender::IdWithScore> ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->similar_row_from_id(convert(id), size)); )
+ return ret;
+}
+
+QList<QJubatusRecommender::IdWithScore> QJubatusRecommender::similarRowFromDatum(const QVariantMap &data, uint size)
+{
+ QList<QJubatusRecommender::IdWithScore> ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->similar_row_from_datum(convert(data), size)); )
+ return ret;
+}
+
+QVariantMap QJubatusRecommender::decodeRow(const QString &id)
+{
+ QVariantMap ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->decode_row(id.toStdString())); )
+ return ret;
+}
+
+QStringList QJubatusRecommender::getAllRows()
+{
+ QStringList ret;
+ EXEC_JUBATUS_COMMAND( ret = convert(client()->get_all_rows()); )
+ return ret;
+}
+
+float QJubatusRecommender::calcSimilarity(const QVariantMap &data1, const QVariantMap &data2)
+{
+ float ret = 0.0;
+ EXEC_JUBATUS_COMMAND( ret = client()->calc_similarity(convert(data1), convert(data2)); )
+ return ret;
+}
+
+float QJubatusRecommender::calcL2Norm(const QVariantMap &data)
+{
+ float ret = 0.0;
+ EXEC_JUBATUS_COMMAND( ret = client()->calc_l2norm(convert(data)); )
+ return ret;
+}
+
+QJubatusRecommender::IdWithScore QJubatusRecommender::convert(const jubatus::recommender::id_with_score &data) const
+{
+ QJubatusRecommender::IdWithScore ret;
+ ret.id = convert(data.id);
+ ret.score = data.score;
+ return ret;
+}
+
+QList<QJubatusRecommender::IdWithScore> QJubatusRecommender::convert(const std::vector<jubatus::recommender::id_with_score> &data) const
+{
+ QList<QJubatusRecommender::IdWithScore> ret;
+ foreach (const jubatus::recommender::id_with_score id_with_score, data) {
+ ret.append(convert(id_with_score));
+ }
+ return ret;
+}
+
+jubatus::recommender::client::recommender *QJubatusRecommender::client() {
+ return QJubatusClient::client<jubatus::recommender::client::recommender>();
+}
--- /dev/null
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Silk nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QJUBATUSRECOMMENDER_H
+#define QJUBATUSRECOMMENDER_H
+
+#include "jubatus_global.h"
+#include "qjubatusclient.h"
+
+#include <QtCore/QVariant>
+
+namespace jubatus {
+ namespace recommender {
+ struct id_with_score;
+ namespace client {
+ class recommender;
+ }
+ }
+}
+
+class JUBATUS_EXPORT QJubatusRecommender : public QJubatusClient
+{
+ Q_OBJECT
+public:
+ explicit QJubatusRecommender(QObject *parent = 0);
+
+ struct IdWithScore {
+ QString id;
+ float score;
+ };
+
+ Q_INVOKABLE bool clearRow(const QString &id);
+ Q_INVOKABLE bool updateRow(const QString &id, const QVariantMap &data);
+ Q_INVOKABLE QVariantMap completeRowFromId(const QString &id);
+ Q_INVOKABLE QVariantMap completeRowFromDatum(const QVariantMap &data);
+ Q_INVOKABLE QList<IdWithScore> similarRowFromId(const QString &id, uint size);
+ Q_INVOKABLE QList<IdWithScore> similarRowFromDatum(const QVariantMap &data, uint size);
+ Q_INVOKABLE QVariantMap decodeRow(const QString &id);
+ Q_INVOKABLE QStringList getAllRows();
+ Q_INVOKABLE float calcSimilarity(const QVariantMap &data1, const QVariantMap &data2);
+ Q_INVOKABLE float calcL2Norm(const QVariantMap &data);
+
+protected:
+ using QJubatusClient::convert;
+ IdWithScore convert(const jubatus::recommender::id_with_score &data) const;
+ QList<IdWithScore> convert(const std::vector<jubatus::recommender::id_with_score> &data) const;
+
+private:
+ jubatus::recommender::client::recommender *client();
+};
+
+#endif // QJUBATUSRECOMMENDER_H
--- /dev/null
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+PUBLIC_HEADERS += $$PWD/qjubatusrecommender.h
+HEADERS += $$PUBLIC_HEADERS
+SOURCES += $$PWD/qjubatusrecommender.cpp