ストックドッグ

KatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。サービスも運営してます→http://fmbrain.work

株価の予測精度が60%を超えた

【更新 2017-08-15】
未だによくアクセスがあるので、書いておきます。
この結果が検証したわけではないですが、きっと間違いです。
シミュレーション期間がとても短いこともあって、運が良かっただけのように思います。
検証するのも面倒なので、しませんが。
ただ、記事としては残しておこうと思います。
若気の至り的な自戒もこめて...

目次

予測精度が60%超えた!?

2014年8月15日〜2017年2月28日までの期間で、株価を予測するシミュレーションを行ったところ...

66.19%

となりました。


2値分類モデルで、n日後の株価が上昇しているか下落しているかを予測する、というものです。


予測対象はETFで、2013年1月時点で運用をしているという条件で絞り込んでいます。

[ 1305, 1306, 1308, 1309, 1310, 1311, 1320, 1321, 1324, 1325, 1326, 1328, 1329, 1330, 1343, 1344, 1345, 1346, 1348, 1540, 1541, 1542, 1545, 1546, 1547, 1550, 1552, 1554, 1555, 1563, 1566, 1569, 1570, 1571, 1572, 1615, 1671, 1678, 1680, 1681, 1698, 1699 ]

ETFだから予測精度が高いとかそういうことではなくて、個別銘柄でもおそらくあまり変わらない結果が出ると思います。

ETFにしているのは、購入単位が安いので売買シミュレーションがしやすいからです。

以下は平均予測精度を時系列順にプロットしたものです。

f:id:doz13189:20170303184448p:plain

これらの平均が66.19%ということになります。

定期的に大きく予測が外れるという特徴は以前から変わらずですね。

本当に予測できてるのか?

わかりません。

もう実践に投入して確かめるしかないと思ってます。


シミュレーションというシミュレーションはし尽くしました。

使用しているプログラムにも今の所ミスは見つかっていません。

ただ、今までの経験上予測精度が60%を超えると確実にミスが発見されます。

引き続きプログラムミスの可能性を疑ってかかることにします。


ということもありますが、今後はこれを活かすためにシストレやりたいなぁという方向性で頑張っています。

ただ、それらの知識が皆無なので大変です。

なんとか4月の入社までにある程度の形にもっていきたいですが、厳しいかも。

中身のアルゴリズムはあまり詳しく話しませんが...

私が株価予測を行う上で、ここを気にしたというポイントをまとめます。

2ヶ月前の自分に口酸っぱく言いたいな!という内容を書いています。

  • 株価の価格を予測しない
  • 時系列を意識する
  • 手法を組み合わせる


この3つに集約されます。

この3つを意識したあたりから、私は上手く行き出しました。

株価の価格を予測しない、というのはちょっとわかりにくいですね。

言い換えると、株価の価格を予測しても精度は上がらないよ、ということです。

じゃあ何予測すんねんって感じですね笑

これは私の経験則であり、組むアルゴリズムによってそこらへんの事情は変わると思いますが、私は価格を予測しようとしても精度は50%程度にいつも収束していきました。

だから、予測する対象を変えました。

予測する対象は、市場の方向性です。

市場の方向性とはつまり、市場が上昇傾向にあるのか、あるいは下落傾向にあるのか、です。

方向性を予測した結果を銘柄に適用しているだけです。


2つめの時系列を意識するというのは、当たり前かもしれません。

例えば、株価は自己相関しますね。(自己相関とは、上がったら下がってきて、下がったら上がってくる、という株価の性質をカッコよく言っているだけです。)

その性質を利用したアルゴリズムは数多く提唱されており、例えば、anticorなどが有名です。

anticorは時系列を強く意識したアルゴリズムと言えます。

株価の1回1回の価格形成は独立しているわけではありません。(前日の株価が次の日の株価に影響を与えている、ということ)

私は自己相関を利用しているわけではありませんが、時系列というのは強く意識しています。

株価が時間と共に変動している以上、時間という要素を抜いてはあまり上手くはいかないのじゃあないかな、というのが私の意見です。


はい、3つ目。

単発の手法ではなかなか精度は上がらないかな、というこれも私の経験則に基づいたものです。

株価に限らず、予測という分野は手法を組み合わせることで精度が劇的に上がるケースは多いと思います。

となると、ディープラーニングと何を組み合わせようかな〜、と考えてしまう人がいると思いますが、これはきっと上手く行きません。

ディープラーニングを使わないと予測できないとか、機械学習を使わないと予測できないとか、手法の問題ではないと思います。

手法を組み合わせるって言っても、考え方の問題だと私は思っています。

私は、アルゴリズムの中に強化学習を使用していますが、強化学習のどのアルゴリズムを使用しているというわけではありません。

強化学習の「報酬を最大化」する、という考え方をアルゴリズムに組み込んでいるだけです。

どうしても手法ありきで考えてしまうと、この手法は株価予測に使えるor使えないで判断してしまいます。

株価予測に最適なアルゴリズムなんてものはないので、ピッタリくるものはなかなか出会えないですよね。

色々なアルゴリズムの考え方を組み合わせながら、株価予測のアルゴリズムを構築していくのが大事かなって思います。

以上、ゆるーくポイントをまとめてみました。

ゆくゆくはアルゴリズムもフルオープンにしたいなぁと考えるもそう甘くはない

アルゴリズム取引の世界ってすごくクローズドですよね。

こんなにも様々な分野の様々な記事がネット上にアップされているにも関わらず、アルゴリズムトレードに関するものは極端に数が少なく、あったとしてもその記事の質は低かったりします。

もちろん、アルゴリズムを公開していて生き残って行ける業界ではないのですが。

ただ、ノウハウを個人個人で溜め込んで、それを墓まで持っていくスタイルなので、ノウハウの蓄積が少なく、若い人材が確実に育ちにくい形態をしています。

業界の体質上仕方がない気もしますが、なんとも歯がゆい...


今後10年でアルゴリズム取引という業界は今よりもっともっと大きくなります。

今でさえ米国では80〜90%の取引はアルゴリズムによるものであるというデータがありますし、フラッシュクラッシュなんて楽しいことも起きています。

現状、日本市場で動いているアルゴリズム取引も米国産のものが多いと言われていますし、日本のシストレ勢はまだまだ少ないように思います。

(少ないと言っても私のフォロー・フォロワーさんは優秀なシストレ勢がたくさんいますが...)


この現状をどうにかしたいなぁ、なんて考えているのでよく株価分析系の記事をできるだけわかりやすい内容にしてアップしたりはしているのですが、もっと根本の部分から変えないと現状は変わらないように感じています。

どうにかその仕組みづくりをできればなぁなんてのが最近の野望です。

最後に予測モデルで売買シミュレーションを行ったので、それを貼って記事を締めます

予測モデルと言っても、以前から使用してる予測精度が54〜55%くらいのモデルです。

(60%を超えたモデルではまだ売買シミュレーションをやっていません。)

予測モデルに従い、100万円を元手に2014年から2016年の3年間に取引を行うとどうなるかっていうシミュレーションです。

手数料はSBI証券のものを適用しています。

対象銘柄は、先ほどと同じETFであり、予測結果の中からランダムで銘柄選択をしているので、シミュレーションを20回行っています。

f:id:doz13189:20170303202833p:plain

3年間運用して、元手の100万円を割ったのは、20回中3回。

厳しい結果ですね。

予測精度と言っても、結局当たるか外れるかは確率なので、予測精度が利益に繋がるとは限りませんね。

これだとまだまだ市場投入するには早いかなって思います。

60%を超えたモデルでのシミュレーションはまだ行っていないので近々やると思います。

結果が楽しみです。(~o~)


今回は目的もなくダラダラと書いてしまって、収集がつきません。

強制的にここらで終わることにします。

終わり!

強化学習で銘柄を選んでみた(検証)

目次

今日やること

銘柄選択を強化学習に任せてみよう、ということをお題にシンプルな検証をやってみたいと思います。

強化学習

強化学習の中でも、基礎とされるn本腕バンディット問題について扱います。

相場をn本腕バンディット問題に見立てて、検証したいと思います。

そもそもn本腕バンディット問題って何?

見識高き読者は華麗に読み飛ばして下さい。

今回使用するバンディットアルゴリズムのε-グリーディ手法を私なりに説明してるだけです(数式は一切使いません)。


n本腕バンディット問題は例えで説明すると、とてもわかりやすいです。

例えスタート!!

