金融知識(shí)圖譜構(gòu)建:量化分析、圖算法、關(guān)系預(yù)測(cè)、命名實(shí)體識(shí)別、
手把手教學(xué)小型金融知識(shí)圖譜構(gòu)建:量化分析、圖數(shù)據(jù)庫(kù)neo4j、圖算法、關(guān)系預(yù)測(cè)、命名實(shí)體識(shí)別、Cypher Cheetsheet詳細(xì)教學(xué)等
效果預(yù)覽:



1. 知識(shí)圖譜存儲(chǔ)方式
知識(shí)圖譜存儲(chǔ)方式主要包含資源描述框架(Resource Description Framework,RDF)和圖數(shù)據(jù)庫(kù)(Graph Database)。
1.1 資源描述框架特性
存儲(chǔ)為三元組(Triple)
標(biāo)準(zhǔn)的推理引擎
W3C標(biāo)準(zhǔn)
易于發(fā)布數(shù)據(jù)
多數(shù)為學(xué)術(shù)界場(chǎng)景
1.2 圖數(shù)據(jù)庫(kù)特性
節(jié)點(diǎn)和關(guān)系均可以包含屬性
沒(méi)有標(biāo)準(zhǔn)的推理引擎
圖的遍歷效率高
事務(wù)管理
多數(shù)為工業(yè)界場(chǎng)景
碼源鏈接見(jiàn)文末跳轉(zhuǎn)
文末鏈接跳轉(zhuǎn)
2. 圖數(shù)據(jù)庫(kù)neo4j
neo4j是一款NoSQL圖數(shù)據(jù)庫(kù),具備高性能的讀寫(xiě)可擴(kuò)展性,基于高效的圖形查詢語(yǔ)言Cypher
,更多介紹可訪問(wèn)neo4j官網(wǎng),官網(wǎng)還提供了Online Sandbox實(shí)現(xiàn)快速上手體驗(yàn)。
2.1 軟件下載
下載鏈接:https://neo4j.com/download-center/
2.2 啟動(dòng)登錄
2.2.1 Windows
進(jìn)入
neo4j
目錄
cd neo4j/bin
./neo4j start
啟動(dòng)成功,終端出現(xiàn)如下提示即為啟動(dòng)成功
Starting Neo4j.Started neo4j (pid 30914). It is available at http://localhost:7474/ There may be a short delay until the server is ready.
(1)訪問(wèn)頁(yè)面:http://localhost:7474
(2)初始賬戶和密碼均為neo4j
(host
類型選擇bolt
)
(3)輸入舊密碼并輸入新密碼:?jiǎn)?dòng)前注意本地已安裝jdk
(建議安裝jdk version 11
):https://www.oracle.com/java/technologies/javase-downloads.html
2.2.2 MacOS
執(zhí)行 Add Local DBMS 后,再打開(kāi) Neo4j Browser即可
2.3 儲(chǔ)備知識(shí)
在 neo4j 上執(zhí)行 CRUD 時(shí)需要使用 Cypher 查詢語(yǔ)言。
官網(wǎng)文檔
個(gè)人整理的常見(jiàn)Cypher指令
2.4 Windows安裝時(shí)可能遇到問(wèn)題及解決方法
問(wèn)題:完成安裝JDK1.8.0_261后,在啟動(dòng)
neo4j
過(guò)程中出現(xiàn)了以下問(wèn)題:
Unable to find any JVMs matching version "11"
解決方案:提示安裝
jdk 11 version
,于是下載了jdk-11.0.8
,Mac OS
可通過(guò)ls -la /Library/Java/JavaVirtualMachines/
查看已安裝的jdk
及版本信息。
3. 知識(shí)圖譜數(shù)據(jù)準(zhǔn)備
3.1 免費(fèi)開(kāi)源金融數(shù)據(jù)接口
Tushare免費(fèi)賬號(hào)可能無(wú)法拉取數(shù)據(jù),可參考issues提供的股票數(shù)據(jù)獲取方法:
3.1.1 Tushare
官網(wǎng)鏈接:http://www.tushare.org/
3.1.2 JointQuant
官網(wǎng)鏈接:https://www.joinquant.com/

