頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


matplotlibでグラフを描こうとするとエラー

Pythonで計算した結果をグラフにしようとしたらエラーが出て困った、というお話。

QObject::connect: Cannot connect NavigationToolbar2QT::message(QString) to (null)::_show_message()

ってエラーが出る。なぜだ?matplotlibでグラフって前にもやってるのに、、、?
そのコードを探して持ってきて実行させてもやはり同じエラーが出る。
エラーメッセージで検索するとバージョンが古いんじゃね?という記述を見たので、自分の環境を調べてみた。

import matplotlib

print(matplotlib.__version__) # 1.5.1
1.5.1で古いんかな?pip install matplotlib してみるけど
Requirement already satisfied: matplotlib
てな感じで最新版ダウンロードしてるようにも見えないし、、、

以前やったコードを「そのまま」実行させたらちゃんと動いた!

matplotlibによるグラフ

つまり、、、そういうことか!

PyQtによるメニュー画面

↑今はこんな感じのPyQt5使ったメニュー画面を経由したところでmatplotlibでグラフ表示させようとしてる。
どうやらそれがダメらしい。メニュー画面を経由しなければいけた。

PyQt5 Matplotlib – Python Tutorial
↑こんな感じでPyQtのメインウインドウにグラフを描くのはできるみたいなんだけど、描きたいのはサブウインドウに、なんだよなあ、、、うーん。
何かやり方はあるのかもしれないけど、、、
結局下のようなおきまりのコードを追加して直接このファイルを実行するようにした。

if __name__ == '__main__' :
    showGraph()
↑Pythonを勉強し始めた頃には何の役に立つの?と思っていたけど、大助かりだわ。


SceneKitでシェーダーを適用したのに一部しか反映されない

Blenderで作成したオブジェクトをdaeファイルで出力→SceneKitで使おうとしたけどうまく認識できていない?って妙な不具合に悩んでいた。まあ同じような症状にはまる人もいないと思うけど、とりあえず書いておく。

Blenderでオブジェクト作成

↑Blenderではこんな形状。これで1つのオブジェクト。ボーンが設定されてるんだけど本筋には関係なかった。
これをdaeファイルで出力。

SceneKitでdaeファイルの表示

↑SceneKitで使う。ここまではいいんだけど、このオブジェクトにシェーダーを適用すると、、、

SCNNodeにシェーダー適用

↑片側しか適用されない?なんでや?

Xcodeでdaeファイル確認

↑もしかして二つのSCNNodeオブジェクトになってんの?と思い、Xcode上でオブジェクトの構成を確認しても1つのオブジェクトみたい。
いろいろ試したり、調べてたりしたんだけど、daeファイルの中身を見てたらマテリアルが二重に設定されてることに気付いた。

Blenderでのマテリアル設定

↑Blenderで確認すると確かに設定したつもりはないんだけど二つある。片方を削除してやったら、、、

SCNNodeにシェーダー適用(修正後)

↑いけた!そういうことだったのか。
確かに、コードでも最初のmaterialにだけシェーダを適用するように書いてたわ。
{
    SCNGeometry *geometry = node.geometry;
    SCNMaterial *material = geometry.firstMaterial;

    SCNProgram *program = [SCNProgram program];
    program.vertexFunctionName = @"myVertex";
    program.fragmentFunctionName = @"myFragment";
    material.program = program;
}



SceneKitのHitTestにオプション付けたらなぜかうまくいった

macOS用アプリでSceneKit使ってエディターっぽいものを作っているんだけど、オブジェクトのHit Testがたまにうまくいかない場合があってなんだこりゃ?と悩んでいたんだけど、
{
    NSDictionary *option = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:SCNHitTestBoundingBoxOnlyKey];
    NSArray *results = [scnView hitTest:point options:option];
}
てな感じでbounding box only のオプションをセットすると意図通りに動いた!
ということはややこしい形状のオブジェクトだとHit Testの精度がイマイチなのだろうか?

カメラオブジェクト

↑ややこしいと言ってもこの程度なんだけどなあ?


MacのPythonからIFTTTを使ってiPhoneに通知

機械学習で株価予測やってみたが
↑これに関連して、Pythonで日経平均採用銘柄225種の株価のスクレイピングをやってる。
時々インターネットの回線の具合が悪いのか、データを取りに行ったもののうまくいかずエラーで止まってることがある。そこで例外拾って再度動かす、というのもありだけど、スクレイピングなので意図しない不具合でアホみたいにリクエストしてサイトにブロックされても困るし、、、ってことでここは通知してもらいたい。

そんなわけで、エラー発生時にiPhoneにメールか通知でもできんかなあと調べてみた。
するとなにやらapnsなるものを使ってどうのこうのとすればいい、という記事はあるんだけど俺には難易度が高い。もっと簡単なのはないかのうと試したのがIFTTTを使ってみる方法。

1)エラー発生時など通知したいタイミングでMacのDropboxフォルダーにテキストファイルを保存する。