f:id:doz13189:20170224221859j:plain

  1. ここに5つのコインがあります(画像は6枚ですが、気にしないで)
  2. 5つのコインは表がでる確率がそれぞれ異なります
  3. コインAは30%、コインBは40%、コインCは50%、コインDは60%、コインEは70%、の確率で表がでます
  4. どのコインがどの確率なのかはわかりません
  5. 5つのコインから1つだけを選んで投げる、という行動を10000回繰り返します
  6. 目的は、この10000回の中でできるだけ表を多く出したい
  7. さて、どういった戦略をとれば表を多く出せるでしょう?

10000回の試行回数の中でどれが一番表が出やすいコインを手探りで確かめなければならない、かつ、できるだけ早く見つける。

こういった状況をバンディット問題と呼びます。

(n本腕というのは選択肢の数で、今回は5つのコイン、つまり、5つの選択肢があるので5本腕バンディット問題ということになります)

そして、この手探りの効率の良さをより求めたものがバンディットアルゴリズムとして提唱されています。


さて、そろそろ戦略について考えてみましょう。


では、まずギャンブラー的戦略をとってみましょう。

ギャンブラー的戦略:5つのうちどれかを選び、それを10000回投げ続ける。コインEを偶然選ぶことができればラッキー、コインAに当たれば悲劇。


次にみんな平等、ゆとり教育的戦略をとりましょう。

ゆとり教育的戦略:みんな平等、5つとも2000回づつ投げましょう。表が出る期待値は、当然5枚のコインの期待値の平均。


次は、ちょっと頭をひねった戦略をとります。

最初の5000回は5枚とも均等にコインを投げます。

5000回投げ終わった時点で、それぞれのコインの表が出た回数を計算し、その中で一番表が出た回数が多かったものを残りの5000回投げましょう、という戦略。

実はこれはグリーディ手法と呼ばれる戦略です。

最初の5000回の中から期待値の高いものを貪欲に(Greedy)選ぶことからグリーディ手法と呼ばれています。


さて、先ほどのグリーディ手法ですが、最初に5000回は投げ過ぎじゃないですか?

もうちょっと減らしても、コインEは見つけれるんじゃないか?

1000回、いいや、100回、いやいや、20回!


20回まで減らして、もし20回の中でコインEを見つけることができれば、残りの9880回はコインEを投げれるわけです。

しかし、心配な点もあります。

それは20回の中で、たまたまコインDの表が出る回数が多くて、残りの9880回にコインDを選んでしまうケース。

悲劇ですね。

しかし、あくまでもコインの表が出るのは確率なので、十二分に考えられます。

コインEを見つけるための試行回数を減らしすぎると、こういった悲劇(不確実性)が起こりやすくなります。


ちなみにバンディット問題では。

このコインEを見つけるための行動を探索と言います。

そして、コインEの表が出る確率が高いということを見出し、コインEを投げることを知識の利用と言います。(試行回数をこなすことで得た知識を利用)


探索と知識の利用はトレードオフの関係にあり、探索をしすぎても最終的な報酬(表が出る回数)は減り、知識の利用を早い段階からしすぎても不確実性が増すことになります。

バンディットアルゴリズムでは、探索と知識の利用のバランシングの効率の良さを追求しています。

このバランスは、どこが最適かとかは扱う問題によって異なるので、最適を求めるのは難易度高めです。

今回のようなコイン投げだと、確率論的に求めることはできますが、こんな単純な問題は現実には存在しません。

この記事で扱う内容も、バランシングの最適化はまったく行っていません。(無理なので)


と、n本腕バンディット問題についてざっと説明が終わったところで、最後にもうひとつだけ戦略を上げておきます。(本命)

今回、検証で使用するものです。

ε-グリーディ手法と言って、グリーディ手法のデメリットをちょっと改善したものです。

コインEを見つけるために、最初の20回はどのコインも均等に投げるとします。

ここまではグリーディ手法と同じです。

グリーディ手法だと、残りの9880回は20回の中での表が出た回数が多かったコインをひたすら投げ続けますが、ε-グリーディ手法は、残りの9880回の中でもたまに他のコインを投げます。

もし、誤った選択をしていても、たまに他のコインを投げ、その都度表が出る期待値を計算し直すので、どこかでコインEにたどり着くことができるでしょう。

探索をある一定の確率で行い続けるのが、ε-グリーディ手法です。

ε-グリーディ手法では、このように不確実性を減らしていき、かつ最終的な報酬も求めていきます。

検証方法

相場をn本腕バンディット問題に見立てながら、検証を行っていきます。

先ほどは5つのコインでしたが、相場なので5つの銘柄です。


対象銘柄

証券コード ETF リターン
1545 (NEXT FUNDS)NASDAQ-100(R)連動型上場投信 -0.0061
1525 国際のETF VIX短期先物指数 0.035
1671 WTI原油価格連動型上場投信 0.010
1681 上場インデックスファンド海外新興国株式 0.0004
1698 上場インデックスファンド日本高配当 -0.0035

リターンは、2013年から2016年まで、10営業日保有して売却するという行動を行い、それらの平均リターンを示しています。

どの銘柄がどの平均リターンかはわからないものとします。

だいたい、リターンがバラけるように選びました。


2013年から2016年までの合計取引回数は全部で89回です。

目的は、この89回の試行回数でより平均リターン高めることです。

つまり、ε-グリーディ手法によってできるだけ少ない試行回数で、一番リターンの高い国際のETF VIX短期先物指数(1525)を見つけることができれば良いということになります。

結果

f:id:doz13189:20170224204715p:plain

平均リターンは、0.0129となりました。

国際のETF VIX短期先物指数(1525)の0.035には及ばないものの、ちゃんと1525を選べているようです。

探索と知識利用のバランスは、はじめの20回をランダムに取引し(探索)、その後は知識の利用にしています。

f:id:doz13189:20170224204933p:plain

これは試行回数ごとに選択した銘柄をプロットしています。

1525が一番多く選択されていることがわかります。

たまに他の銘柄も選択しているのがε-グリーディ手法の特徴とも言えます。


ちなみにグリーディ手法で行った際のシミュレーションも見てみましょう。

f:id:doz13189:20170225054809p:plain

平均リターンは0.020でした。

今回に限っては、ε-グリーディ手法より上を行きました。

それだけε-グリーディ手法に無駄な探索が多かったと言えます。

f:id:doz13189:20170225054835p:plain

試行回数ごとに選択した銘柄をプロットしたものを見ると、1525を選んでいることがわかります。


ここまでは、ε-グリーディ手法orグリーディ手法が上手くいったパターンでした。

次に上手く探索できず国際のETF VIX短期先物指数(1525)を見つけれなかったパターンを見てみます。

f:id:doz13189:20170224205357p:plain

平均リターンは、0.0049となりました。

国際のETF VIX短期先物指数(1525)の0.035には遠く及びません。

それもそのはず選択した銘柄を見てみると...

f:id:doz13189:20170224205512p:plain

最初はWTI原油価格連動型上場投信(1671)のリターンが高いと評価しており、途中から上場インデックスファンド海外新興国株式(1681)に乗り換えています。

残念、どっちもはずれです。


こういったこともあるので、探索と知識の利用のバランシングは慎重に行わなければいけません。

強化学習のアルゴリズムは全般的に学習までの期間にかなりの時間を要します。

試行回数89回程度ではなかなか最適な解は見つかりにくく、ある程度の不確実性は許容するしかありません。

しかし、相場の歴史は長いです。

いくらでもさかのぼって探索の期間をたっぷり取ればいいか、というとまたそうでもありません。

今回のシミュレーションの問題点

一言で言うと、相場は非定常環境であるにも関わらず、定常環境を想定したシミュレーションを行っている、ということです。

コインの表は出る確率は一定ですが(定常環境)、リターンは時間と共に平均が変化していきます(非定常環境)。

これの何がまずいかというと...

2013年から2016年の平均リターンをとったら-0.01でも、2013年から2014年というある期間をとったら+0.05かもしれない。

ということは、ε-グリーディ手法は2013年から2014年の間を探索期間として設けていると高確率で誤った知識を得ることになります。

いや、そもそも誤った知識でもありませんね。

ただ、その知識を2014年、2015年と利用していても良い結果は得ることはできません。

今回のシミュレーションで言うと、2013年〜2016年は高いリターンを示していた国際のETF VIX短期先物指数(1525)を2017年以降も買い続けていれば高いリターンを期待できるかというとそうではない、ということです、当たり前ですね笑