3.1.3 導(dǎo)入模塊
import tushare as ts ?# 參考Tushare官網(wǎng)提供的安裝方式import csvimport timeimport pandas as pd# 以下pro_api token可能已過(guò)期,可自行前往申請(qǐng)或者使用免費(fèi)版本pro = ts.pro_api('4340a981b3102106757287c11833fc14e310c4bacf8275f067c9b82d')
3.2 數(shù)據(jù)預(yù)處理
3.2.1 股票基本信息
stock_basic = pro.stock_basic(list_status='L', fields='ts_code, symbol, name, industry')# 重命名行,便于后面導(dǎo)入neo4jbasic_rename = {'ts_code': 'TS代碼', 'symbol': '股票代碼', 'name': '股票名稱', 'industry': '行業(yè)'}
stock_basic.rename(columns=basic_rename, inplace=True)# 保存為stock_basic.csvstock_basic.to_csv('financial_data\\stock_basic.csv', encoding='gbk')

3.2.2 股票持有股東信息
holders = pd.DataFrame(columns=('ts_code', 'ann_date', 'end_date', 'holder_name', 'hold_amount', 'hold_ratio'))# 獲取一年內(nèi)所有上市股票股東信息(可以獲取一個(gè)報(bào)告期的)for i in range(3610):
? code = stock_basic['TS代碼'].values[i]
? holders = pro.top10_holders(ts_code=code, start_date='20180101', end_date='20181231')
? holders = holders.append(holders) ? if i % 600 == 0:
? ? ? print(i)
? time.sleep(0.4)# 數(shù)據(jù)接口限制# 保存為stock_holders.csvholders.to_csv('financial_data\\stock_holders.csv', encoding='gbk')
holders = pro.holders(ts_code='000001.SZ', start_date='20180101', end_date='20181231')

3.2.3 股票概念信息
concept_details = pd.DataFrame(columns=('id', 'concept_name', 'ts_code', 'name'))for i in range(358):
? id = 'TS' + str(i)
? concept_detail = pro.concept_detail(id=id)
? concept_details = concept_details.append(concept_detail)
? time.sleep(0.4)# 保存為concept_detail.csvconcept_details.to_csv('financial_data\\stock_concept.csv', encoding='gbk')

3.2.4 股票公告信息
for i in range(3610):
? code = stock_basic['TS代碼'].values[i]
? notices = pro.anns(ts_code=code, start_date='20180101', end_date='20181231', year='2018')
? notices.to_csv("financial_data\\notices\\"+str(code)+".csv",encoding='utf_8_sig',index=False)
notices = pro.anns(ts_code='000001.SZ', start_date='20180101', end_date='20181231', year='2018')

3.2.5 財(cái)經(jīng)新聞信息
news = pro.news(src='sina', start_date='20180101', end_date='20181231')
news.to_csv("financial_data\\news.csv",encoding='utf_8_sig')

3.2.6 概念信息
concept = pro.concept()
concept.to_csv('financial_data\\concept.csv', encoding='gbk')

3.2.7 滬股通和深股通成分信息
#獲取滬股通成分sh = pro.hs_const(hs_type='SH')
sh.to_csv("financial_data\\sh.csv",index=False)#獲取深股通成分sz = pro.hs_const(hs_type='SZ')
sz.to_csv("financial_data\\sz.csv",index=False)

3.2.8 股票價(jià)格信息
for i in range(3610):
? code = stock_basic['TS代碼'].values[i]
? price = pro.query('daily', ts_code=code, start_date='20180101', end_date='20181231')
? price.to_csv("financial_data\\price\\"+str(code)+".csv",index=False)

3.2.9 使用免費(fèi)接口獲取股票數(shù)據(jù)
import tushare as ts# 基本面信息df = ts.get_stock_basics()# 公告信息ts.get_notices("000001")# 新浪股吧ts.guba_sina()# 歷史價(jià)格數(shù)據(jù)ts.get_hist_data("000001")# 歷史價(jià)格數(shù)據(jù)(周粒度)ts.get_hist_data("000001",ktype="w")# 歷史價(jià)格數(shù)據(jù)(1分鐘粒度)ts.get_hist_data("000001",ktype="m")# 歷史價(jià)格數(shù)據(jù)(5分鐘粒度)ts.get_hist_data("000001",ktype="5")# 指數(shù)數(shù)據(jù)(sh上證指數(shù);sz深圳成指;hs300滬深300;sz50上證50;zxb中小板指數(shù);cyb創(chuàng)業(yè)板指數(shù))ts.get_hist_data("cyb")# 宏觀數(shù)據(jù)(居民消費(fèi)指數(shù))ts.get_cpi()# 獲取分筆數(shù)據(jù)ts.get_tick_data('000001', date='2018-10-08', src='tt')
3.3 數(shù)據(jù)預(yù)處理
3.3.1 統(tǒng)計(jì)股票的交易日量眾數(shù)
import numpy as np
yaxis = list()for i in listdir:
? ?stock = pd.read_csv("financial_data\\price_logreturn\\"+i)
? ?yaxis.append(len(stock['logreturn']))
counts = np.bincount(yaxis)
np.argmax(counts)
3.3.2 計(jì)算股票對(duì)數(shù)收益
股票對(duì)數(shù)收益及皮爾遜相關(guān)系數(shù)的計(jì)算公式:

