2022年9月5日月曜日

PytorchのC++のライブラリlibtorchを使う2022

最近AI囲碁や将棋、たんぱく質の構造推定などあらゆるAIでResNetが使われています。

ResNetって画像分類以外のこともできるようです。

ResNetくらいなら簡単なものならおじさんの個人所有のGPUでもなんとか学習ができそう。

C++でやってみたい・・・・



c++でResNetができるフレームワークを探すと、Pytorchがでてきます。

Pytorchはもともとコア部分がlibtorchにまとまっていてc++から使えるようになっているし、Android版はNewralNetworkAPIなどに対応しており、GPUを使って高速に演算ができるようです。

 最近、GoogleのTensorFlow、マイクロソフトのonnxruntime、FacebookのPytorchなど、いろいろな機械学習フレームワークが続々とONNX対応、c++対応やスマホ対応になってきています。

Pytorchのようなスマホ対応のフレームワークを使えば、フルセットのPytorchがスマホでも動き、GPU付きのPCで学習させてスマホでその結果を利用することもできるようです。

いろいろなOSで動いて、学習データの再利用ができてほんとうに便利ねー。


そこで、本日は最新のPytorch 1.12.1のc++ライブラリlibtorchをビルドして動かしてみたいと思います。


ビルド方法はドキュメントに書かれている通りでとっても簡単

以前の自分のブログに書いてある通りでビルドできます。

http://yomeiotani.blogspot.com/2019/04/windowslibtorch.html


--------------------

cd <pytorch_root>\tools

mkdir build

cd build

python ..\build_libtorch.py

--------------------

上記のように打つだけ。
Windowsでのビルドは、公式にはVisualStudio 2017にしか対応していないようですが、コンパイラのバージョンをチェックしている部分を直せばVisualStudio 2022でもビルドできるようです。
外部依存ライブラリが前回より変わっています。
演算をより高速にするためにいろいろな機能を追加しているみたいですね。

PyTorchのexample/cppフォルダにはc++のサンプルがあります。
このなかに定番の文字認識「MNIST」のlibtorch版、mnist.cppがあります。


とりあえずビルドして動かしてみました。
----------------------------
Training on CPU.
Train Epoch: 1 [59584/60000] Loss: 0.2362
Test set: Average loss: 0.2119 | Accuracy: 0.935
Train Epoch: 2 [59584/60000] Loss: 0.1365
Test set: Average loss: 0.1301 | Accuracy: 0.959
Train Epoch: 3 [59584/60000] Loss: 0.1805
Test set: Average loss: 0.1069 | Accuracy: 0.965
Train Epoch: 4 [59584/60000] Loss: 0.1147
Test set: Average loss: 0.0899 | Accuracy: 0.970
Train Epoch: 5 [59584/60000] Loss: 0.1017
Test set: Average loss: 0.0834 | Accuracy: 0.974
Train Epoch: 6 [59584/60000] Loss: 0.0549
Test set: Average loss: 0.0725 | Accuracy: 0.976
Train Epoch: 7 [59584/60000] Loss: 0.0657
Test set: Average loss: 0.0697 | Accuracy: 0.979
Train Epoch: 8 [59584/60000] Loss: 0.0832
Test set: Average loss: 0.0639 | Accuracy: 0.980
Train Epoch: 9 [59584/60000] Loss: 0.0523
Test set: Average loss: 0.0609 | Accuracy: 0.982
Train Epoch: 10 [59584/60000] Loss: 0.0504
Test set: Average loss: 0.0559 | Accuracy: 0.983
----------------------------

なんかあってそう。
とりあえずlibtorchのカスタムビルドができたから次はResNetでいろいろ遊ぼうっと。
android版のビルドもしてみたいなぁ。

2022年2月22日火曜日

株価指数を計算する。

 おじさん、今週は株価指数を計算するライブラリを作成しています。


株価指数って、まずTOPIXが基本らしい。