これを解決するには、古い知識の価値をあまり評価せず、新しい知識を評価するということが上がられます。

これを今回のシミュレーションに置き換えると、時間軸をもとにリターンを加重平均すると非定常環境に対応することができるということになります。


このように相場に合わせていくと、強化学習を使ったトレンドフォロー型のアルゴリズムができます。

(今回のシミュレーションもリターンの高いものを積極的に選ぶトレンドフォロー型)

ちなみに強化学習を使った株取引で15%の超過リターンを達成したで〜っていう論文もあります。

http://sigfin.org/?plugin=attach&refer=SIG-FIN-011-04&openfile=SIG-FIN-011-04.pdf


工夫次第で取引戦略に組み込めそうですね!!!


〜更新〜

非定常環境に対応させたバージョン

直近のリターンが高いものを高く評価した場合のシミュレーション

f:id:doz13189:20170225080339p:plain

平均リターンは0.0260となかなかの数値。

何回かシミュレーションを繰り返しましたが、比較的高い数値を出しました。


f:id:doz13189:20170225080500p:plain

試行回数ごとに選択した銘柄をプロットしたものを見ても、適度に他の銘柄を選んでいることがわかります。

以上でした。

勝機はリスク管理と分散投資にあり!?コツコツドカンはもう嫌だ!

目次

的中率は悪くないのになぜ?

最近はもっぱら機械学習での株価予測にいそしんでいます。

n日後の株価が上昇or下落を予測する2値分類モデルなのですが、ここ一ヶ月はモデルの構築よりシミュレーションに重きをおいています。

もう星の数ほどのシミュレーションをやってきたのですが、そのシミュレーションの中でたびたび理不尽なことが起こります。

それは...

株価予測の精度はそこまで悪くないのに、利益でねぇ、ってことです。

株価の予測精度は時期によってけっこうブレがあって、いい時期はだいたい55%〜60%ほどなんですが、そういった時期でも期待するほどの収益を上げることができません。

というか予測精度は55%ほどあるにも関わらず、収益のトータルがマイナスのことがあります。

これは理不尽ですね。

なぜ合理的な株式市場でこのような理不尽な出来事が起こるのでしょうか?

正体はコツコツドカン

また君か。

君はいったいどこから湧いてくるんだ。

コツコツドカンを撲滅するために

利益を上げるには、どうやら予測の精度をこれ以上あげるより、もっとやるべきことがあるようです。

それはリスク管理分散投資です。

実世界での私は元手が少ないので分散投資リスク管理もできませんが、シミュレーションの中ではお金の量は自由に増減可能です。

実世界での私は貧乏なので、自分には縁のないことだと思いこれまでリスク管理分散投資はあまり勉強してきませんでした。

というか、それって長期投資する人のためのものでしょくらいにしか思ってなかったのですが、どうやら違ったようです。


今回は、リスク管理分散投資の効果について売買シミュレーションを行い検証してみたのでその結果を記事にしました。

シミュレーションについての説明

売買戦略

機械学習で騰落を予測し、予測が上昇であれば買い、下落であれば売りのポジションを取り、10日間保有して売却します。

リスク管理の方法

現代ポートフォリオ理論に基づき、ポートフォリオに組み込む銘柄同士の相関を計算し、リスク(標準偏差)が最小になるようにポートフォリオを最適化しました。

分散投資の方法

今回は分散投資と言っても、債権、オルタナティブ、株式など金融商品の種類ごとに分けるものではありません。

あくまでも株式の中で分散させるだけで、ポートフォリオに同じ業種の銘柄ができるだけ入らないようにするというものです。

業種の判断には証券コードを使用しました。

検証方法

いくつの銘柄に分散させるか、によって分類し、それぞれで売買シミュレーションを行いました。

パターンA 1つの銘柄を購入(リスク管理なし)

パターンB 2つの銘柄を購入(リスク管理あり)

パターンC 4つの銘柄を購入(リスク管理あり)

パターンD 6つの銘柄を購入(リスク管理あり)


パターンAは銘柄が1つなので、リスク管理のしようがありませんので、リスク管理なしです。

そして、どのパターンも購入する合計の株数は1000株です。

パターンAであれば、一つの銘柄を1000株購入することになります。

パターンBであれば、500株と500株だったり、300株と700株など銘柄同士の相関係数によって比率を変えながら合計1000株購入します。

パターンC,Dまでなると、合計1000株だとキレイに分割できず、140株購入など現実にはできない買い方をしてしまっています...

プログラムの仕様を合計1000株ではなくて、合計1000万円にしていたら良かったのですが、途中で仕様を変えるのも面倒だったのでこれで押し切りました。


また、購入する銘柄は予測結果の中からランダムに選んでいます。

f:id:doz13189:20170220221907p:plain

このような形で予測結果は出力されるので、パターンAであればここから1つ銘柄を選び、パターンDであれば、ここから6つ銘柄を選びます。

検証期間

2014年から2016年までの3年間です。

取引は、2014年から20営業日ごとに2016年まで行い、合計39回の取引を行っています。

シミュレーション結果発表

パターンA 1つの銘柄を購入(リスク管理なし)

20営業日ごとに1つの銘柄を1000株買い、10日間保有して、売却するということを3年間続けた結果です。

銘柄の選定をランダムで行っているため、運要素が強いです。

そのため、同じ戦略を10回繰り返し行っています。

f:id:doz13189:20170220222432p:plain

ベストパフォーマンスが最終利益、プラス200万。

ワーストパフォーマンスの最終利益は、マイナス300万。

一回の取引で必要なのは、だいたい600万ほどです。

リスク管理なし、分散投資なしではいくら予測精度が高くてもなかなか利益に結びつきにくいわけですね...

パッと見、ランダムウォークのようですね。

10回の取引のうち6回がプラス、4回がマイナスという結果です。

パターンB 2つの銘柄を購入(リスク管理あり)

シミュレーション方法は同じです。

f:id:doz13189:20170220223319p:plain

ベストパフォーマンスが最終利益、プラス300万。

ワーストパフォーマンスの最終利益は、マイナス300万。


ベストパフォーマンスの最終利益が100万円ほどアップしました。

最終的な利益も総じて、パターンAより良さそうです。

パターンC 4つの銘柄を購入(リスク管理あり)

f:id:doz13189:20170220224029p:plain

ベストパフォーマンスが最終利益、プラス500万。

ワーストパフォーマンスの最終利益は、マイナス200万。


ベストパフォーマンスは200万ほどアップし、ワーストパフォーマンスも200万まで下がりました。

順調にリスク管理分散投資の効果が現れてきたように思います。

パターンD 6つの銘柄を購入(リスク管理あり)

f:id:doz13189:20170220224457p:plain

ベストパフォーマンスが最終利益、プラス300万。

ワーストパフォーマンスの最終利益は、マイナス100万。


ベストパフォーマンスはまたプラス300万ほどに戻ってしまいましたが、ワーストパフォーマンスは100万まで下がりました。

そして、10回のシミュレーションのうち8回がプラス、2回がマイナスになりました。

パターンDまで来ると、平均リターンもそこそこありそうです。

目算だと10回のシミュレーションの平均はプラス100万円ほどでしょう。

スタートの取引額は600万円ほどなので、3年間でプラス10%ほどの期待リターンです。

まとめ

今回のシミュレーションでは、複利、マーケットインパクト、手数料等は考慮されていません。

実践を想定するなら、もう少し洗練されたシミュレーションを行う必要があると思いますが、リスク管理分散投資の重要性という観点に注目するとなかなか興味深い結果だったと思います。


そして、このシミュレーションは10日間保有して売却するだけの戦略であり、長期投資ではありません。

ですが、リスク管理分散投資は確かに効果を発揮しました。

パターンAとパターンDを見比べれば、結果は歴然です。



今回得た知識をこれからの投資ライフに生かしていきたいです。

まだまだ素人の域を抜けれそうにないです...

最強の銘柄を決めようではないか

目次

最強の銘柄はどれだ?

粉飾決算発覚、トランプツイート砲、突如現れる空売り勢、常に起こる株式市場での混乱。

これらの横風を受けながらも直近の4年間で素晴らしい成績を残した銘柄たちをランキング形式で届けます。

対象銘柄は東証1部でかつ1日の売買高が10億円以上ある大型株に絞っています。(だいたい350銘柄ほど)

最強の定義