import pandas as pdimport numpy as npimport osimport math
listdir = os.listdir("financial_data\\price")for l in listdir:
? stock = pd.read_csv('financial_data\\price\\'+l)
? stock['index'] = [1]* len(stock['close'])
? stock['next_close'] = stock.groupby('index')['close'].shift(-1)
? stock = stock.drop(index=stock.index[-1])
? logreturn = list() ? for i in stock.index:
? ? ? logreturn.append(math.log(stock['next_close'][i]/stock['close'][i]))
? stock['logreturn'] = logreturn
? stock.to_csv("financial_data\\price_logreturn\\"+l,index=False)
3.3.3 股票間對(duì)數(shù)收益率相關(guān)系數(shù)
from math import sqrtdef multipl(a,b):
? sumofab=0.0
? for i in range(len(a)):
? ? ? temp=a[i]*b[i]
? ? ? sumofab+=temp ? return sumofabdef corrcoef(x,y):
? n=len(x) ? #求和
? sum1=sum(x)
? sum2=sum(y) ? #求乘積之和
? sumofxy=multipl(x,y) ? #求平方和
? sumofx2 = sum([pow(i,2) for i in x])
? sumofy2 = sum([pow(j,2) for j in y])
? num=sumofxy-(float(sum1)*float(sum2)/n) ? #計(jì)算皮爾遜相關(guān)系數(shù)
? den=sqrt((sumofx2-float(sum1**2)/n)*(sumofy2-float(sum2**2)/n)) ? return num/den
由于原始數(shù)據(jù)達(dá)百萬(wàn)條,為節(jié)省計(jì)算量?jī)H選取前300個(gè)股票進(jìn)行關(guān)聯(lián)性分析
listdir = os.listdir("financial_data\\300stock_logreturn")
s1 = list()
s2 = list()
corr = list()for i in listdir: ? for j in listdir:
? ? ? stocka = pd.read_csv("financial_data\\300stock_logreturn\\"+i)
? ? ? stockb = pd.read_csv("financial_data\\300stock_logreturn\\"+j) ? ? ? if len(stocka['logreturn']) == 242 and len(stockb['logreturn']) == 242:
? ? ? ? ? s1.append(str(i)[:10])
? ? ? ? ? s2.append(str(j)[:10])
? ? ? ? ? corr.append(corrcoef(stocka['logreturn'],stockb['logreturn']))
? ? ? ? ? print(str(i)[:10],str(j)[:10],corrcoef(stocka['logreturn'],stockb['logreturn']))
corrdf = pd.DataFrame()
corrdf['s1'] = s1
corrdf['s2'] = s2
corrdf['corr'] = corr
corrdf.to_csv("financial_data\\corr.csv")
4 搭建金融知識(shí)圖譜
安裝第三方庫(kù)
pip install py2neo
4.1 基于python連接
具體代碼可參考3.1 python操作neo4j-連接
from pandas import DataFramefrom py2neo import Graph,Node,Relationship,NodeMatcherimport pandas as pdimport numpy as npimport os# 連接Neo4j數(shù)據(jù)庫(kù)graph = Graph('http://localhost:7474/db/data/',username='neo4j',password='neo4j')
4.2 讀取數(shù)據(jù)
stock = pd.read_csv('stock_basic.csv',encoding="gbk")
holder = pd.read_csv('holders.csv')
concept_num = pd.read_csv('concept.csv')
concept = pd.read_csv('stock_concept.csv')
sh = pd.read_csv('sh.csv')
sz = pd.read_csv('sz.csv')
corr = pd.read_csv('corr.csv')
4.3 填充和去重
stock['行業(yè)'] = stock['行業(yè)'].fillna('未知')
holder = holder.drop_duplicates(subset=None, keep='first', inplace=False)
4.4 創(chuàng)建實(shí)體
概念、股票、股東、股通
sz = Node('深股通',名字='深股通')
graph.create(sz) ?
sh = Node('滬股通',名字='滬股通')
graph.create(sh) ?for i in concept_num.values:
? a = Node('概念',概念代碼=i[1],概念名稱=i[2])
? print('概念代碼:'+str(i[1]),'概念名稱:'+str(i[2]))
? graph.create(a)for i in stock.values:
? a = Node('股票',TS代碼=i[1],股票名稱=i[3],行業(yè)=i[4])
? print('TS代碼:'+str(i[1]),'股票名稱:'+str(i[3]),'行業(yè):'+str(i[4]))
? graph.create(a)for i in holder.values:
? a = Node('股東',TS代碼=i[0],股東名稱=i[1],持股數(shù)量=i[2],持股比例=i[3])
? print('TS代碼:'+str(i[0]),'股東名稱:'+str(i[1]),'持股數(shù)量:'+str(i[2]))
? graph.create(a)

