BerandaComputers and TechnologyMenjelajahi Saham Indeks S&P 100 Menggunakan Pembelajaran Mesin Grafik

Menjelajahi Saham Indeks S&P 100 Menggunakan Pembelajaran Mesin Grafik

Jude, Wang Jie

2020-11-12

Exploring the S&P 100 Index Stocks Using Graph Machine Learning

Dalam posting sebelumnya dari seri ini [1], kami memperkenalkan cara menggunakan pustaka analisis grafik berbasis Python NetworkX [2] dan Grafik Nebula [3] untuk menganalisis hubungan karakter dalam “Game of Thrones”.

Dalam posting ini, kita akan menjelajahi bagaimana menggunakan Java- perpustakaan analisis grafik berbasis JGraphT [4] dan pustaka diagram mxGraph [5] untuk memvisualisasikan perubahan korelasi antara saham Indeks S&P 100 [6] dari waktu ke waktu.

Exploring the S&P 100 Index Stocks Using Graph Machine Learning

Pemrosesan Set Data

Metode analisis utama yang digunakan dalam posting ini mengacu pada [7] dan [8]. Ada dua dataset: himpunan puncak dan himpunan tepi.

Data Stok (Kumpulan Vertex)

Pilih saham Indeks S&P 100 berikut, dan modelkan setiap saham sebagai simpul. Properti dari setiap simpul adalah kode saham dan industri dari perusahaan yang terdaftar.

Tabel 1: Sampel kumpulan titik

AAPL

Vertex ID Kode Industri Nama Perusahaan
1

Elektronik Konsumen

Apple Inc. (AAPL) 2 ABBV Produsen Obat — Umum

AbbVie Inc. (ABBV)

3 ABT Alat kesehatan Abbott Laboratories (ABT) 4 ACN Layanan Teknologi Informasi Accenture plc (ACN) 5 AIG Asuransi — Diversifikasi American International Group, Inc. (AIG) 6 SEMUA Asuransi — Properti & Korban The Allstate Corporation (SEMUA) 7 AMGN Produsen Obat — Umum Amgen Inc. (AMGN) 8 AMT REIT — Keahlian khusus American Tower Corporation (REIT) (AMT) 9 AMZN Ritel Internet Amazon.com, Inc. (AMZN)

Hubungan Saham (Tepi / Set Hubungan)

Setiap edge hanya memiliki satu properti, yaitu bobot . Bobot sebuah edge menunjukkan kesamaan tingkat pengembalian harian dari perusahaan yang terdaftar yang diwakili oleh simpul (saham) di kedua ujung tepi. Algoritme kesamaan mengacu pada [7] dan [8]: Menganalisis korelasi deret waktu dari tingkat pengembalian harian saham individu $ P_ {ij} $ selama periode waktu (dari 01-01 2014 hingga 2020-01-01), dan tentukan jarak antara masing-masing saham (yaitu bobot tepi) sebagai berikut.

$ l_ {ij}= sqrt {2 (1 -P_ {ij})} $

Melalui pemrosesan seperti itu, kami mendapatkan kisaran jarak sebagai [0,2]. Artinya, semakin jauh jarak kedua saham tersebut, semakin rendah korelasi antara tingkat pengembaliannya.