荒ぶる株式市場で、リスクは最小に、かつリターンを最大にしたいと投資家たちは常々考えているはず...

ここでは、リスクが最小でかつ4年間の平均リターンがプラスの銘柄を最強と定義します。

リターンとリスクの求め方

今回は、過去4年間での株価変動を対象にしています。

リターンは2013年1月4日〜2017年1月31日の間の20営業日ごとの平均変動率です。

例)

2016年12月30日時点の終値が1000円、2017年1月31日時点の終値が1100円ならば、リターンは+10%となります。

このように20営業日ごとのリターンを2013年から2017年まで計算し、それらの平均値をリターンとします。

ちなみに日経平均株価の4年間の平均リターンは0.99%です。

ということは、日経平均株価と連動するETFを買って20営業日保有すると、買った価格からだいたい+0.99%になるということです。


リスクは標準偏差です。

2013年〜2017年まで20営業日ごとのリターンを求め、それらの標準偏差がリスクとなります。

例1)

f:id:doz13189:20170217061510p:plain

2013年から2017年までのほとんどの期間が上下0.1(10%)以内に収まっていることがわかります。

実際、この銘柄の標準偏差は6.62%です。

20営業日の間、いつも上下6.62%ほど株価は変動しているということになります。

例2)

f:id:doz13189:20170217061714p:plain

激しい時はプラス0.8(80%)ほどまで上がる期間も...

かなり値動きの激しい銘柄で、この銘柄の標準偏差は22.64%です。

20営業日あると、いつも上下22.64%ほど株価は変動しているということになります。

例1と比べるとかなりリスクの大きい銘柄ということになります。


ざっとリターンとリスクについて説明したところで、最強銘柄ランキングを発表することにします。

最強の銘柄はこれだ!

順位 コード 企業名 リターン リスク
1位 2811 カゴメ 1.33% 5.05%
2位 4508 田辺三菱制約 1.23%% 5.55%
3位 2875 東洋水産 1.27% 5.56%
4位 9532 大阪ガス 0.88% 5.61%
5位 9041 近鉄グループHD 0.15% 5.80%
6位 8304 青空銀行 0.65% 5.96%
7位 7911 凸版印刷 1.33% 5.99%
8位 9020 JR東 1.19% 6.06%
9位 2897 日清食品HD 1.20% 6.11%
10位 5012 東燃ゼネラル石油 1.10% 6.12%

安定感抜群の猛者たちでした。

デンジャラスな冒険銘柄

ひたすらリターンの大きさのみに注目した銘柄です。

順位 コード 企業名 リターン リスク
1位 5801 古河電気工業 21.49% 136.36%
2位 5401 新日鉄住金 18.45% 124.64%
3位 4631 DIC 18.05% 105.07%
4位 5406 神戸製鋼所 17.93% 119.8%
5位 5711 三菱マテリアル 17.86% 116.91%
6位 8309 三井トラストHD 16.95% 107.60%
7位 4004 昭和電工 16.90% 106.82%
8位 7211 三菱自動車工業 13.39% 92.41%
9位 2201 森永製菓 13.20% 67.35%
10位 1808 長谷工コーポレーション 11.19% 57.86%

算出してみたのですが、ちょっと感覚と異なる銘柄がズラリ。

調べてみるとほとんどの銘柄が、ある期間に突出した暴騰があり平均を釣り上げているようです。

デンジャラスな冒険銘柄は上手く調べることはできませんでした...(妥協)

まとめ

いかがだったでしょうか。

簡単な計算でリターンとリスクは求めることができます。

リスクの管理をしっかりとしていきたいですね。

Pythonで機械学習を使った株価予測のコードを書こう

目次

はじめに

プログラミングを始めたばかりの人、機械学習を使って株価を分析してみたい人、このような人たちのために記事にしました。
少しでも助けとなれば私はうれしいです。

全てを読めば、株価を予測するためのコードを理解することができるよう心がけました。
理解することが大事なので、コードはシンプルにしてあります。

ひとつ注意点があります。
この記事を読むことで、株価を予測するためのコードは理解できるようになりますが、株価の予測はできません。
株価の予測は非常に難しいことであり、たくさんの工夫が必要です。
ただ、この記事は最初の一歩になると思います。
一歩さえ踏み出してしまえば、あとは各自で工夫していけるはずです。

ページの最後に本記事で使用したコードを掲載しています。

準備するもの

scikit-learn
pandas
ubuntu(OSは自由)
ネット回線

記事の流れ

  1. データ収集
  2. データの前処理
  3. モデルの学習
  4. 構築したモデルによる予測

予測手法

機械学習のランダムフォレストです。

ランダムフォレストは、調整が必要なパラメータが少なく過学習もしにくいため、機械学習の中でも扱いやすい部類に入ります。

かと言って、判別精度が悪いわけではないので非常に優秀な手法です。

ランダムフォレストについて詳しく知りたい方は以下の記事を参考にして下さい。

doz13189.hatenablog.com

データ収集

本記事で予測するのは、野村総合研究所(4307)の株価です。
以下のサイトで直近250日分のデータ(始値・高値・安値・終値出来高・売買代金)がダウンロードできます。
CSVと書かれている部分をクリックするだけです。

[4307 東証1部] 野村総合研究所 日足 時系列データ CSVダウンロード


次に説明変数となるデータを集めてきます。
野村総合研究所の株価を予測するには、野村総合研究所の株価データだけでは足りません。

では、何を集めてきたらいいでしょう?

まずは日経平均株価かな、次はTOPIX?あとドル円データも欲しいな…
あとは原油価格もあればうれしい、といろいろとあると思います。

あげだしたらきりがないし、正直それぞれ集めてくるの面倒くさいですね。
というか、こういうデータは自分で考えながら集めてくるものはありませんね。
集めれるだけデータを集めて、そこから説明変数として効果的なものを選びだすほうが効率が良いです。
少なくとも私はそうしています。

ということで、ここに載っているデータを適当に集めましょう。
ここにETF一覧が掲載されています。

stocks.finance.yahoo.co.jp

あれ?ETF??
私が探しているのは日経平均株価とか為替データで…

いいんです、ETFで。

ETFについて、とても軽く説明します。知っている方は読み飛ばして下さい。
ETFというのは、上場投資信託というもので、その名の通り投資信託が上場しているんです。
ヨーロッパ・アメリカでは有名な金融商品であり、最近は日本でも注目度が上がっている商品です。
投資信託と比べて色々とメリットはあるのですが、話が逸れそうなので詳しくは他のサイトに譲ります。

なぜ、ETFは説明変数候補として集めるかというと、指標と連動させている商品だからです。
例えば、日経225連動型上場投資信託
これは日経平均株価と連動するように運用されています。
そのため、日経平均株価を説明変数として組み込むのと、 日経225連動型上場投資信託を組み込むのは同じこと、になるんです。

ETFには様々な指標に連動させた商品があります。
上海株式、金、銀、原油、とうもろこしなどなど。
これらの指標は説明変数になりえます。

ということで、先ほどのETF一覧を見ながら、野村総合研究所の株価データをダウンロードしたサイトから集めてきましょう。

さすがに全部集めるのはしんどいので、適当に選びましょう。
ちなみに私は、

コード ETF
1309 上海株式指数・上証50連動型上場投資信託
1313 サムスンKODEX200証券上場指数投資信託
1314 上場インデックスファンドS&P日本新興株100
1322 上場インデックスファンド中国A株(パンダ)CSI300
1326 SPDRゴールド・シェア
1343 NEXT FUNDS 東証REIT指数連動型上場投信
1543 パラジウム上場信託(現物国内保管型)
1548 上場インデックスファンド中国H株(ハンセン中国企業株)
1549 上場インデックスファンドNifty50先物(インド株式)
1551 JASDAQ-TOP20上場投信
1633 NEXT FUNDS 不動産(TOPIX-17)上場投信
1673 ETFS 銀上場投資信託
1678 NEXT FUNDS インド株式指数・Nifty 50連動型上場投信
1681 上場インデックスファンド海外新興国株式(MSCIエマージング
1682 NEXT FUNDS 日経・東商取白金指数連動型上場投信
1698 上場インデックスファンド日本高配当(東証配当フォーカス100)

これらをダウンロードしました。

プラスアルファ
手動でデータを集めてくるのもいいですが、効率良く集めたいならスクレイピングがいいです。
現時点でスクレイピングがわからないという方は、「python スクレイピング]でググってみましょう。
思いの外スクレイピングが簡単にできることがわかると思います。
今回は、できるだけ記事をシンプルにしたいので余計な技術は使いません。