4.5 創(chuàng)建關(guān)系
股票-股東、股票-概念、股票-公告、股票-股通
matcher = NodeMatcher(graph)for i in holder.values: ? ?
? a = matcher.match("股票",TS代碼=i[0]).first()
? b = matcher.match("股東",TS代碼=i[0]) ? for j in b:
? ? ? r = Relationship(j,'參股',a)
? ? ? graph.create(r)
? ? ? print('TS',str(i[0]))for i in concept.values:
? a = matcher.match("股票",TS代碼=i[3]).first()
? b = matcher.match("概念",概念代碼=i[1]).first() ? if a == None or b == None: ? ? ? continue
? r = Relationship(a,'概念屬于',b)
? graph.create(r)
noticesdir = os.listdir("notices\\")for n in noticesdir:
? notice = pd.read_csv("notices\\"+n,encoding="utf_8_sig")
? notice['content'] = notice['content'].fillna('空白') ? for i in notice.values:
? ? ? a = matcher.match("股票",TS代碼=i[0]).first()
? ? ? b = Node('公告',日期=i[1],標(biāo)題=i[2],內(nèi)容=i[3])
? ? ? graph.create(b)
? ? ? r = Relationship(a,'發(fā)布公告',b)
? ? ? graph.create(r)
? ? ? print(str(i[0]))for i in sz.values:
? a = matcher.match("股票",TS代碼=i[0]).first()
? b = matcher.match("深股通").first()
? r = Relationship(a,'成分股屬于',b)
? graph.create(r)
? print('TS代碼:'+str(i[1]),'--深股通')for i in sh.values:
? a = matcher.match("股票",TS代碼=i[0]).first()
? b = matcher.match("滬股通").first()
? r = Relationship(a,'成分股屬于',b)
? graph.create(r)
? print('TS代碼:'+str(i[1]),'--滬股通')# 構(gòu)建股票間關(guān)聯(lián)corr = pd.read_csv("corr.csv")for i in corr.values:
? a = matcher.match("股票",TS代碼=i[1][:-1]).first()
? b = matcher.match("股票",TS代碼=i[2][:-1]).first()
? r = Relationship(a,str(i[3]),b)
? graph.create(r)
? print(i)

5 數(shù)據(jù)可視化查詢
基于Crypher語(yǔ)言,以平安銀行為例進(jìn)行可視化查詢。
5.1 查看所有關(guān)聯(lián)實(shí)體
match p=(m)-[]->(n) where m.股票名稱="平安銀行" or n.股票名稱="平安銀行" return p;

5.2 限制顯示數(shù)量
計(jì)算股票間對(duì)數(shù)收益率的相關(guān)系數(shù)后,查看與平安銀行股票相關(guān)聯(lián)的實(shí)體
match p=(m)-[]->(n) where m.股票名稱="平安銀行" or n.股票名稱="平安銀行" return p limit 300;

5.3 指定股票間對(duì)數(shù)收益率相關(guān)系數(shù)
match p=(m)-[]->(n) where m.股票名稱="平安銀行" and n.股票名稱="萬(wàn)科A" return p;

碼源鏈接見(jiàn)文末跳轉(zhuǎn)
[文末鏈接跳轉(zhuǎn)] :https://blog.csdn.net/sinat_39620217/article/details/131608595
更多優(yōu)質(zhì)內(nèi)容請(qǐng)關(guān)注公號(hào)&知乎:汀丶人工智能;會(huì)提供一些相關(guān)的資源和優(yōu)質(zhì)文章,免費(fèi)獲取閱讀。