株系のWebページって結構みんな読まれるためか、いろいろな人がいろいろなことを書いているのですが、結構適当な記事が多いです。


ある経済ライターさんのページには以下のように書かれています。

https://seikeidenron.jp/articles/584

------------------

景気を知るためにもう一つ覚えておきたいのが「TOPIX(東証株価指数)」。

こちらは、東証一部に上場しているすべての銘柄の時価総額(株価×発行済株式数)を足して、銘柄数で割ったものだ。

------------------


平均だから銘柄数で割ったら平均になりそうだけどね。

うそつきー。うそのこと書くなよ!

景気を知る前に株価指数のこと知れよ!!!!



おじさんがプログラムで計算した式は、


(今の浮遊株時価総額)÷(昔の浮遊株時価総額)×(100または1000)

(浮遊株時価総額)=(浮遊株数)×(終値)


だぞ!


おじさんも二週間、朝から晩までプログラム書いて株価指数の計算方法がわかったので、こういう嘘のことを書いているのがわかるようになりました。

おじさんの勉強では平均株価ってだいたい「浮動株基準時価総額加重平均型株価」って方法で計算するらしい。


https://ja.wikipedia.org/wiki/%E6%99%82%E4%BE%A1%E7%B7%8F%E9%A1%8D%E5%8A%A0%E9%87%8D%E5%B9%B3%E5%9D%87%E5%9E%8B%E6%A0%AA%E4%BE%A1%E6%8C%87%E6%95%B0


でもこの株価指数の計算ってなかなか大変。

浮遊株数とか基準時時価総額とかの具体的な計算例や一覧データはどこにもフリーのデータがありません。

東証から月3300円で入手しないといけないっぽいです。

10年分とると40万円いるじゃないか!

うそ書いてるやると金とるやつしかいない・・・・。

なんという厳しい世界。


TOPIXでさえ、株価指数の計算の仕方が正確に書かれていないので、おじさんきちんとTOPIXを求めてみました。

浮遊株数ってどうやって計算するんだろ?

おじさん頑張ってフリーのデータから基準時時価総額と浮遊株数を計算する方法を見つけました。



まず、東京証券取引所からTOPIXの銘柄別のウェイト情報を入手

https://www.jpx.co.jp/markets/indices/topix/index.html

構成銘柄別ウエイト一覧


つぎに、年末の浮遊株時価総額と基準時時価総額を入手。

https://www.jpx.co.jp/markets/indices/related/value/index.html

2021年12月末現在



上記の二個のファイルから、TOPIX時価総額にウェイトをかけて各銘柄の浮遊株時価総額を計算。

浮遊株時価総額をその日の終値で割って、浮遊株式数を逆計算で取得。

浮遊株式数から株価指数を計算。


さらに実際には、銘柄変更、上場廃止、一時取引停止、株式分割などいろいろなイベントが毎週あるので、これらのイベントに対応し計算しないといけないためかなりめんどくさい。


でもこの方法で業種別の株価指数を計算できるようになりました。

これでただで業種別株価指数を使ってAIで株価分析してやる。



ソースはこちら。

https://github.com/yomei-o/Protra_cpp





2022年2月16日水曜日

33業種データベースを作る。

 おじさん、以下のサイトで株価はマーケットや業種ごとに傾向がことなることを勉強しました。

https://qiita.com/blog_UKI/items/25dc1c2559c61890a449

なるほど、ウイリアム・シャープっていうノーベル賞を受賞したおちゃんが言っているのね。

https://ja.wikipedia.org/wiki/%E8%B3%87%E6%9C%AC%E8%B3%87%E7%94%A3%E4%BE%A1%E6%A0%BC%E3%83%A2%E3%83%87%E3%83%AB


何言ってるのかよくわからん。

けど、機械学習とかって論文や資料が全部英語なんだけど、金融経済分野って資料が全部日本語に翻訳されている・・・。