データが集まったらいよいよ前処理です。
前処理がおそらく一番難しくて、大変な作業です。
これさえ乗り切ってしまえばあとは楽勝です、がんばりましょう!

前処理

前処理ですること

  1. 野村総合研究所のデータと全てのETFのデータを統合して、ひとつの.csvにまとめる

まずは野村総合研究所の株価データを読み込んでみましょう。

import pandas as pd
df = pd.read_csv("code_4307.csv", header=0)
df.columns=["Date", "Open", "High", "Low", "Close", "Volume", "Trading Value"]
df["index"] = [i for i in range(len(df))]
print(df.head(10))

f:id:doz13189:20170209033100p:plain

人によっては、UnicodeDecodeErrorが出るかもしれません。
この原因は、ダウンロードしたcsvデータのcolumnsが日本語だからです。
csvデータの日付、始値、高値、安値、終値出来高の部分が文字化けしていると思うので、少し面倒ですがcsvデータからこれらを適当な英数字に修正しましょう。


さて、次のステップでETFのファイルを読み込み、それらを野村総合研究所の株価データと統合します。

そのために、まずETFのリストを作ります。
etf_listにダウンロードしたETFファイルのコードを入れましょう。

そして、ETFファイルの名前を「etf_1309.csv]にします。
ファイルの名前構成を「"etf_" + ETFコード + ".csv"」にすることで、ループ分を回した時にETFコードの部分を変えるだけで読み込むファイルを変えることができるようになります。

etf_list = [

1309,#上海株式指数・上証50連動型上場投資信託
1313,#サムスンKODEX200証券上場指数投資信託
1314,#上場インデックスファンドS&P日本新興株100
1322,#上場インデックスファンド中国A株(パンダ)CSI300
1326,#SPDRゴールド・シェア
1343,#NEXT FUNDS 東証REIT指数連動型上場投信
1543,#純パラジウム上場信託(現物国内保管型)
1548,#上場インデックスファンド中国H株(ハンセン中国企業株)
1551,#JASDAQ-TOP20上場投信
1633,#NEXT FUNDS 不動産(TOPIX-17)上場投信
1673,#ETFS 銀上場投資信託
1678,#NEXT FUNDS インド株式指数・Nifty 50連動型上場投信
1681,#上場インデックスファンド海外新興国株式(MSCIエマージング)
1682,#NEXT FUNDS 日経・東商取白金指数連動型上場投信
1698,#上場インデックスファンド日本高配当(東証配当フォーカス100)

]

さきほどの名前構成を変更したので、ループ分でetf_listに入っている全てのETFファイルを読み込むことができます。

for etf in etf_list:

	df_etf = pd.read_csv("etf_" + str(etf) + ".csv", header=0)
	df_etf.columns=["Date", "Open", "High", "Low", "Close", "Volume", "Trading Value"]


読み込むことができたら、次はETFファイルと野村総合研究所のデータを統合します。

統合する際に少し工夫が必要です。
ETFファイルは中身を見て頂ければわかると思いますが、穴ボコです。
NaNデータが多く、野村総合研究所のデータとそのまま統合すると、データの長さが異なるためズレて統合されてしまいます。

そのため、以下のコードでは野村総合研究所の日付をループ分で順番に取り出しながら、ETFファイルの日付に検索をかけます。
そして、日付が一致した日のETFのCloseデータを取り出します。
もし、そのCloseデータがNaNであった場合は前日のデータを代わりに入れています。

for etf in etf_list:

	df_etf = pd.read_csv("etf_" + str(etf) + ".csv", header=0)#データ読み込み
	df_etf.columns=["Date", "Open", "High", "Low", "Close", "Volume", "Trading Value"]#columns名を変更

	dates = []
	closeis = []
	for d in df["Date"]:
		date = df_etf.loc[(df_etf.Date == d), "Date"]#野村総合研究所の日付をETFファイルから検索
		yesterday_date = date.values[0]
		dates.append(date.values[0])#日付をデータセットに追加

		close = df_etf.loc[(df_etf.Date == d), "Close"]#日付が一致した日のETFのCloseのデータを取り出す
		if str(close.values[0]) != str("nan"):#取り出したCloseがnanでないかを判断
			yesterday_close = close.values[0]
			closeis.append(close.values[0])	

		else:
			closeis.append(yesterday_close)
		
	df_etf2 = pd.DataFrame({"Date_" + str(etf) : dates, "Close_" + str(etf) : closeis})#新しくデータフレームを作成
	df = pd.concat([df, df_etf2], axis=1)#野村総合研究所のデータとETFデータを統合

ETFデータは、Closeしか必要はありません。
しかし、プログラムでは日付データも一緒に追加しています。
これは、統合した後に目視で確認しやすいようにです。(出来上がったデータを見てもらえば、確認のしやすさがわかります)

よくデータ同士の統合で、データが一段ずれるなどのトラブルが起こります。
これはこういったトラブルを防ぐためのちょっとした工夫です。


さて、無事統合できました。
しかし、このETFデータにもうひと工夫する必要があります。

ETFのデータを階差系列に変更する必要があります。
このステップは非常に重要で、ETFの価格自体を説明変数として使っても、野村総合研究所の株価データは説明することはできません。
そのため、前日比などに変更する必要があります。

このコードをfor文の中に入れてやる必要があります。

df["diff_" + str(etf)] = (df["Close_" + str(etf)] / df["Close_" + str(etf)].shift(-1)) - 1

これで前処理は終了したので、新しくできたデータフレームをcode_4307_plus.csvとして保存します。

df.to_csv("code_4307_plus.csv")

モデルの学習

ここで新しくファイルを作成しましょう。

いよいよ機械学習で株価を予測します。

構築するモデルは、過去249日を学習して、250日目を予測するというものです。

import pandas as pd
from sklearn.ensemble import RandomForestClassifier


ETFデータを統合した野村総合研究所の株価データを表示しましょう。

df = pd.read_csv("code_4307_plus.csv")
df = df.sort_values(by=["index"], ascending=False)
print(df.tail(20))

ETFデータが全て統合されたデータが表示されたはずです。

このデータをテストデータとトレーニングデータにわけます。

df_train = df.iloc[1:len(df)-1]
#はじまりを[1:]としているのは、階差系列をとっているため[1]がNaNデータだからです。
#学習データにNaNデータがあると、エラーがでます。

df_test = df.iloc[len(df)-1:len(df)]
#テストデータには、一番最新のデータを入れます。

説明変数として使用するものをリストにしておきます。

xlist = [

"diff_1309",#上海株式指数・上証50連動型上場投資信託
"diff_1313",#サムスンKODEX200証券上場指数投資信託
"diff_1314",#上場インデックスファンドS&P日本新興株100
"diff_1322",#上場インデックスファンド中国A株(パンダ)CSI300
"diff_1326",#SPDRゴールド・シェア
"diff_1343",#NEXT FUNDS 東証REIT指数連動型上場投信
"diff_1543",#純パラジウム上場信託(現物国内保管型)
"diff_1548",#上場インデックスファンド中国H株(ハンセン中国企業株)
"diff_1551",#JASDAQ-TOP20上場投信
"diff_1633",#NEXT FUNDS 不動産(TOPIX-17)上場投信
"diff_1673",#ETFS 銀上場投資信託
"diff_1678",#NEXT FUNDS インド株式指数・Nifty 50連動型上場投信
"diff_1681",#上場インデックスファンド海外新興国株式(MSCIエマージング)
"diff_1682",#NEXT FUNDS 日経・東商取白金指数連動型上場投信
"diff_1698",#上場インデックスファンド日本高配当(東証配当フォーカス100)

]


ここで学習用のデータを作ります。
学習データの作り方は、x日のデータ(ETFの前日比)を説明変数に、x+1日の騰落を目的変数に入れます。
x+1日の株価が上昇していれば、+1を入れ、下落していれば-1を入れます。

x_train = []
y_train = []
for s in range(0, len(df_train) - 1):
	#print(df_train["Date"].iloc[s], df_train["Date"].iloc[s + 1])
	#print(df_train["Close"].iloc[s], df_train["Close"].iloc[s + 1])

	x_train.append(df_train[xlist].iloc[s])

	if df_train["Close"].iloc[s + 1] > df_train["Close"].iloc[s]:
		y_train.append(1)
	else:
		y_train.append(-1)