Tabel 2: Sampel set tepi

    ID simpul sumber ID simpul target Bobot tepi
    1 2 1.4206879982683
    1 4 1,37090336100054
    1 6 1.39684994985333

    Kumpulan titik dan himpunan tepi seperti itu membentuk jaringan grafik, yang dapat disimpan dalam database Grafik Nebula.

    JGraphT

    JGraphT adalah file Pustaka kelas Java open-source yang menyediakan tidak hanya berbagai struktur data grafik yang efisien dan umum, tetapi juga banyak algoritme yang berguna untuk memecahkan masalah grafik yang paling umum. Fitur JGraphT adalah sebagai berikut:

    • Mendukung tepi terarah, tepi tidak diarahkan, tepi tertimbang, tepi tidak berbobot, dll.
    • Mendukung grafik sederhana, multigraf, dan pseudograf.
    • Menyediakan iterator khusus (DFS, BFS, dll.) Untuk traversal grafik.
    • Menyediakan banyak algoritma grafik yang umum digunakan, seperti pencarian jalur, deteksi isomorfisme, pewarnaan, umum leluhur, pengembaraan, konektivitas, pencocokan, deteksi siklus, partisi, pemotongan, aliran, dan sentralitas.
    • Menyediakan impor yang mudah dari / ekspor ke GraphViz. File GraphViz yang diekspor dapat diterapkan oleh alat visualisasi Gephi untuk analisis dan demonstrasi.
    • Mendukung pembuatan jaringan grafik yang nyaman saat digunakan dengan alat seperti JGraphX, mxGraph, dan Generator Grafik Jambu.

    Selanjutnya, mari kita coba.

    1. Buat grafik terarah di JGraphT.
     impor org.jgrapht. ;  impor org.jgrapht.graph. ;  impor org.jgrapht.nio. ;  impor org.jgrapht.nio.dot. ;  impor org.jgrapht.traverse. ;   impor java.io. ;  impor java.net. ;  impor java.util. ;   Grafik   URI ,  DefaultEdge >  g =  baru  DefaultDirectedGraph   ( DefaultEdge . kelas  );   URI google =  baru  URI  (  "http://www.google.com"  );  URI wikipedia =  baru  URI  (  "http://www.wikipedia.org"  );  Jgrapht URI =  baru  URI  (  "http://www.jgrapht.org"  );    

    1. Tambahkan simpul.
    2.  
        g . addVertex ( google ); g . addVertex ( wikipedia ); g . addVertex ( jgrapht );

      1. Tambahkan tepi.
       

      // Tambahkan tepi untuk membuat struktur yang terhubung g . addEdge ( jgrapht , wikipedia ); g . addEdge ( google , jgrapht ); g . addEdge ( google , wikipedia ); g . addEdge ( wikipedia , google );

      Basis data Grafik Nebula

      JGraphT biasanya menggunakan file lokal sebagai data sumber. Tidak apa-apa saat Anda melakukan penelitian jaringan statis, tetapi jika jaringan grafik terus berubah, seperti jaringan grafik dari data stok, yang berubah setiap hari, akan sedikit merepotkan untuk membuat file statis baru, lalu memuat itu dan kemudian menganalisanya setiap saat. Idealnya, seluruh proses perubahan dapat ditulis ke database secara terus-menerus, dan subgraf atau grafik lengkap dapat dimuat langsung dari database secara real-time untuk dianalisis. Pada postingan kali ini, kami menggunakan Grafik Nebula sebagai database grafik untuk menyimpan data grafik.

      Klien Java Nebula Graph nebula-java [11] menyediakan dua cara untuk mengakses Grafik Nebula. Salah satunya adalah berinteraksi dengan lapisan mesin kueri [13] melalui bahasa kueri grafik nGQL [12], yang biasanya cocok untuk mengakses subgraf dan mendukung semantik kompleks; Yang lainnya adalah berinteraksi langsung dengan lapisan penyimpanan yang mendasarinya (proses penyimpanan) [14] melalui API, yang digunakan untuk mendapatkan set lengkap simpul dan tepi. Selain mengakses Grafik Nebula itu sendiri, nebula-java memberikan contoh interaksi dengan Neo4j [15], JanusGraph [16], Spark [17], dan lainnya.

      Dalam posting ini, kami menggunakan API untuk mengakses lapisan penyimpanan (proses penyimpanan) secara langsung untuk mendapatkan semua simpul dan tepi. Dua antarmuka berikut dapat digunakan untuk membaca semua data titik dan tepi.

         // spasi adalah nama ruang grafik yang akan dipindai, dan returnCols adalah simpul / tepi dan propertinya untuk dibaca.   // Format parameter returnCols: {tag1Name: prop1, prop2, tag2Name: prop3, prop4, prop5}    Iterator   ScanVertexResponse >   scanVertex   (             Stringspace ,  Peta  Tali, Daftar   String >>  returnCols );  Iterator   ScanEdgeResponse >   scanEdge   (             Stringspace ,  Peta  Tali, Daftar   String >>  returnCols );   

      1. Menginisialisasi klien dan ScanVertexProcessor. ScanVertexProcessor digunakan untuk memecahkan kode data simpul baca:
        MetaClientImpl metaClientImpl =  baru  MetaClientImpl  ( metaHost ,  metaPort );  metaClientImpl . Menghubung  ();  StorageClient storageClient =  baru  StorageClientImpl  ( metaClientImpl );  Prosesor prosesor =  baru  ScanVertexProcessor  ( metaClientImpl );   

      1. Panggil antarmuka scanVertex, yang mengembalikan iterator untuk objek scanVertexResponse:
        Iterator   ScanVertexResponse >  iterator =                 storageClient .   scanVertex   ( spaceName ,  returnCols );   

      1. Teruslah membaca data di objek scanVertexResponse yang ditunjukkan oleh iterator hingga semua data Baca. Data simpul baca disimpan dan kemudian ditambahkan ke struktur grafik JGraphT.
         sementara   ( iterator .   hasNext   ())   {   Respons ScanVertexResponse = iterator . lanjut  ();    jika  ( respon == batal)   {     catatan.kesalahan  (  "Terjadi kesalahan saat memindai simpul"  );      istirahat ;    }       Hasil hasil = prosesor . proses  ( spaceName ,  tanggapan );    hasil .   addAll   (hasil.   getRows   ( TAGNAME ));  }   

      Data tepi membaca mirip dengan proses di atas.

      Analisis Grafik di JGraphT

        Buat grafik tidak terarah dan berbobot di JGraphT:
       Grafik  String ,  MyEdge >  grafik = GraphTypeBuilder                 .   tidak diarahkan   ()      .   berbobot   ( benar)      .   memungkinkanMultipleEdges   ( benar)      .   memungkinkanSelfLoops   ( Salah)      .   simpulPemasok   ( SupplierUtil .   createStringSupplier   ())      .   edgeSupplier   ( SupplierUtil .   createSupplier   ( MyEdge . kelas ))      .   buildGraph   ();   

      1. Tambahkan data titik dan tepi yang dibaca pada langkah terakhir dari ruang Grafik Nebula ke grafik:
       

      untuk ( VertexDomain vertex : vertexDomainList ) { grafik. addVertex (puncak. getVid (). toString ()); stockIdToName . taruh (puncak. getVid (). toString (), simpul ) ; } untuk ( EdgeDomain edgeDomain : edgeDomainList ) { grafik. addEdge ( edgeDomain . getSrcid (). toString (), edgeDomain . getDstid (). toString ()); MyEdge newEdge = grafik . getEdge ( edgeDomain . getSrcid (). toString () , edgeDomain . getDstid (). toString ()); grafik. setEdgeWeight ( newEdge , edgeDomain . getWeight ()); }

      1. Seperti algoritma analisis yang disebutkan dalam [7] dan [8], gunakan algoritma pohon rentang-minimum Prim untuk grafik sebelumnya dan panggil antarmuka drawGraph yang dienkapsulasi untuk menggambar grafik.

      Algoritma Prim adalah algoritma dalam teori grafik yang mencari pohon rentang minimum dalam grafik terhubung berbobot. Dengan kata lain, pohon yang dibentuk oleh himpunan bagian tepi yang dicari oleh algoritme ini tidak hanya mencakup semua simpul dalam grafik yang terhubung tetapi juga memiliki jumlah bobot minimum dari semua tepi.

        SpanningTreeAlgorithm .   SpanningTree  pMST =  baru  PrimMinimumSpanningTree  (grafik).   getSpanningTree   ();   Legenda.  drawGraph   ( pMST .   getEdges   (),  nama file, stockIdToName );   

      1. Metode drawGraph merangkum pengaturan parameter seperti tata letak gambar. Metode ini membuat saham di sektor yang sama dengan warna yang sama, mengelompokkan saham yang berdekatan menjadi satu.
         publik   kelas  Legenda  {     ...       publik statis kosong  drawGraph  (Set  MyEdge >  tepi ,  Nama file string ,  Peta   String ,  VertexDomain >  idVertexMap )   lemparan  IOException  {       // Membuat grafik dengan model    grafik mxGraph = baru mxGraph  ();       Objek induk = grafik .   getDefaultParent   ();         // setel gaya    grafik .   getModel   ().   beginUpdate   ();       mxStylesheet myStylesheet = grafik .   getStylesheet   ();       grafik.  setStylesheet   ( setMsStylesheet  ( myStylesheet ));        Peta  Tali, Objek >  idMap =  baru  HashMap   ();       Peta  Tali, String >  industryColor =  baru  HashMap   ();         int  colorIndex = 0 ;        untuk  ( Tepi MyEdge :  tepi )   {        Objek src ,  dst ;         jika  (!  idMap .   berisiKunci  (tepi.   getSrc   ()))   {          VertexDomain srcNode = idVertexMap . Dapatkan (tepi.   getSrc   ());           String nodeColor ;           jika  ( warna industri .   berisiKunci   ( srcNode .   getIndustry   ())) {            nodeColor = warna industri . Dapatkan  ( srcNode .   getIndustry   ());           } lain  {            nodeColor = COLOR_LIST  [colorIndex++];             industryColor . taruh  ( srcNode .   getIndustry   (),  nodeColor );           }           src = grafik .   insertVertex  (induk,  batal ,  srcNode .   getName   (),  0 ,  0 ,  105 ,  50 ,   "fillColor="   +  nodeColor );           idMap . taruh  (tepi.   getSrc   (),  src );         }  lain  {          src = idMap . Dapatkan (tepi.   getSrc   ());         }          jika  (!  idMap .   berisiKunci  (tepi.   getDst   ()))   {          VertexDomain dstNode = idVertexMap . Dapatkan (tepi.   getDst   ());            String nodeColor ;           jika  ( warna industri .   berisiKunci   ( dstNode .   getIndustry   ())) {            nodeColor = warna industri . Dapatkan  ( dstNode .   getIndustry   ());           } lain  {            nodeColor = COLOR_LIST  [colorIndex++];             industryColor . taruh  ( dstNode .   getIndustry   (),  nodeColor );           }            dst = grafik .   insertVertex  (induk,  batal ,  dstNode .   getName   (),  0 ,  0 ,  105 ,  50 ,   "fillColor="   +  nodeColor );           idMap . taruh  (tepi.   getDst   (),  dst );         }  lain  {          dst = idMap . Dapatkan (tepi.   getDst   ());         }         grafik.  insertEdge   (induk,  batal,   ""  ,  src ,  dst );       }         catatan.  info   (  "simpul"   +  idMap . ukuran  ());       catatan.  info   (  "ukuran warna"   +  warna industri . ukuran  ());        mxFastOrganicLayout layout =  baru  mxFastOrganicLayout  (grafik);       tata letak .   setMaxIterations   ( 2000 );        // layout.setMinDistanceLimit (10D);    tata letak .  menjalankan  (induk);       grafik.  getModel   ().   endUpdate   ();         // Membuat gambar yang dapat disimpan menggunakan ImageIO    Gambar BufferedImage = createBufferedImage  (grafik,  null   ,  1 ,  Warna .  PUTIH ,                                                 benar ,   null  );         // Demi contoh ini, kami menampilkan gambar di jendela     // Simpan sebagai JPEG    File file = baru Berkas  (nama file);      ImageIO . menulis  (gambar,   "JPEG"  ,  file );      }        ...   }   

      1. Visualisasikan data.

          Warna setiap simpul pada Gambar 1 mewakili industrinya. Kita dapat melihat bahwa saham-saham dengan kemiripan bisnis yang tinggi telah dikelompokkan bersama, tetapi beberapa saham yang tidak memiliki korelasi yang jelas juga telah dikelompokkan bersama, yang alasannya perlu dipelajari secara terpisah.

          Clustering based on the stock data from 2014-01-01 to 2020-01-01

          Gambar 1 : Pengelompokan berdasarkan data stok dari 01-01-2014 hingga 2020-01-01

          1. Beberapa eksplorasi dinamis lainnya berdasarkan jendela waktu yang berbeda.

          Kesimpulan sebelumnya terutama didasarkan pada agregasi stok dari 2014-01-01 hingga 2020- 01-01. Kami juga melakukan upaya lain: Gunakan jendela geser 2 tahun dan metode analisis yang sama untuk mengamati apakah kelompok yang dikelompokkan akan berubah seiring waktu.

          Clustering based on the stock data from 2014-01-01 to 2016-01-01 Gambar 2: Pengelompokan berdasarkan data stok dari 2014-01-01 hingga 2016-01-01

          Clustering based on the stock data from 2015-01-01 to 2017-01-01

          Gambar 3: Pengelompokan berdasarkan data stok dari 2015-01-01 hingga 01-01 2017

          Clustering based on the stock data from 2016-01-01 to 2018-01-01

          Gambar 4: Pengelompokan berdasarkan data stok dari 01-01 hingga 2018-01-01

          Clustering based on the stock data from 2017-01-01 to 2019-01-01

          Gambar 5: Pengelompokan berdasarkan data stok dari 01-01-2017 hingga 2019-01-01

          Clustering based on the stock data from 2018-01-01 to 2020-01-01

          Gambar 6: Pengelompokan berdasarkan data stok dari 01-01-2018 hingga 2020-01-01

          Menurut analisis kasar, dengan perubahan jendela waktu, pengelompokan saham di sebagian besar industri mempertahankan relatif baik, yang berarti bahwa dengan perubahan waktu, semua jenis saham dalam industri yang sama memiliki korelasi yang relatif tinggi.

          Penolakan

          image

          Posting ini tidak boleh dianggap sebagai nasihat investasi. Karena situasi penangguhan perdagangan, pemutus sirkuit, batas perdagangan, transfer, merger dan akuisisi, perubahan bisnis utama, dll., Pemrosesan data dalam posting ini mungkin salah. Kami belum memeriksa semua data sepotong demi sepotong.

          Dibatasi oleh waktu, posting ini hanya memilih data 100 sampel stok dalam enam tahun terakhir, dan hanya mengadopsi metode pohon ekspansi minimum untuk melakukan clustering dan klasifikasi. Di masa mendatang, mungkin kami dapat menggunakan kumpulan data yang lebih besar (seperti saham AS, derivatif, dan mata uang digital) untuk mencoba lebih banyak metode dalam pembelajaran mesin.

          Untuk kode yang digunakan dalam posting ini, silakan lihat [18].

          Referensi

          [1] Menganalisis Hubungan dalam Game of Thrones Dengan NetworkX, Gephi, dan Nebula Graph (Bagian Satu) https: / /nebula-graph.io/posts/game-of-thrones-relationship-networkx-gephi-nebula-graph/

          [2] Menganalisis Hubungan di Game of Thrones Dengan NetworkX, Gephi, dan Nebula Graph (Bagian Dua) ​​ https: // n ebula-graph.io/posts/game-of-thrones-relationship-networkx-gephi-nebula-graph-part-two/

          [3] NetworkX: paket Python untuk pembuatan, manipulasi, dan studi tentang struktur, dinamika, dan fungsi jaringan yang kompleks. https://networkx.github.io/

          [4] Grafik Nebula: Terdistribusi dengan kuat, dapat diskalakan, Database grafik secepat kilat yang ditulis dalam C ++. https://nebula-graph.io/

          [5] JGraphT: perpustakaan grafik Java teori struktur data dan algoritma. https://jgrapht.org/

          [6] mxGraph: pustaka diagram JavaScript yang memungkinkan grafik interaktif dan aplikasi charting. https://jgraph.github.io/mxgraph/

          [7] Bonanno , Giovanni & Lillo, Fabrizio & Mantegna, Rosario. (2000). Korelasi silang frekuensi tinggi dalam Kumpulan Saham. arXiv.org, Makalah Keuangan Kuantitatif. 1. 10.1080 / 713665554.

          [8] Mantegna, RN Struktur hierarki di pasar keuangan. Eur. Phys. J. B 11, 193–197 (1999).

          [9] https://graphviz.org/

          [10] https://gephi.org/

          [11] https://github.com/vesoft-inc/ nebula-java

          [12] Bahasa Kueri Grafik Nebula (nGQL). https: //docs.nebula- graph.io/manual-EN/1.overview/1.concepts/2.nGQL-overview/

          [13] Mesin Kueri Grafik Nebula. https://github.com / vesoft-inc / nebula-graph

          [14] Penyimpanan nebula: Penyimpanan grafik yang konsisten dan terdistribusi. https: // github. com / vesoft-inc / nebula-storage

          [15] Neo4j. www.neo4j.com

          [16] JanusGraph. janusgraph.org

          [17] Apache Spark. spark.apache .org .

          [18] https://github.com/Judy1992/nebula_scan

          Seperti apa yang kami lakukan? Bintangi kami di GitHub. https : //github.com/vesoft-inc/nebula

      Read More

      RELATED ARTICLES

      LEAVE A REPLY

      Please enter your comment!
      Please enter your name here

      Most Popular

      Recent Comments