きっとこの分野、お金が有り余ってるに違いない。


株のリターンを計算するには、上場企業の「業種」やどのマーケットに上場しているのかのデータが必要らしいです。

Protraの上場企業データベースには、上場しているマーケット情報はあるのですが、業種のデータベースがありません。なので、本日は上場企業の業種のデータベースを作ろうと思ういます。


上場企業の業種の一覧ってどこにあるんだろ?

調べてみると、東京証券取引所にあるみたい。



https://www.jpx.co.jp/markets/statistics-equities/misc/01.html

ここにいろんな企業の株に関するデータがありました。

ここの東証上場銘柄一覧というエクセルの中に業種があるのね。


しかしこのエクセル、「食品    」のように業種の文字のあとにスペースが入ってる・・・。

たしかに見た感じわかんないひっかけだけど、微妙に間違ってるのね。

金融とか証券ってこういうの間違っちゃいけないと思うんだけど・・・。

きっと誰もこのエクセル使っていないのね。


エクセルを見ると、「17業種コード」と「33業種コード」があるらしい。

「17業種コード」は1から連番なのですが、「33業種コード」は7250とか意味不明な数字が・・・

図書館の本の分類の日本十進分類だって連番なのに、Kaggleのようにあちこちにいろんな罠があります。

https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E5%8D%81%E9%80%B2%E5%88%86%E9%A1%9E%E6%B3%95


こういう不連続なデータをきちんと機械学習できるように連番にしていきます。

データを正確に分類するのって結構大変なのね。


ということで、いろいろ罠があり時間がかかってしまいましたが、上場企業の業種のライブラリができた!


https://github.com/yomei-o/Protra_cpp/blob/main/src/Industory.h




2022年2月14日月曜日

ローソク足を表示する

 おじさん、今日はどうやってJavaScriptで株価のローソク足を描画するのか調べています。

日経平均株価のリアルタイム表示サイトとかで使われている赤と緑のグラフのやつね。

デフォルトのChart.jsだとローソク足表示はできないらしい。

だけど、なかなかあれと同じようなちょうどいいライブラリがないねぇ。


いろいろ試してみると、このライブラリが一番きれいにローソク足が表示できそう。

https://github.com/chartjs/chartjs-chart-financial/tree/master/docs

Chart.jsのプラグインになっているようです。



思う通りの日経平均株価のローソク足表示ができた。
おじさんシステムトレードのプログラム作るより、証券会社のWebページを作った方が儲かるんじゃないかと思えてきました。
自分で作って分かったのですが、証券会社のWebページって結構製作難易度高いように思ういます。
みんなどのように作っているのでしょうね?

ソースコードはこちら

2022年2月10日木曜日

残差プロットをする。

おじさん、先日作ったlightgbmの住宅価格の予想プログラムを任意のCSVファイルを読めるように少し改造してました。

あとモデルデータの保存と読み込みもできるようにしました。

でもどうしても学習の結果が正しいかどうかなかなかわからない。

プログラムにバグがないことを確認することはほんと至難の業。


いろいろ考えた結果、よく知られているデータの学習結果を残差プロット表示すればわかるんじゃないかと思いつきました。

PandasやR言語でグラフ表示すると結局別のプログラムしないといけないし。

よく考えて、今週は機械学習のデータのグラフ表示のJavascriptライブラリを作ってみました。

いつものようにC++からJavaScriptを生成。

全部C++で行います。


JavaScriptで計算すると遅いのかと思ったのですが、ChromeのJavaScriptってめちゃくちゃ高速なのね。

あまりの速さにびっくり。

相関係数とか行列操作のJavaScriptrの統計ライブラリも作ったので、ブラウザでさくさくCSVファイルを読み込んで相関行列とか残差プロットとかが表示できるようになりました。



先日作った、おじさんのlightgbmのプログラムの、ボストンの住宅価格の残差プロットを作ってみました。
おー、ネットに落っこちている図と同じになった。
右下の部分にある謎の直線上の点が同じ。