#print(x_train)
#print(y_train)

rf = RandomForestClassifier(n_estimators=len(x_train), random_state=0)
rf.fit(x_train, y_train)

n_estimatorsは、ランダムフォレストを構築するために生成する決定木の数です。
基本的には、データ数と同じにすれば大丈夫です。

コメントアウトしてあるprint文を表示してもらえば、一日づつズレて入っていることが解ると思います。

f:id:doz13189:20170209192840p:plain


では、最後に構築したモデルを使用して、株価を予測してみましょう。

データの中で一番最新のもの、つまり、2月7日のETFデータをtest_xとしていれます。

test_x = df_test[xlist].iloc[0]
test_y = rf.predict(test_x.reshape(1, -1))


f:id:doz13189:20170209204500p:plain

マイナス1が出たということは、2/8の株価は下落ということですね。

2月8日の株価を見てみましょう。

f:id:doz13189:20170209204350p:plain

下落しているので、予測は当たっていることになります。


以上で予測は終わりです。

もし、興味が湧いたという方がいればこのコードを少し修正して、他の日もシミュレーションをしてみると良い練習になると思います。

きっと散々な結果がでると思います。

もう一段ステップアップするには何をしたらいい?

ちょっと物足りないという人は他にも色々と試せることはあります。

  • 他の手法を試す
  • 数値を指数平滑化する
  • 過去249日で1日後を予測しているが、これが最適か考える
  • テクニカル指標など他の説明変数を試してみる

まとめ

とても簡単でしたね。

今は色々なパッケージがあるので、機械学習は簡単に扱うことができます。

案外簡単だったと思うので、この記事を機会に色々と勉強してみると面白いと思います。

今回使ったコード

ベタ打ちですみません。
ファイルは2つあります。

野村総合研究所のデータとETFデータを統合するためのファイル

import pandas as pd


df = pd.read_csv("code_4307.csv", header=0)
df.columns=["Date", "Open", "High", "Low", "Close", "Volume", "Trading Value"]
df["index"] = [i for i in range(len(df))]
print(df.head(20))

etf_list = [

		1309,#上海株式指数・上証50連動型上場投資信託

		1313,#サムスンKODEX200証券上場指数投資信託

		1314,#上場インデックスファンドS&P日本新興株100

		1322,#上場インデックスファンド中国A株(パンダ)CSI300

		1326,#SPDRゴールド・シェア

		1343,#NEXT FUNDS 東証REIT指数連動型上場投信

		1543,#純パラジウム上場信託(現物国内保管型)

		1548,#上場インデックスファンド中国H株(ハンセン中国企業株)

		#1549,#上場インデックスファンドNifty50先物(インド株式)

		1551,#JASDAQ-TOP20上場投信

		1633,#NEXT FUNDS 不動産(TOPIX-17)上場投信

		#1649,

		1673,#ETFS 銀上場投資信託

		1678,#NEXT FUNDS インド株式指数・Nifty 50連動型上場投信

		1681,#上場インデックスファンド海外新興国株式(MSCIエマージング)

		1682,#NEXT FUNDS 日経・東商取白金指数連動型上場投信

		1698,#上場インデックスファンド日本高配当(東証配当フォーカス100)

		]

for etf in etf_list:
	#print(etf)
	df_etf = pd.read_csv("etf_" + str(etf) + ".csv", header=0)
	df_etf.columns=["Date", "Open", "High", "Low", "Close", "Volume", "Trading Value"]

	dates = []
	closeis = []
	for d in df["Date"]:
		#try:
		date = df_etf.loc[(df_etf.Date == d), "Date"]
		yesterday_date = date.values[0]
		dates.append(date.values[0])

		close = df_etf.loc[(df_etf.Date == d), "Close"]
		if str(close.values[0]) != str("nan"):
			yesterday_close = close.values[0]
			closeis.append(close.values[0])	

		else:
			#print("nan")
			closeis.append(yesterday_close)
		
	df_etf2 = pd.DataFrame({"Date_" + str(etf) : dates,
							"Close_" + str(etf) : closeis})

	df = pd.concat([df, df_etf2], axis=1)
	df["diff_" + str(etf)] = (df["Close_" + str(etf)] / df["Close_" + str(etf)].shift(-1)) - 1
	#print(df)

df.to_csv("code_4307_plus.csv")


機械学習を行うためのファイル

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

df = pd.read_csv("code_4307_plus.csv")
df = df.sort_values(by=["index"], ascending=False)
print(df.tail(20))


df = df.iloc[0:len(df) - 1]
print(df.tail())

df_train = df.iloc[1:len(df)-1]
df_test = df.iloc[len(df)-1:len(df)]

#print("train", df_train)
#print("test", df_test)

xlist = [

		"diff_1309",#上海株式指数・上証50連動型上場投資信託

		"diff_1313",#サムスンKODEX200証券上場指数投資信託

		"diff_1314",#上場インデックスファンドS&P日本新興株100

		"diff_1322",#上場インデックスファンド中国A株(パンダ)CSI300

		"diff_1326",#SPDRゴールド・シェア

		"diff_1343",#NEXT FUNDS 東証REIT指数連動型上場投信

		"diff_1543",#純パラジウム上場信託(現物国内保管型)

		"diff_1548",#上場インデックスファンド中国H株(ハンセン中国企業株)

		"diff_1551",#JASDAQ-TOP20上場投信

		"diff_1633",#NEXT FUNDS 不動産(TOPIX-17)上場投信

		"diff_1673",#ETFS 銀上場投資信託

		"diff_1678",#NEXT FUNDS インド株式指数・Nifty 50連動型上場投信

		"diff_1681",#上場インデックスファンド海外新興国株式(MSCIエマージング)

		"diff_1682",#NEXT FUNDS 日経・東商取白金指数連動型上場投信

		"diff_1698",#上場インデックスファンド日本高配当(東証配当フォーカス100)

		]


x_train = []
y_train = []
for s in range(0, len(df_train) - 1):
	print("x_train : ", df_train["Date"].iloc[s])
	print("y_train : ", df_train["Date"].iloc[s + 1])
	print("")
	x_train.append(df_train[xlist].iloc[s])

	if df_train["Close"].iloc[s + 1] > df_train["Close"].iloc[s]:
		y_train.append(1)
	else:
		y_train.append(-1)

#print(x_train)
#print(y_train)

rf = RandomForestClassifier(n_estimators=len(x_train), random_state=0)
rf.fit(x_train, y_train)


test_x = df_test[xlist].iloc[0]
test_y = rf.predict(test_x.reshape(1, -1))

print("result : ", test_y[0])

クラウドファンディングの成功率ってどのくらい?徹底調査してみた

目次

クラウドファンディングとは?

クラウドファンディング(英語:Crowdfunding)とは、不特定多数の人が通常インターネット経由で他の人々や組織に財源の提供や協力などを行うことを指す、群衆(crowd)と資金調達(funding)を組み合わせた造語である。 ソーシャルファンディングとも呼ばれる。

近年多くの注目を集めており、大きな資本を持っていなくてもアイデアや技術を売りに資金を募ることができます。

個人やベンチャーからすると、大きな参入障壁である「資金」という壁を取っ払うことができる革新的なサービスです。

キングコング西野さんの絵本や堀江さんのロケットなどはマスコミ含め大きな話題を読んでおり(炎上も含め)、かくいう私自身もクラウドファンディングを利用しています。

私が立ち上げているのプロジェクトはこちら!
camp-fire.jp

年々支援額は伸びており、今後が非常に楽しみな分野であります。

日本の有名ドコロは?

camp-fire.jp

現在、日本のクラウドファンディング業界のトップを走るのがCAMPFIREです。

なんと言っても圧倒的な手数料の低さ。引くほど低い。

シェアを見ても、52%と2位に倍の差をつけていますね。(2017年1月時点)

もうすでにニッチ戦略に走っている他のクラウドファンディングサイトもあり、業界内の勝負は決まったかな、と思えるほどの独走ぶりです。

クラウドファンディングはじめるならCAMPFIRE、と言える状況ではありますが、それでもクラウドファンディングをはじめてさらに他人から資金を援助してもらおうと思うと苦労は多いです。

ということでCAMPFIREを徹底調査し、

どんなプロジェクトにどのくらいお金が集まっているかを調査します!

調査方法は、CAMPFIREのサイトに掲載されている全てのプロジェクトの支援総額と支援者人数を集計し、それらをカテゴリごとに平均、一人あたりの平均支援額などを計算しました。

