pytorch-lightningのtorchmetricsにある Recallの定義
torchmetrics.Recallを使いたかったけど、説明に陽性陰性の定義方法が書いてなかった。ソース辿っていくと
metrics/torchmetrics/functional/classification/stat_scores.py
にその定義が書いてあった。
具体的には
https://github.com/PyTorchLightning/metrics/blob/03a8520e4c6d0282260820a03d86a9f260314694/torchmetrics/functional/classification/stat_scores.py#L65
に
pos_pred, neg_pred = preds == 1, preds == 0
とあったので、1が陽性で0が陰性である。 ドキュメントに書いて欲しい。バイナリで指定してでだけではどっちか不安になってしまう。しかし、提供されているだけありがたい。自分で書くとこういうところは面倒だ。
アメリカ市場の分足のデータを取得する
株価の予測を機械学習で行ったりしたい。データの量を考えると分足が望ましいが、お金がないのでできれば無料のものが良い。 私は米国株が中心なので、米国株について調べたが、日本語ではyahoo finance USを使うもの以外あまりまとまった情報が出てこなかった。これでもいいじゃんと最初は思ったのだが、実際にデータを取得すると結構な頻度でデータが欠損しているので非常に扱いづらい。そこで海外の情報をまとめてみよう。これらのサービスには企業を対象に想定したもののみのところや、個人も想定しているところがあったりする。プランに分け隔てないとかなり値段が高くなるので、個人向けプランを出しているところを選択するのが良いだろう。
Free
まずは完全に無料のものから、実質ないに等しいが挙げてみる。
yahoo finance (US)
正式には公開が終了したものの、なぜか公開されているyahoo financeのAPIである。 検索でてくるとよく出てくるものである。1分あしで取得するとデータの欠損がそこそこあり、信頼性に欠けるので避けるべきだろう。分足なら使えるかもしれない。ただし、そこそこの頻度でアクセスするとブラックリスト入りするので注意が必要。 株式分割の調整は不明。
Freemium
ちょっと使ってみるだけならタダで使えるやつ。実際の使い勝手などを確認できるので便利である。
yahoo finance on Rapid API
こちらは上のAPIの非公式バージョン。こちらはいろいろなAPIが用意されており、freemiumで提供されている。ファンダメンタルズの情報やニュースまでAPIで取得できる。 使うならこちらの方が良いだろう。ただし、1分足は上と同様に欠損があった。 提供データはOHLCV (open/high/low/close/volume).
Alpha Vantage
無料だと1分間に最大5回、1日に最大500回までAPIを叩ける。プレミアムになると75/分で、価格は50$/mo.それ以上のプランもあり。 RapidAPIでも提供している。 提供データはOHLCV (open/high/low/close/volume) .
https://rapidapi.com/alphavantage/api/alpha-vantage/pricing
polygon
無料で過去2年間、有料(99$/mo)で10年間遡ってデータを取得できる。それぞれ1分足で取得できる。1分足でそこそこ過去データが欲しい場合はここを使うと良さそう。プレマーケットとアフターマーケットが含まれていることに注意。これらは必ず取引があるとは限らないので、データとしてない時もある。無料でも2年まで遡れるのは素晴らしい。株式分割の調整は有無の両方が取れる。ここは良さそうだ。
https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/minute/2019-2-14/2019-3-14?unadjusted=true&sort=asc&limit=120&apiKey={YOUR_API_KEY}
OHLCV (open/high/low/close/volume) + The volume weighted average price.
Paid
これらは有料のサービスである。お金が気にならなければどれも最高だ。基本的に高い。freemiumを採用しているところと違い、企業向けのものが多い印象だが、中には個人向けもある。
firstratedata
Download Historical Intraday Data (20 Years Data)
おそらく最も長い期間のデータを取得できる販売所。 各銘柄の上場初日からのデータを取得できるが、その分価格は高い。一銘柄あたり5000円ほどかかる。SP500に組み込まれている銘柄のセットや上場廃止になった銘柄など、様々用意されている。 提供データはOHLCV (open/high/low/close/volume) 。
EOD histrical data
APIを通じて取得できる。サブスクリプション形式。全世界の株式市場のデータを過去30年以上に渡り取得できるのが特徴。EODはEnd-of-Dayのことで、名前の通り日足データが中心。株式分割の情報も取れる。分足の提供もあるが、直近のものしかない。プレマーケットとアフターマーケットもあり。プランによっては株価だけでなく、ファンダメンタルの情報(これも20年以上データがある)やオプションなども取得できる。全部盛ると高い。スクリーナーもAPIで提供されており、手厚い。20$/moからでそこそこ手軽。Fundamental APIを利用するとETFの組み込み銘柄も取れるらしい。 OHLCV (open/high/low/close/volume)
IEX Cloud
有料の中ではダントツで安い。個人なら年契約で9$/mo。月契約なら19$/mo。SSE (Server-sent events) も50シンボルまでサポート。 気をつけるポイントは9$で使いたい放題というわけではなく、メッセージというクレジットが付与されてそれを全て消費すると追加のメッセージ代金がかかるという仕組みである。各APIのメッセージコストは種類や呼び出し内容によって変化する。ただし、そうそう超えることはなさそう。 Estimate your monthly message use | IEX Cloudここで用途ごとの価格をシミュレーションできる。
分足は最新30日、日足は最新15年がある。株式分割の調整は有無の両方が取れる。
OHLCV (open/high/low/close/volume) ?。
さいごに
日足で少ししか集めないのであればとりあえずyahoo financeを使っておけば良いと思う。 一方大量に取得したいなら、有料のサービスを使った方が良い。freeやfreemiumは制限が多く無駄に時間がとられてしまうためだ。また、有料だとファンダメンタルズやオプションの情報も取れるのでより楽しめるだろう。 分足が欲しいのであればpolygonと IEX Cloudで事足りそうだ。調べているともう少しいろいろありそうだったが、とりあえずこれでリサーチは止めておく。 今回は主に株価価格のみに着目したが、オプションやファンダメンタルズの情報もAPIで取れるのが一般的だ。株価以外の情報も使いたくなったらまたリサーチを行。
rustで1競技プログラミングはじめました。
Rustで競技プログラミング(競プロ)を本格的に始めようかと思います。 競プロはまえまえからちゃんとやりたいと思っていたが、モチベーションがいまいち高まらずにいたが、会社の同僚とRustの勉強をしているけれど本を読んでいるだけで手も動かしたいなということで、言語の勉強とアルゴリズムの勉強ができるということではじめることにする。
Qiitaの記事に分野別 初中級者が解くべき過去問精選 100 問があるのでそれを解いていく。 すでに5問ほどといたが、今後も継続しよう。 qiita.com
あと、土曜日の夜にatcoderのコンテストが開催されるが、なんとかそれには参加するようにしよう。
Atcoderに取り組むにあたり、使用可能なライブラリをまとめてくれているテンプレートを見つけたので、それを使用する。
singuralityでAWS ECRのdocker imageを方法
AWSのプロファイルは設定済みとする。 環境変数を設定してpullするだけでできる。
set -x SINGULARITY_DOCKER_USERNAME AWS set -x SINGULARITY_DOCKER_PASSWORD (aws ecr get-login-password --region ap-northeast-1) singularity pull docker://{MY_DOCKER_IMAGE}
これを行うと通常のsingularityのイメージのビルドが行えなくなるので、作業が終わったらSINGULARITY_DOCKER_USERNAME
を空に戻しておく必要がある。
docker内でGPG errorが出た際の対処
docker内で以下のようなGPG errorが出た際の対処方法
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://security.debian.org/debian-security buster/updates InRelease: At least one invalid signature was encountered.
GPG keyが古くなってしまっているので、新しいものに交換する必要があるのだが、その作業をdockerfile内に書くのはあまり良くない。この方法ではDockerfileを変更することなく回避することができる。
対処法
- 元イメージを最新にする ex)
docker pull python:3.7-slim-buster
--no-cache
をつけてビルドする- ビルドキャッシュを削除する
docker system prune
元イメージにあるGPG keyが古いので新しいkeyを持っている(であろう)イメージに交換する。元イメージはなるべく大きなプロジェクトのものを使用していればたいてい更新してくれているはずだ。もし、更新してくれなければ、それはこちらで対応するのではなく、元イメージの方を更新するという対処を行うべきだろう。
2つ目は内部のキャッシュにより古いイメージが使用されてしまう可能性があるため、キャッシュを使用しない用にしよう。
3つ目は、2つ目があれば良さそうだが、私の場合はシステムのビルドキャッシュをすべて削除しなければ更新されなかった。ここは要調査である。
pytorchのdataloaderとtransformを自作する
pytorchのdataloaderとtransformを自作する
概要
最小構成でのサンプルにより、dataloaderとtransformの自作方法を例示する。
ポイントは前処理を行うtorchvision.transforms
に関する部分には、自由に関数を入れることができるというところである。ToTensor()
を使用すると形がndarrayからtensorに変化してしまうので注意する必要がある。ToTensor()
より前なら汎用的な関数を使用できるので便利だろう。
前処理の定義方法は、前処理の関数をlistとしてtorchvision.transforms.Compose()
に渡すことで行うことができる。Compose()
は必須ではないが、これを使うと複数の前処理を連鎖して実行できるようになるのだ。渡すlistの中身は関数オブジェクトか、__call__()
メソッドを持つオブジェクトであり、前から順番に実行される。以下の例ではf
が関数でtorchvision.transforms.ToTensor()
がオブジェクトである。pytorchが用意してくれている関数は基本的に__call__()
メソッドを持つオブジェクトである。オブジェクトにするとパラメーターを変更したいときに元の関数を変更しなくともよいので便利である。もちろん関数を返す関数を作成してもよいので、これは好みによるかなとおもう。
DataLoader
のnum_workers
の意味
DataLoaderで最終なdataの読み込みを行うイテレータを作成する、単なるイテレータならわざわざpytorchのDataLoaderを使わずとも簡単に自作できる。pytorchのDataloaderの場合は__len__()
を持ってる必要がある分、generatorが使用できないのでむしろ不便である。
しかし、DataLoader
にはloopを回している間に次のイテレータの実行をバックグラウンドで行なってくれるという大きな利点がある。前処理をおこなうworkerという名前で呼ばれるプロセスを立ち上げて、loopの中身を実行している間に事前に前処理を行なってくれるのだ。ちなみに、pythonは言語としてマルチスレッドに対応していないので、プロセスを立ち上げるという対応になっているのだと思う。
num_workers
はそのプロセス数を指定する物である。num_workers
の数だけworkerプロセスが立ち上げられる。気をつけなければならないのは、一つのイテレータないで並列化されるのではなく、それぞれのプロセスは別々のイテレータの前処理をおこなうという点だ。例えばnum_workers=5
とすると5個先のイテレータまでバックグラウンドで実行してくれる。
また、workerは常に投機的に実行し続けるので、同時に実行する前処理のプロセス数はnum_workers
で指定した数だが、早く終わるとさらに先の前処理までおこなうようになっている。
無限におこなうはずはないと思うが、どこまで投機的に実行するのかは追い切れていない。
所感としては、loopの中と前処理が毎回同じ実行コストで低コストあれば2で十分だが、ばらつきがある場合は、長くかかるloopや前処理のバッファを貯めるために少し多めに設定しても良いのではと思う。また、ほとんどの処理がシングルスレッドならGPUでの計算を邪魔しない程度に増やしても良いだろう。逆にデータのロードの際にIO waitがボトルネックになる場合は多くしないほうがよさそうではある。
sample code
import torch import torchvision import numpy as np import time def f(x): time.sleep(0.2) return 2*x class MyTransform: def __init__(self, a): self.a = a def __call__(self, x): return self.a * x class Mydatasets(torch.utils.data.Dataset): def __init__(self, leng, transform1 = None): self.transform1 = transform1 self.dataset = list(np.arange(leng).reshape(leng,1,1)) self.datanum = leng def __len__(self): return self.datanum def __getitem__(self, idx): out_data = self.dataset[idx] if self.transform1: out_data = self.transform1(out_data) return out_data def __str__(self): return f"""my original dataloader. data num: {self.datanum}""" if __name__ == "__main__": trans = torchvision.transforms.Compose([f, MyTransform(3), torchvision.transforms.ToTensor()]) dataset = Mydatasets(10, transform1=trans) print(dataset) trainloader = torch.utils.data.DataLoader(dataset, batch_size = 10, shuffle = False, num_workers = 2) for z in trainloader: print(z) # for check worker's behaviour for i, z in enumerate(trainloader): print(z[0][0][0][0]) if i%5 == 0 and i is not 0: time.sleep(10) else: time.sleep(0.1)