ということは、先日作ったおじさんのlightgbmのプログラムや今週作ったJavaScriptの統計ライブラリは正しいっぽい。
モデルデータの保存と読み込みやCSVファイルの処理もあってそう。
しかもおじさんの方が右下部分の点の数が少ないからある意味正確??
おじさんのデータだと10以上外したの二つしかないし。

学習アルゴリズムが多少違っても、どちらもある程度正しく学習できていれば、残差プロットの特徴ってだいたい一致するのね。


残差プロットってこういう具合にプログラムにバグがないかを判断するのにも使えるのね。

勉強になるねぇ。

これで、いろんな株価の特徴データのCSVファイルを作れば、ブラウザベースで株価のAIデータ解析ができて、学習が正しいかわかるはず。

ソースコードはこちら

https://github.com/yomei-o/Protra_cpp/tree/main/server/scatter_plot

2022年2月6日日曜日

c++でデータマイニングをする。

 おじさん、先週は勾配ブーストの機械学習ライブラリの使い方がわかったので、今週はデータマイニングのやり方を勉強します。


データマイニングって意味がよくわからないし。日本語で言うと統計解析?

統計解析とデータマイニングは違うといってる人もいるし。

データマイニングとは、上の図のように相関行列を求めたりしてデータの中から意味のある情報を取りだすことらしいです。

そしてその手法が統計解析っぽいです。

PythonのPandasなどの統計解析のライブラリを使うと上の図のような相関行列を簡単に作り出せます。

なんかデータマイニングしてる感じが出てかっこいいね。


そもそも統計解析はR言語やPythonを使って行うのが一般的なのですが、R言語とかでやると遅いらしく、海外ではC++で高速に行ったりもしています。

でもC++で統計解析を行っている日本語の記事が一つもない。

どうやってC++で統計解析をやるのか日本語で正しく書かれているサイトがひとつもないのです。

さみしいなぁ。

日本の金融業界とか証券業界ってどうやって統計解析をやっているのでしょうか?

きっと外部に丸投げ?

ということで、今日はC++で統計解析を行って相関係数を求めてみたいと思います。


C++で統計解析を行うには、DataFrameというライブラリを使用します。

https://github.com/hosseinmoein/DataFrame

これ名前がよくなくて、DetaFrameなんていう一般的によく使われる単語の組み合わせなので、なかなか検索で出てきません。

でもこれを使うと簡単に相関係数を求めることができます。


統計解析のライブラリってどれもだいぶ癖が強めです。

というかDetaFrameという概念に癖がありますね。

普通、データをCSVファイルとかで読むときとかは、まず行を読んでそのあと列に分割して処理するのですが、行を中心に行います。

しかし、統計解析って列選択して統計処理を行うので行と列が逆なのです。。

そもそも英語でcolとrowどっちがどっちかわからないし。

年を取ってくると頭が固くなってこういう柔軟な思考に頭が瞬時に追いつかない。

でもDetaFrameの使い方がわかれば、ついでにR言語やPandasの使い方もわかります。


いろいろ書きましたが、C++でDetaFrameのライブラリを使ってボストンの住宅価格の相関行列を求めてみました。



ソースコード

-------------------------------------

#include <stdio.h>

#include <iostream>

#include <stdexcept>


#include <DataFrame_DataFrame.h>


using namespace hmdf;

using MyDataFrame = StdDataFrame<int>;


template<class T> inline std::vector<std::string> split(const std::string& s, const T& separator, bool ignore_empty = 0, bool split_empty = 0) {

struct {

auto len(const std::string& s) { return s.length(); }

auto len(const std::string::value_type* p) { return p ? std::char_traits<std::string::value_type>::length(p) : 0; }

auto len(const std::string::value_type  c) { return c == std::string::value_type() ? 0 : 1; /*return 1;*/ }

} util;


if (s.empty()) { /// empty string ///

if (!split_empty || util.len(separator)) return { "" };

return {};

}


auto v = std::vector<std::string>();

auto n = static_cast<std::string::size_type>(util.len(separator));

if (n == 0) {    /// empty separator ///

if (!split_empty) return { s };

for (auto&& c : s) v.emplace_back(1, c);

return v;

}


auto p = std::string::size_type(0);

while (1) {      /// split with separator ///

auto pos = s.find(separator, p);

if (pos == std::string::npos) {

if (ignore_empty && p - n + 1 == s.size()) break;

v.emplace_back(s.begin() + p, s.end());

break;

}

if (!ignore_empty || p != pos)

v.emplace_back(s.begin() + p, s.begin() + pos);

p = pos + n;

}

return v;

}


struct datapair {

float* data;

float* label;

int rows;

int cols;

};


struct datapair* readboston(const char* fn)

{

FILE* fp;

struct datapair* ret = NULL;

char buf[256];

std::string str;

std::vector<std::string> rows;

std::vector<std::string> cols;

fp = fopen(fn, "rt");

if (fp == NULL)return ret;

while (1) {

buf[0] = 0;

fgets(buf, sizeof(buf), fp);

if (buf[0] == 0)break;

str = buf;

rows.push_back(str);

}

ret = new(struct  datapair);

ret->cols = 13;

ret->rows = rows.size();

ret->data = new float[13 * rows.size()];

ret->label = new float[rows.size()];


for (int i = 0; i < rows.size(); i++) {

cols = split(rows[i], " ", 1, 1);

if (cols.size() < 14)continue;

for (int j = 0; j < 13; j++) {

ret->data[13 * i + j] = std::stod(cols[j]);

}

ret->label[i] = std::stod(cols[13]);

}

return ret;

}


void freedata(struct datapair* d)

{

if (d == nullptr)return;

delete[] d->data;

delete[] d->label;

delete d;

}



int main(int argc, char* argv[])

{

    MyDataFrame df;

    std::vector<int> index;

    std::vector<float> tmp;

    StatsVisitor<float>    stats_visitor;

std::vector<std::string> col_lbl;

char col_name[256];

struct datapair* dp;

int ret;


dp = readboston("housing.data");

for (int j = 0; j < dp->rows; j++) {

index.push_back(j);

}

df.load_index(std::move(index));


for (int j = 0; j < dp->cols; j++) {

sprintf(col_name, "col_%d", j);

tmp.clear();

for (int i = 0; i < dp->rows; i++) {

tmp.push_back(dp->data[j+i*dp->cols]);

}

col_lbl.push_back(col_name);

df.load_column<float>(col_name, std::move(tmp));

}


sprintf(col_name, "col_%d", 24);

tmp.clear();

for (int j = 0; j < dp->rows; j++) {

tmp.push_back(dp->label[j]);

}

df.load_column<float>(col_name, std::move(tmp));

col_lbl.push_back(col_name);


CorrVisitor<float> corr_visitor;

for (int j = 0; j < dp->cols + 1; j++) {

for (int i = 0; i < dp->cols + 1; i++) {

printf("+-----");

}

printf("+\n");

for (int i = 0; i < dp->cols + 1; i++) {

auto fut10 = df.visit<float, float>(col_lbl[i].c_str(), col_lbl[j].c_str(), corr_visitor);

float res = corr_visitor.get_result();

printf("|%5.2f", res);

}

printf("|\n");

}

for (int i = 0; i < dp->cols + 1; i++) {

printf("+-----");

}

printf("+\n");

return 0;

}


-------------------------------------


結果


これでC++を使ってプログラムで自動でデータマイニングができそう。


2022年2月4日金曜日

lightGBMで回帰分析をする。

 おじさん、毎日システムトレードに向けてプログラムを勉強しています。

株価の予想ってたぶん回帰分析なので、本日はlightGBMで回帰分析をしてみます。