注意点として、CAMPFIREのサイトに掲載されており、かつSUCCESSしているプロジェクトが対象という点です。

※支援額がプロジェクトの目標金額に達することをCAMPFIREではSUCCESSと言う


プロジェクトは立ち上げても、必ずCAMPFIREのサイトに掲載されるわけではありません。

注目度や内容を加味して、CAMPFIREの運営者がサイトに掲載するかどうかを決定するみたいです。

そのため、掲載されているものは人気なものが多いです。

人知れず、目標金額に届かずに消えていくプロジェクトは多数あるとは思いますが、それらはなかなか調べることはできません。(CAMPFIREにはデータとして蓄積されているでしょうが...)

調査結果

CAMPFIREにはカテゴリが存在します。

プロジェクトがどのカテゴリに属するかを表しています。

カテゴリ一覧
アート、音楽、演劇・ダンス、プロダクト、テクノロジー、ゲーム、ジャーナリズム、コミュニティ、フード、写真、ファッション、映画・映像、本・漫画、アニメ、パフォーマンス、スポーツ、ビジネス、お笑い・ネタ、ソーシャルグッド


支援総額が大きいプロジェクトランキングTOP10

順位 カテゴリ 支援総額 支援者人数
1 アート 46,373,152円 6257人
2 プロダクト 30,455,500円 1250人
3 コミュニティ 27,040,400円 141人
4 スポーツ 20,209,000円 473人
5 プロダクト 15,043,000円 244人
6 ミュージック 14,826,200円 693人
7 ビジネス 13,646,000円 254人
8 ミュージック 11,855,553円 754人
9 プロダクト 10,611,600円 269人
10 ソーシャルグッド 10,007,091円 2,974人

一位はなんと5000万近く集めているようです。驚愕。

トップ10は一本超えのモンスター級ばかりが並んでいますね。



平均支援額・平均支援者人数

プロジェクト一本あたりの平均支援額、平均支援者人数を見てみましょう

平均支援額 平均支援者人数
1,051,861円 99人

ひとつのプロジェクトを立ち上げた時、平均で100万円くらい集まり、平均して100人くらいの人が支援をしてくれることになります。

これはあくまでも平均です。

キンコン西野さんや堀江さんなどの化物プロジェクトが平均を大きく釣り上げています。


気になるプロジェクト成功率

一体クラウドファンディングを立ち上げた際の成功率はどのくらいなのでしょうか?

しかし、プロジェクト成功率は公表されていません。

そのため、プロジェクト成功率は私自身の予測であり、正式な数値ではありません。

ただ、けっこうな妥当な数値かなぁ、と思います。


サイトに掲載されており、SUCCESSしているプロジェクトは1117件でした。

そして、CAMPFIREがいかにすごいかを自慢しているページに、「19カテゴリで4200件以上」のプロジェクトが立ち上がっていることが書かれています。

camp-fire.jp

この4200件という数値はおそらく成功or失敗に関わらない全てのプロジェクト数だと思われます。

ということは。

SUCCESSプロジェクト数1117件 ÷ 全プロジェクト数4200件 = 26%

プロジェクトの成功率は26%ということになります。


予想より高いですね...

ただ、気をつけたいのはCAMPFIREではプロジェクトを立ち上げる前に、プロジェクトの審査があります。

審査に通過したものでないと、プロジェクトとして立ち上がりません。

もし、この成功率があっていたなら、審査を通過してもなお、4分の1しかプロジェクトは成功しないことになります。


支援額を可視化

f:id:doz13189:20170125211828p:plain

これは、横軸に支援額、縦軸にプロジェクト数をとったグラフです。

可視化する際に、支援額の大きいプロジェクトの上位20位くらいを省いています。

でないと、1番支援されているものは5000万ほどだったので支援額の小さいものがグラフで目視できないレベルに押し込められてしまいます。


100万円以下がかなり盛り上がっていることがわかります。

大きなプロジェクトを除けば、だいたい平均支援額は60〜80万くらいになりそうです。


支援者の人数を可視化

f:id:doz13189:20170125212704p:plain

縦軸にプロジェクト数、横軸に支援者数をとっています。

こちらも100人以下が盛り上がっており、支援者は40人程度のプロジェクトが一番多いようですね。

グラフの横軸にpatronと書いてあるのは、CAMPFIREでは支援者のことをパトロンと呼ぶからです。


支援者と支援額の関係を可視化

f:id:doz13189:20170125212939p:plain

縦軸に支援者数、横軸に支援額をとっています。

散布図は右に流れていっていますね。

このことから、だいたい支援者数100人くらいからは伸びづらくなっていることがわかると思います。

なので、支援額が大きいプロジェクトを立ち上げる際は、支援者を増やすというよりかは、一人あたりの支援額を伸ばすことを意識した方が良いということが言えますね。


カテゴリごとの平均支援額

f:id:doz13189:20170125213720p:plain

画像小さくてすみません、右からアート、音楽、演劇・ダンス、プロダクト、テクノロジー、ゲーム、ジャーナリズム、コミュニティ、フード、写真、ファッション、映画・映像、本・漫画、アニメ、パフォーマンス、スポーツ、ビジネス、お笑い・ネタ、ソーシャルグッド、です。

ダントツの一位は平均160万円のアニメでした。

パフォーマンスは平均30万ほどで、最下位でした。

この数値は、良く支援されているか否かを表すものではありません。

「アニメ」は制作にそれだけコストがかかるため平均支援額が大きく、「パフォーマンス」は比較的安価であるということを意味しています。


もし、これからクラウドファンディングをはじめる方がいればこの数値は大いに参考になるはずです。

例えば、アニメを作ろうとした時、目標金額を200万にすると他のプロジェクトよりもかなり高くなります。

そんなにアニメ作るのにお金いるの?と支援者が疑問に思ってしまうと支援はなかなかもらえません。

もし、無難に支援を集めたいなら平均を大きく超える目標金額の設定は控えたほうが良いと思います。


もちろん、プロジェクトによって必要な支援が額はまちまちなので、あまり平均にとらわれる必要はありませんが。


カテゴリごとのプロジェクト数

f:id:doz13189:20170125214722p:plain

これはカテゴリごとのプロジェクト数を可視化しており、どのカテゴリでのプロジェクト立ち上げが多いかがわかります。

音楽は200件、ソーシャルグッドは150件と多いです。

コミュニティも100件ほどありますね、地方創生が活発であることが見てとれます。


アニメ、テクノロジー、コメディが10件程度と少ないですね。

この2つのプロジェクトは成功率が低いから成功数も低いのか、はたまた、異なるクラウドファンディングサイトでのプロジェクト立ち上げが多いのか。

もし、後者であればCAMPFIRE運営の課題でもありますね。

たしか、アニメ専門のクラウドファンディングがあったと思うので、もしかしたらそちらに流れているのかも。


この可視化で、どのカテゴリが盛り上がっているかがわかりますね。

プロジェクトの成功率は、このプロジェクト本数とある程度比例するんじゃあないでしょうか。

支援する人は自分の好きなカテゴリを選ぶことが多いので、CAMPFIREではミュージックに関心がある支援者が多い、ともとれます。


カテゴリごとの一人あたり支援額

f:id:doz13189:20170125215650p:plain

だいたい1万円くらいが平均みたいです。

アニメを除けば、ほかはあまりカテゴリごとに偏りはなさそうですね。

以上が集計結果でした

資金のない個人、ベンチャーからするとクラウドファンディングは夢を叶えるチャンスを大きく広げるサービスです。

ただ、多くのプロジェクトを見ると、立ち上げている本人のワクワクは伝わってくるものの、大切な資金の使い道やなぜ必要なのか、プロジェクトの魅力が十分に伝わっていないものも散見されます。

人から支援を受けるには、ワクワクだけでは足りないのが事実です。


私も立ち上げた経験があるので、とてもワクワクする気持ちはわかります。本当にワクワクします。プロジェクトを友達に告知するのが楽しくて楽しくて仕方がありません。

ワクワクは悪くはないのですが、少し冷静になって分析することは大切かなぁ、なんて思います。

そういった時に、どのくらいの規模のプロジェクトが成功しやすいのかや、どのくらいの支援者を目標にすればいいか、などの目標設定や分析に今回の調査結果を使用していただければ幸いです。

お金が足りない...はもう言い訳にならない

成功率は4分の1程度と調査結果を発表しました。