{
    req = urllib.request.Request(url)

    try :
        response = urllib.request.urlopen(req)
    except urllib.error.URLError as e:
        print(e.reason)
        MyUtility.sendErrorNotify(stockName)

    html = response.read()
}
↑呼び出す部分はこんな感じ。例外のとこで通知するようにしてる。
Pythonでの「通知」処理とは言っても単にDropboxの任意のフォルダー(ここではiftttとしてる)に適当なテキストファイルを保存するだけなのでコードは省略。

2)iPhoneのIFTTTアプリで「Dropboxのあるフォルダーにファイルが保存されたらiPhoneに通知」というAppletを作成

IFTTTのApplet

これでOK。
最初はGoogle Driveでやってみたけど試した時にGoogle Driveの調子が悪いのかうまくいかなかった。IFTTTで扱えるサービスで自分好みのを使えばよろしいかと。

IFTTTによる通知

↑実際のiPhoneの通知画面だとこんな感じ。文字もいろいろとカスタマイズできる。すごいな、IFTTT!
ただDropbox経由なのでホントに回線が切れっぱなしだと通知は来ないんだけどね。
機械学習の途中経過報告とかにも使えそう。


機械学習で株価予測やってみたが

今更かよってネタだけどTensorFlow使って株価予測をやってる。
やってみたけどうまくいかないって内容だけど、、、現時点での備忘録。

1)データセット
スクレイピングなどのデータ収集方法は置いといて、、、
学習データには日付、日経平均、JASDAQ指数、ドル、ユーロと予想の対象となる株価(今回はトヨタ 7203)を使ってる。売買の手数料については無視(俺の場合だと信用取引で100万円betしても税込388円だし)。

ユーロが1991年1月から導入されたとかなんとかで、自分が収集した方法ではこのユーロが一番データ数が少ない。1991年1月から2017年6月末までを学習データ、7月から12月末までをテストデータとしてデータセットを作成。
寄りで買うか売り、引けでその反対の売買をする。信用取引で売りからもあり。宵越しの株は持たない。

1つのデータは以下のようなデータを持つ。
横幅はn日分、縦は項目(上記の日付、日経平均など)、奥行きが4つで始値、高値、安値、終値の4つ。悩んだけど、出来高は考慮外。

正解は 終値/始値 の値をベースに9種類とした。ざっくり下のような感じ。5から8はマイナス側。
0 +6%超
1 +4%〜+6%
2 +2%〜+4%
3 0%〜+2%
4 変化なし

確率分布図1
↑理想的には確率分布を求めるイメージ。
あと、学習には使わないけど実際にbetした場合の利率(一番知りたい値だよね)を計算するために 終値/始値 の値も入れてる。


2)NNの構成
上記のようなデータにしたのはCNN(畳み込み)で解いてみようとしたため。MNISTとかだと画像が白黒だったのでチャンネル(画像の奥行き)が1だったが、今回は4。Cifar10はカラー画像なので参考になるかも。
なお、今回のデータを4チャンネルの画像としてデータ化すると1つの値が8ビットしかないので無次元化すると高値も安値も同じ値になるかもしれないので注意(いや、俺が実際画像を作って気付いたんだけどね)。32bitの浮動小数点数で扱ってる。
畳み込みなのでCifar10みたいな畳み込み層2つにLRN層、ドロップアウト、全結合層、出力層ってよくある感じ。


3)損失関数、期待値
損失関数にはソフトマックス関数を使っているので各ラベルの確率を得ることができる。
画像認識なんかでは単に一番確率の高いのを選ぶのが一般的だけど、今回は確率分布を得ているつもりなので、期待値の高い方にbetすることにする。

確率分布図2
↑極端な例だけどこういう場合、確率が一番高いのはマイナス側にあるので売りがよさそうに見えるけど、買いと売りだと買いの方が期待値(面積だよね)が高くなるので買いにbetする。この期待値うんぬんは学習時には関係なくて、テストデータの検証でのみ使う。


4)結果

TensorBoadによる損失関数の値変化
↑学習するやん!と喜んだのだが、、、学習が進むめば進むほど損失関数の値が学習用のデータに対する値と、テスト用のデータに対する値でどんどん乖離していった。
的中率や肝心の利率も同様で、正解率はせいぜい43%程度、半年での利率は0から-3%という結果に(パラメータをいじってもたいしてよくならなかった)。

ちなみに学習データに対してはツイートもしたけど、、、



こういう値がテストデータで出るのを期待してたんだが。
データ数少ないよねえ、、、1991年からで5,400個程度だしなあ。


5)雑感
こういうわけのわからん株価データに対してもちゃんと学習が進むんだなあ、というのには感心した。NNの表現力というか。機械学習やTensorFlowの研究者、開発者にほんとリスペクトである。

それと相場ってのはやっぱり掴み所がないんだねえ。26年間のデータに対し90%正解率あるモデルでも、いざ新しいデータに対しては50%いかないんだもの。


動くようになったらNNの構成やパラーメータをいじったりしないと、と思ってたけどそれ以前に圧倒的にデータ数が足りないみたい。ここをなんとかしないとねえ、、、




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad