グラフマシン学習を用いたS&P 100インデックス株の調査



このシリーズ[ 1 ]の前のポストでは、私たちは、Pythonのベースのグラフ分析ライブラリNetWorx [ 2 ]とNebula Graph [ 3 ]を使用して、「ゲームの中で」の文字関係を分析する方法を紹介しました.
このポストでは、我々は、Javaベースのグラフ解析ライブラリJGrapt [ 4 ]とDiagramming図書館Mxgraph [ 5 ]を使用して、S & P 100インデックス株[ 6 ]間の相関関係の変化を視覚的に可視化する方法を検討します.

データセット処理


このポストで使用される主な分析方法は[ 7 ]と[ 8 ]を参照します.頂点セットとエッジセットの2つのデータセットがあります.

ストックデータ(頂点集合)


次のS&P 100指数株を選択し、頂点として各在庫をモデル化します.各頂点のプロパティは、上場企業と上場企業の業界です.
表1 :頂点集合サンプル

株式の関係



このような処理を通して、距離の範囲を[ 0 , 2 ]とします.それは、2つの株より遠く離れて、彼らの復帰率の間の相関関係が低いことを意味します.
表2 :エッジセットサンプル

このような頂点集合とエッジ集合は、星雲グラフデータベースに格納できるグラフネットワークを形成する.

原研


JGraptは、最も一般的なグラフの問題を解決するための様々な効率的で一般的なグラフのデータ構造だけでなく、多くの便利なアルゴリズムを提供するオープンソースのJavaクラスライブラリです.JGraptの特徴は以下の通りです.
  • は、指示されたエッジ、無向のエッジ、重み付けされたエッジ、非重み付けされたエッジ、その他を支持する
  • は単純なグラフ、マルチグラフ、および擬似グラフをサポートします.
  • は、グラフ横断のために専用のイテレータ(DFS、BFSなど)を提供します.
  • は、パスルックアップ、同型検出、着色、共通祖先、徘徊、接続性、マッチング、サイクル検出、分割、切断、フロー、および中心性などの一般的に使用されるグラフアルゴリズムを多数提供する.
  • はGraphVizに簡単にインポート/エクスポートを提供します.エクスポートされたGraphizファイルを解析とデモのための可視化ツールGephiで適用することができます.
  • は、JGrapx、MXGraph、およびGuavaグラフジェネレータなどのツールで使用されている便利なグラフネットワークを生成をサポートしています.
  • 次に試してみましょう.
  • JGraptで有向グラフを作成します.
  • import org.jgrapht.*;
    import org.jgrapht.graph.*;
    import org.jgrapht.nio.*;
    import org.jgrapht.nio.dot.*;
    import org.jgrapht.traverse.*;
    
    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    Graph<URI, DefaultEdge> g = new DefaultDirectedGraph<>(DefaultEdge.class);
    
    URI google = new URI("http://www.google.com");
    URI wikipedia = new URI("http://www.wikipedia.org");
    URI jgrapht = new URI("http://www.jgrapht.org");
    
  • 頂点を追加します.
  • g.addVertex(google);
    g.addVertex(wikipedia);
    g.addVertex(jgrapht);
    
  • エッジを追加します.
  • // Add edges to create a linked structure
    
    g.addEdge(jgrapht, wikipedia);
    g.addEdge(google, jgrapht);
    g.addEdge(google, wikipedia);
    g.addEdge(wikipedia, google);
    

    星雲グラフデータベース


    JGraptは通常、データソースとしてローカルファイルを使用します.あなたが静的ネットワーク研究をしているとき、それはすばらしいです、しかし、グラフ・ネットワークが常に変化しているならば、株価データのグラフ・ネットワークのように、それは毎日変わります、それは新しい静的なファイルを生成するために少しの手間がかかります.理想的には、全体の変更プロセスを永続的にデータベースに記述することができますし、サブグラフや完全なグラフを直接分析のためのデータベースからロードすることができます.このポストでは、グラフデータを格納するためのグラフデータベースとして星雲グラフを使用する.
    星雲グラフのJavaクライアント星雲Java [ 11 ]は星雲グラフにアクセスする2つの方法を提供します.一つはグラフ問い合わせ言語NGQL [ 12 ]を通して照会エンジン層[ 13 ]と相互作用しています.もう一つは、頂点とエッジの完全なセットを得るために使用されるAPIを通しての基礎的な記憶層(Storageしたプロセス)[ 14 ]と直接対話することです.星雲グラフ自体にアクセスすることに加えて、Nebula JavaはNEA 4 J [ 15 ]、Janusgraph [ 16 ]、SLAGS [ 17 ]と相互作用する例を提供します.
    この記事では、すべての頂点とエッジを取得するために、ストレージ層にアクセスするためにAPIを使用します.次の2つのインターフェイスを使用して、頂点とエッジのすべてのデータを読み取ることができます.
    // space is the name of the graph space to be scanned, and returnCols is the vertex/edge and its properties to be read.
    // Format of returnCols parameter: {tag1Name: prop1, prop2, tag2Name: prop3, prop4, prop5}
    Iterator<ScanVertexResponse> scanVertex(
                Stringspace, Map<String, List<String>>returnCols);
    Iterator<ScanEdgeResponse> scanEdge(
                Stringspace, Map<String, List<String>>returnCols);
    
  • クライアントとscanvertexprocessorを初期化します.ScanverTexprocessorを使用して、読み取り頂点データをデコードします.
  • MetaClientImpl metaClientImpl = new MetaClientImpl(metaHost, metaPort);
    metaClientImpl.connect();
    StorageClient storageClient = new StorageClientImpl(metaClientImpl);
    Processor processor = new ScanVertexProcessor(metaClientImpl);
    
  • ScanverTextResponseオブジェクトの反復子を返すScanverTexインターフェイスを呼び出します.
  • Iterator<ScanVertexResponse> iterator =
                    storageClient.scanVertex(spaceName, returnCols);
    
  • データを読み込むまでイテレータが指しているScanverTextResponseオブジェクト内のデータを読み続けます.読み出された頂点データは保存され、後でJGraptのグラフ構造に追加されます.
  • while (iterator.hasNext()) {
      ScanVertexResponse response = iterator.next();
      if (response == null) {
        log.error("Error occurs while scan vertex");
        break;
      }
    
      Result result = processor.process(spaceName, response);
      results.addAll(result.getRows(TAGNAME));
    }
    
    読み出しエッジデータは上記の処理と同様である.

    グラフの解析

  • JGraptの無向グラフと重み付けグラフを作成します.
  • Graph<String, MyEdge> graph = GraphTypeBuilder
                    .undirected()
        .weighted(true)
        .allowingMultipleEdges(true)
        .allowingSelfLoops(false)
        .vertexSupplier(SupplierUtil.createStringSupplier())
        .edgeSupplier(SupplierUtil.createSupplier(MyEdge.class))
        .buildGraph();
    
  • 星雲グラフ空間から最後のステップで読み込んだ頂点とエッジのデータをグラフに追加します.
  • for (VertexDomain vertex : vertexDomainList){
        graph.addVertex(vertex.getVid().toString());
        stockIdToName.put(vertex.getVid().toString(), vertex);
    }
    
    for (EdgeDomain edgeDomain : edgeDomainList){
        graph.addEdge(edgeDomain.getSrcid().toString(), edgeDomain.getDstid().toString());
        MyEdge newEdge = graph.getEdge(edgeDomain.getSrcid().toString(), edgeDomain.getDstid().toString());
        graph.setEdgeWeight(newEdge, edgeDomain.getWeight());
    }
    
  • [ 7 ]と[ 8 ]で説明された解析アルゴリズムのように、前のグラフのPRIMの最小スパニングツリーアルゴリズムを使用し、カプセル化されたドロドログラフインターフェイスを呼び出してグラフを描画します.
  • primのアルゴリズムは重み付き接続グラフの最小スパンニング木を探索するグラフ理論のアルゴリズムである.言い換えれば、このアルゴリズムによって探索されたエッジ部分集合によって形成された木は、接続されたグラフ内のすべての頂点を含むだけでなく、すべてのエッジの重みの最小和を有する.
    SpanningTreeAlgorithm.SpanningTree pMST = new PrimMinimumSpanningTree(graph).getSpanningTree();
    
    Legend.drawGraph(pMST.getEdges(), filename, stockIdToName);
    
  • DrawGraphメソッドは、図面のレイアウトなどのパラメーター設定をカプセル化します.このメソッドは、同じ色で同じセクターの株式を集めて、近くの株をまとめています.
  • public class Legend {
    
    ...
    
      public static void drawGraph(Set<MyEdge> edges, String filename, Map<String, VertexDomain> idVertexMap) throws IOException {
         // Creates graph with model
         mxGraph graph = new mxGraph();
         Object parent = graph.getDefaultParent();
    
         // set style
         graph.getModel().beginUpdate();
         mxStylesheet myStylesheet = graph.getStylesheet();
         graph.setStylesheet(setMsStylesheet(myStylesheet));
    
         Map<String, Object> idMap = new HashMap<>();
         Map<String, String> industryColor = new HashMap<>();
    
         int colorIndex = 0;
    
         for (MyEdge edge : edges) {
           Object src, dst;
           if (!idMap.containsKey(edge.getSrc())) {
             VertexDomain srcNode = idVertexMap.get(edge.getSrc());
             String nodeColor;
             if (industryColor.containsKey(srcNode.getIndustry())){
               nodeColor = industryColor.get(srcNode.getIndustry());
             }else {
               nodeColor = COLOR_LIST[colorIndex++];
               industryColor.put(srcNode.getIndustry(), nodeColor);
             }
             src = graph.insertVertex(parent, null, srcNode.getName(), 0, 0, 105, 50, "fillColor=" + nodeColor);
             idMap.put(edge.getSrc(), src);
           } else {
             src = idMap.get(edge.getSrc());
           }
    
           if (!idMap.containsKey(edge.getDst())) {
             VertexDomain dstNode = idVertexMap.get(edge.getDst());
    
             String nodeColor;
             if (industryColor.containsKey(dstNode.getIndustry())){
               nodeColor = industryColor.get(dstNode.getIndustry());
             }else {
               nodeColor = COLOR_LIST[colorIndex++];
               industryColor.put(dstNode.getIndustry(), nodeColor);
             }
    
             dst = graph.insertVertex(parent, null, dstNode.getName(), 0, 0, 105, 50, "fillColor=" + nodeColor);
             idMap.put(edge.getDst(), dst);
           } else {
             dst = idMap.get(edge.getDst());
           }
           graph.insertEdge(parent, null, "", src, dst);
         }
    
         log.info("vertice " + idMap.size());
         log.info("colorsize " + industryColor.size());
    
         mxFastOrganicLayout layout = new mxFastOrganicLayout(graph);
         layout.setMaxIterations(2000);
         //layout.setMinDistanceLimit(10D);
         layout.execute(parent);
    
         graph.getModel().endUpdate();
    
         // Creates an image than can be saved using ImageIO
         BufferedImage image = createBufferedImage(graph, null, 1, Color.WHITE,
                                                   true, null);
    
         // For the sake of this example we display the image in a window
         // Save as JPEG
         File file = new File(filename);
         ImageIO.write(image, "JPEG", file);
    
       }
    
      ...
    
    }
    
  • データを視覚化します.
  • 図1の各頂点の色はその産業を表します.ビジネスの類似性の高い株は、クラスター化されていることがわかるが、明らかな相関関係のない株も一緒に集められている.

    図1 : 2014 - 01 - 01から2020 - 01 - 01までの株式データに基づくクラスタリング
  • 別の時間窓に基づくいくつかの他のダイナミックな探査.
  • 以上の結論は主に2014 - 01 - 01から2020 - 01 - 01までの株式集計による.また、他の試みを行った:2年のスライディングウィンドウと同じ分析方法を使用して、クラスタ化されたグループが時間とともに変化するかどうかを観察します.

    図2 : 2014 - 01 - 01から2016 - 01 - 01までの株式データに基づくクラスタリング

    図3 : 2015 - 01 - 01から2017 - 01 - 01までの株式データに基づくクラスタリング

    図4 : 2016 - 01 - 01から2018 - 01 - 01までの株式データに基づくクラスタリング

    図5 : 2017 - 01 - 01から2019 - 01 - 01までの株式データに基づくクラスタリング

    図6 : 2018 - 01 - 01から2020 - 01 - 01までの株式データに基づくクラスタリング
    タイムラインの変化に伴い、大部分の産業の株のクラスタリングは比較的良いことを維持します.そして、それは時間の変更で、同じ産業の中のすべての種類の株は比較的高い相関を維持します.

    免責事項


    このポストは投資助言とはならない.貿易停止、サーキットブレーカー、取引限度、移転、合併、買収、主要事業の変更等の状況により、このポストのデータ処理は不正確である.すべてのデータを1枚ずつチェックしていない.
    時間によって制限されて、このポストは過去6年で100のストックサンプルのデータだけを選択して、クラスタリングと分類をするために最小拡張木の方法を採用するだけです.将来的には、我々は機械学習においてより多くの方法を試みるために、より大きなデータセット(米国株、デリバティブ、デジタル通貨など)を使うことができるかもしれない.
    このポストで使用されるコードのために、[ 18 ]を見てください.

    参考文献


    [ 1 ] NetworkX , Gephi , Nebula Graphを用いたスプーンゲームの関係分析(第1部)
    [ 2 ] NetworkX , Gephi , Nebula Graphを用いたスプーンゲームの関係分析(第2部) https://nebula-graph.io/posts/game-of-thrones-relationship-networkx-gephi-nebula-graph/
    ネットワークワーク:複雑なネットワークの構造、ダイナミクス、および機能の作成、操作、および研究のためのPythonパッケージ.https://nebula-graph.io/posts/game-of-thrones-relationship-networkx-gephi-nebula-graph-part-two/
    [4]星雲グラフ:C++で書かれた強力に分散した、スケーラブルで、稲妻の速いグラフ・データベース.https://networkx.github.io/
    JGraptグラフ理論データ構造とアルゴリズムのJavaライブラリhttps://nebula-graph.io/
    MXGraph :対話型グラフとチャートアプリケーションを可能にするJavaScript図式ライブラリ.https://jgrapht.org/
    ボナノノ、ジョヴァンニ&リロ、Fabrizio&Mantegna、ロサリオ.(2000)株集合における高周波相互相関arxiv量的財務書類.1 .
    金融市場の階層構造.ユーロ.物理J . B . 11 , 193 - 197 ( 1999 )
    [9]https://jgraph.github.io/mxgraph/
    [10]https://graphviz.org/
    [11]https://gephi.org/
    [12]星雲グラフ言語(NGQL).https://github.com/vesoft-inc/nebula-java
    [ 13 ]星雲グラフクエリエンジン.https://docs.nebula-graph.io/manual-EN/1.overview/1.concepts/2.nGQL-overview/
    [14]星雲ストレージ分散一貫グラフ記憶https://github.com/vesoft-inc/nebula-graph
    [15]neoa 4 jhttps://github.com/vesoft-inc/nebula-storage
    [ 16 ] Janusgraph.www.neo4j.com
    アパッチスパーク.janusgraph.org .
    [18]spark.apache.org

    Like what we do ? Star us on GitHub. https://github.com/vesoft-inc/nebula


    当初は、2020年11月12日にhttps://github.com/Judy1992/nebula_scanに発行された.