プロジェクト審査含めの成功率4分の1ですが、資金を集めるハードルは以前より格段に下がっているでしょう。

学生でも20代でも団塊の世代でも誰でも挑戦できるのがクラウドファンディングの良いとろこです。

どんどん挑戦しましょう!

この記事を読んだことを機会に、クラウドファンディングをやってみよう、と思ってくれる人がいれば私はとても嬉しいです。

一人でも多くの人がクラウドファンディングで何か楽しいことに挑戦することで日本の将来は明るくなっていくと思います!!

最後に告知(2回目だけどワクワク)

camp-fire.jp

こんなプロジェクトを立ち上げています。

もし、内容を読んで支援してやってもいいぞ、という方は支援をよろしくお願いします。

終わり!

本記事の調査方法(コード記載あり)

PythonライブラリのBeautifulSoup4でサイトから数値をスクレイピングさせてもらいました。(サーバーに負荷かけてすみません)

スクレイピングした数値をpandasで計算しています。

以下が使用したコードです。(ベタうちですみません)(スクレイピングに使用したコードのみ)

スクレイピングする際は、time.sleep(1)で相手サーバーに配慮しましょう!!

import requests
from bs4 import BeautifulSoup
import time
import pandas as pd


#CAMPFIREのプロジェクトの分類
category_box = ["art", "music", "dance", "product", "technology", "game", "journalism",
			"community", "food", "photo", "fashion", "movie", "publishing",
			"anime", "performance", "sports", "business", "comedy", "social-good"]


money_list = []
patron_list = []
category_list = []


#CAMPFIREのサイトは、分類ごとに分かれている
#URLの一番右を見ればそれがわかる
#この分類ごとにページをクローリングする
#https://camp-fire.jp/category/art

for category in category_box:

	page = 1
	while True:

		time.sleep(10)

                #分類ごとのURL作成
		url = "https://camp-fire.jp/category/" + str(category) + "/most_funded/page:{0}"

                #CAPFIREのサイトにリクエストを送り、レスポンス(サイト情報)を受け取る
		r = requests.get(url.format(page))

                #分析が可能な形に変換
		soup = BeautifulSoup(r.content, "html.parser")

                #各プロジェクトは、<div class="overview">に囲われている
                #ページ内のプロジェクト数がゼロであれば、while文をbreakする
		if len(soup.select(".overview .total")) == 0:
			print(len(soup.select(".overview .total")))
			break

                #各プロジェクトの情報を取得
                #取得する情報は、「SUCCESS」かどうか、現在集まっているお金、パトロンの人数
		for money, patron, success in zip(soup.select(".overview .total"), soup.select(".overview .rest"), soup.select(".success-summary span")):
			print(success.string)
			if success.string == "SUCCESS":

				money_split = str(money).split("</small>")
				money_split_split = money_split[1].split("円")
				money_processing = money_split_split[0].split(",")
				real_money =  "".join(money_processing)

				print(real_money)
				money_list.append(real_money)

				patron_split = str(patron).split("</small>")
				patron_split_split = patron_split[1].split("人")
				patron_processing = patron_split_split[0].split(",")
				real_patron = "".join(patron_processing)

				print(real_patron)
				patron_list.append(real_patron)

				category_list.append(category)

				print("----------------")
		page += 1

#CSVに出力するためにDataFrame形式にまとめる
df = pd.DataFrame({"money" : money_list,
					"patron" : patron_list,
					"category" : category_list})

df.to_csv("campfire.csv", index=False)

予測精度向上のための次なる手 〜クラウドファンディングはじめました〜

f:id:doz13189:20170120173259j:plain

目次

この記事は前回の続き

前回までのあらすじはこの記事。

doz13189.hatenablog.com

前回のシミュレーション結果を踏まえて、熟考と改善を重ねた結果

予測精度が上がりました!

予測する銘柄数を大幅に減らしました

336銘柄ある中から、予測しやすそうな銘柄のみを厳選し...

さらに説明変数の選び方も少しいじって...

株価の騰落予測を過去12ヶ月分シミュレーションし直してみると...

なんと62.78%まで向上しました。

予測している銘柄少なすぎる問題が発生

前回までは、300ちょいある中からだいたい60銘柄ほどをチョイス。

今回は、さらに減って10ちょいくらいの銘柄数しか予測できていません。

厳選した分は、上がったので良かったですが...

シミュレーション結果

予測月 : 12 月
対象銘柄数 : 6
予測的中銘柄数 : 4
予測精度:66.6%

予測月 : 11 月
対象銘柄数 : 8
予測的中銘柄数 : 5
予測精度:62.5%

予測月 : 10 月
対象銘柄数 : 15
予測的中銘柄数 : 11
予測精度:73.3%

予測月 : 9 月
対象銘柄数 : 7
予測的中銘柄数 : 4
予測精度:57.1%

予測月 : 8 月
対象銘柄数 : 11
予測的中銘柄数 : 6
予測精度:54.5%

予測月 : 7 月
対象銘柄数 : 12
予測的中銘柄数 : 4
予測精度:33.3%

予測月 : 6 月
対象銘柄数 : 11
予測的中銘柄数 : 5
予測精度:45.4%

予測月 : 5 月
対象銘柄数 : 15
予測的中銘柄数 : 12
予測精度:80.0%

予測月 : 4 月
対象銘柄数 : 21
予測的中銘柄数 : 16
予測精度:76.1%

予測月 : 3 月
対象銘柄数 : 9
予測的中銘柄数 : 3
予測精度:33.3%

予測月 : 2 月
対象銘柄数 : 8
予測的中銘柄数 : 7
予測精度:87.5%

予測月 : 1 月
対象銘柄数 : 6
予測的中銘柄数 : 5
予測精度:83.3%

平均予測精度は、62.78%

はてなのテーブル作るのめんどくさすぎるので、プログラムで出力している形のまんまで出しました。

いぜん安定せず...

前回のシミュレーション結果を見ると、ボラティリティの大きい月の予測精度が比較的悪かった印象がありました。

例えば、1月、3月、6月、7月、11月...


何かしらのイベントによる影響が株価を動かしていたこともあり、予測はしづらい月であることは間違いないのですが、そういった月も予測できてやっとはじめて実用的になると思うので、何とか工夫して予測精度が改善できないかを考えていました

なので、説明変数を仕分けしながらボラティリティが大きい時に効くものをチョイスして、ランダムフォレストのモデルを構築しなおしました。


予測精度は改善はしたのですが、予測のしづらい月は相変わらず予測精度50%を切る結果となりました。

最近は、新しいデータを加えるというよりかは、中身のアルゴリズムをいじって改善を試みています。

しかし、今持っているデータでは限界かな、と思えるような結果しか出ないです...

結局、今回もボラティリティが大きい月は50%を下回る予測精度しか出なかったです。(前回、50%を下回った月とほぼ同月)

クラウドファンディングはじめました

SNS等では告知しているのですが。

camp-fire.jp

四季報yahoo!ファイナンスVIP倶楽部のデータが使いたくて、その資金を集めるためにクラウドファンディングをはじめました。

予測精度向上のための次なる手です。

資金が集まらなくて苦労はしていますが...

もし、よければご支援下さい涙

誰かァァァあぁ、支援をぉぉ涙涙涙

おまけ

空き時間を見つけては、「株価 機械学習」とかいろんなワードでググったり、twitterで検索しながら何か参考にできる情報がないかを探索しています。

f:id:doz13189:20170120172407p:plain

このツイートを見つけて、めちゃめちゃ共感しちゃいました。

株価予測をするときに、「未来のデータを参照」はもうホントあるある探検隊です笑

一回私もやらかしましたからね...

見つけた時の絶望感半端ないです。

pandasでデータをくっつけるときによく起こりがちな事故なんですよね。


それからは、DataFrame同士をくっつける時に、いっしょに日付データも入れるようにして再発防止をしています。

なので、統合したDataFrameはくっつけた分だけ日付データがあります笑

ただ、目視での確認がとてもしやすいです。

ドルと日経平均とユーロをくっつけたDataFrameはこんな感じです。

f:id:doz13189:20170120173820p:plain


今作っているデータには未来のデータ参照はおそらくないと思います。(おそらく)(何回も確認しています)

未来のデータを参照した時って、めっちゃ安定するんですよね、精度が。

そういった意味では、今回のシステムの精度は分散激しいし、むしろ50%下回っている月もあるのでかえってリアリティ増しているのかなぁなんて思っています。