回帰分析と言えば、ボストンの住宅価格予想!

アメリカのボストンの住宅のデータをもとにその価格を予想する定番のやつです。

これを住宅データの代わりに株のデータにすれば、株価の予想ができるはず。



むかし、このブログでもタイタニックの生存者の判定とかマンションの価格推定とかをやりました。

混同行列の図を見ればわかりますが、このふざけた複雑な相関関係。

いかにも普通のプログラムでは難しそう。でも原理は全く同じです。


作ってみてわかったのですが、先日作ったlightGBMのMNISTのソースコードをほんの少し直すだけで、住宅価格の回帰分析ができます。

学習の関数に渡すパラメーターを変えるだけでいろんなタイプの学習ができるんですね。

これはすごい。

たぶん、株価の予想もこれを少し直すだけできっとできるようになるんですね。


ネットでも書かれている通り、回帰分析って作ったプログラムの結果が正しいかどうか結果の数値だけからはなかなかわからない。

解けた感が全くありません。

むしろこれが本当に正しいのかという猜疑心が常にわいてきます。

同じデータを別のプログラムでもう一つ作らないと正しいことがわからないのです。

おじさんもネットに落ちていたPythonのlightGBMのボストンの住宅価格のプログラムの結果と比較して自分のプログラムが正しいことを確かめました。

いろいろ勉強になるね。


ソースコード

---------------------------------

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <string>

#include <vector>

#include "LightGBM/c_api.h"



template<class T> inline std::vector<std::string> split(const std::string& s, const T& separator, bool ignore_empty = 0, bool split_empty = 0) {

struct {

auto len(const std::string& s) { return s.length(); }

auto len(const std::string::value_type* p) { return p ? std::char_traits<std::string::value_type>::length(p) : 0; }

auto len(const std::string::value_type  c) { return c == std::string::value_type() ? 0 : 1; /*return 1;*/ }

} util;


if (s.empty()) { /// empty string ///

if (!split_empty || util.len(separator)) return { "" };

return {};

}


auto v = std::vector<std::string>();

auto n = static_cast<std::string::size_type>(util.len(separator));

if (n == 0) {    /// empty separator ///

if (!split_empty) return { s };

for (auto&& c : s) v.emplace_back(1, c);

return v;

}


auto p = std::string::size_type(0);

while (1) {      /// split with separator ///

auto pos = s.find(separator, p);

if (pos == std::string::npos) {

if (ignore_empty && p - n + 1 == s.size()) break;

v.emplace_back(s.begin() + p, s.end());

break;

}

if (!ignore_empty || p != pos)

v.emplace_back(s.begin() + p, s.begin() + pos);

p = pos + n;

}

return v;

}


struct datapair {

float* data;

float* label;

int rows;

int cols;

};


struct datapair* readboston(const char* fn)

{

FILE* fp;

struct datapair * ret = NULL;

char buf[256];

std::string str;

std::vector<std::string> rows;

std::vector<std::string> cols;

fp = fopen(fn, "rt");

if (fp == NULL)return ret;

while (1) {

buf[0] = 0;

fgets(buf, sizeof(buf), fp);

if (buf[0] == 0)break;

str = buf;

rows.push_back(str);

}

ret = new(struct  datapair);

ret->cols = 13;

ret->rows = rows.size();

ret->data = new float[13*rows.size()];

ret->label = new float[rows.size()];


for(int i=0;i<rows.size();i++){

cols=split(rows[i], " ", 1, 1);

if (cols.size() < 14)continue;

for (int j = 0; j < 13; j++) {

ret->data[13*i+j]=std::stod(cols[j]);

}

ret->label[i]= std::stod(cols[13]);

}

return ret;

}


void freedata(struct datapair*d)

{

if (d == nullptr)return;

delete[] d->data;

delete[] d->label;

delete d;

}


int main(int argc, char* argv[])

