pytorch-lightningのtorchmetricsにある Recallの定義

torchmetrics.readthedocs.io

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分あしで取得するとデータの欠損がそこそこあり、信頼性に欠けるので避けるべきだろう。分足なら使えるかもしれない。ただし、そこそこの頻度でアクセスするとブラックリスト入りするので注意が必要。 株式分割の調整は不明。

https://query1.finance.yahoo.com/v7/finance/chart/HACK?range=7d&interval=1m&indicators=quote&includeTimestamps=true

Freemium

ちょっと使ってみるだけならタダで使えるやつ。実際の使い勝手などを確認できるので便利である。

yahoo finance on Rapid API

rapidapi.com

こちらは上のAPIの非公式バージョン。こちらはいろいろなAPIが用意されており、freemiumで提供されている。ファンダメンタルズの情報やニュースまでAPIで取得できる。 使うならこちらの方が良いだろう。ただし、1分足は上と同様に欠損があった。 提供データはOHLCV (open/high/low/close/volume).

Alpha Vantage

www.alphavantage.co

無料だと1分間に最大5回、1日に最大500回までAPIを叩ける。プレミアムになると75/分で、価格は50$/mo.それ以上のプランもあり。 RapidAPIでも提供している。 提供データはOHLCV (open/high/low/close/volume) .

https://rapidapi.com/alphavantage/api/alpha-vantage/pricing

polygon

polygon.io

無料で過去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

eodhistoricaldata.com

APIを通じて取得できる。サブスクリプション形式。全世界の株式市場のデータを過去30年以上に渡り取得できるのが特徴。EODはEnd-of-Dayのことで、名前の通り日足データが中心。株式分割の情報も取れる。分足の提供もあるが、直近のものしかない。プレマーケットとアフターマーケットもあり。プランによっては株価だけでなく、ファンダメンタルの情報(これも20年以上データがある)やオプションなども取得できる。全部盛ると高い。スクリーナーもAPIで提供されており、手厚い。20$/moからでそこそこ手軽。Fundamental APIを利用するとETFの組み込み銘柄も取れるらしい。 OHLCV (open/high/low/close/volume)

IEX Cloud

iexcloud.io

有料の中ではダントツで安い。個人なら年契約で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に取り組むにあたり、使用可能なライブラリをまとめてくれているテンプレートを見つけたので、それを使用する。

github.com

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__()メソッドを持つオブジェクトである。オブジェクトにするとパラメーターを変更したいときに元の関数を変更しなくともよいので便利である。もちろん関数を返す関数を作成してもよいので、これは好みによるかなとおもう。

DataLoadernum_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)