{

int ret;


DatasetHandle hx_train, hx_test;

struct datapair* dp;



dp=readboston("housing.data");

int pos = dp->rows * 0.8;

int n = dp->rows - pos;


#if 0

for (int i = 0; i < pos; i++) {

printf("%d ",i);

for (int j = 0; j < 13; j++)printf("%f ",dp->data[i*13+j]);

printf(">>%f\n",dp->label[i]);

}

#endif


ret = LGBM_DatasetCreateFromMat(dp->data, C_API_DTYPE_FLOAT32, pos,

dp->cols, 1, "", nullptr, &hx_train);

if (ret) {

printf("Error: LGBM_DatasetCreateFromMat()\n");

return 1;

}

ret = LGBM_DatasetSetField(hx_train, "label", dp->label, pos, C_API_DTYPE_FLOAT32);

if (ret) {

printf("Error: LGBM_DatasetSetField()\n");

return 1;

}


ret = LGBM_DatasetCreateFromMat(&dp->data[dp->cols*pos], C_API_DTYPE_FLOAT32, n,

dp->cols, 1, "", hx_train, &hx_test);

if (ret) {

printf("Error: LGBM_DatasetCreateFromMat()\n");

return 1;

}

ret = LGBM_DatasetSetField(hx_test, "label", &dp->label[pos], n, C_API_DTYPE_FLOAT32);

if (ret) {

printf("Error: LGBM_DatasetSetField()\n");

return 1;

}


printf("Create Data OK!!\n");


BoosterHandle bh;

ret = LGBM_BoosterCreate(hx_train, "objective=regression "

"metric=rmse", &bh);

if (ret) {

printf("Error: LGBM_BoosterCreate()\n");

return 1;

}


ret = LGBM_BoosterAddValidData(bh, hx_test);

if (ret) {

printf("Error: LGBM_BoosterAddValidData()\n");

return 1;

}


int is_finished = 0;

for (int i = 0; i < 100; i++) {

double d = 0;

ret = LGBM_BoosterUpdateOneIter(bh, &is_finished);

if (ret) {

printf("Error: LGBM_BoosterUpdateOneIter()\n");

return 1;

}

int out_len = 10;

ret = LGBM_BoosterGetEval(bh, 1, &out_len, &d);

if (ret) {

printf("Error: LGBM_BoosterGetEval()\n");

return 1;

}

printf("%d %f\n",i,d);

}


printf("Update OK!!\n");


long long d_len = 1;

double d;


ret = LGBM_BoosterPredictForMat(bh, &dp->data[dp->cols * pos], C_API_DTYPE_FLOAT32, 1, 13,

1, C_API_PREDICT_NORMAL, 0, -1, "", &d_len, &d);

if (ret) {

printf("Error: LGBM_BoosterPredictForMat()\n");

return 1;

}

printf("input\n");

for (int i = 0; i < 13; i++) {

printf("%d  %f\n",i, dp->data[dp->cols * pos+i]);

}

printf("predict\n");

printf("d=%f\n", d);


LGBM_BoosterFree(bh);

LGBM_DatasetFree(hx_train);

LGBM_DatasetFree(hx_test);


freedata(dp);


return 0;

}

---------------------------------



結果

---------------------------------

Create Data OK!!
[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000566 seconds.
You can set `force_row_wise=true` to remove the overhead.
And if memory is not enough, you can set `force_col_wise=true`.
[LightGBM] [Info] Total Bins 1028
[LightGBM] [Info] Number of data points in the train set: 404, number of used features: 13
[LightGBM] [Info] Start training from score 24.175743
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
0 8.902198
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
1 8.128168
...
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
99 5.225559
Update OK!!
input
0  41.529202
1  0.000000
2  18.100000
3  0.000000
4  0.693000
5  5.531000
6  85.400002
7  1.607400
8  24.000000
9  666.000000
10  20.200001
11  329.459991
12  27.379999
predict
d=9.342857

---------------------------------