之前看過(guò)米哥的一篇文章《知識(shí)圖譜及金融相關(guān)》,文章主要是一些介紹,所以一直打算寫(xiě)個(gè)關(guān)于股票方面圖譜的東西。關(guān)于知識(shí)圖譜,概念有很多,具體大家可自行百度,我這里只摘錄米哥之前的文章里面的概念。
什么是知識(shí)圖譜? 直接了當(dāng)?shù)恼f(shuō),知識(shí)圖譜是人工智能技術(shù)的重要組成部分,它是具有語(yǔ)義處理與信息互聯(lián)互通能力的知識(shí)庫(kù)。通常在智能搜索、機(jī)器人聊天、智能問(wèn)答以及智能推薦方面有著廣泛的應(yīng)用。 今天我們學(xué)習(xí)和探討的知識(shí)圖譜,實(shí)際是Google公司在2012年提出的為了提高搜索引擎能力,增強(qiáng)用戶的搜索效率效果以及搜索體驗(yàn)的一種技術(shù)實(shí)踐。 而在10年前,就已經(jīng)提出了語(yǔ)義網(wǎng)的概念,呼吁業(yè)界推廣并完善利用本體(Ontology)模型來(lái)形式化表達(dá)數(shù)據(jù)中的隱含語(yǔ)義,便于知識(shí)的高效呈現(xiàn)和利用。知識(shí)圖譜技術(shù)的出現(xiàn)正是基于以上相關(guān)研究,是對(duì)語(yǔ)義網(wǎng)相關(guān)技術(shù)和標(biāo)準(zhǔn)的提升。 知識(shí)圖譜中的一些概念要素:
實(shí)體:是指具有可區(qū)別性且獨(dú)立存在的某種事物(有點(diǎn)像面向?qū)ο缶幊汤锏腛bject)。如某一種動(dòng)物、某一個(gè)城市、某一種水果、某一類商品等等。世界萬(wàn)物有具體事物組成,此指實(shí)體。實(shí)體是知識(shí)圖譜中的最基本元素,不同的實(shí)體間存在不同的關(guān)系。
語(yǔ)義類(概念):概念主要指集合、類別、對(duì)象類型、事物的種類,例如人物、地理等。 屬性:主要指對(duì)象可能具有的屬性、特征、特性、特點(diǎn)以及參數(shù),例如國(guó)籍、生日等。
屬性值:主要指對(duì)象指定屬性的值,例如國(guó)籍對(duì)應(yīng)的“中國(guó)”、生日對(duì)應(yīng)1988-09-08等。每個(gè)屬性-屬性值對(duì)可用來(lái)刻畫(huà)實(shí)體的內(nèi)在特性。
關(guān)系:用來(lái)連接兩個(gè)實(shí)體,刻畫(huà)它們之間的關(guān)聯(lián)。形式化為一個(gè)函數(shù),它把kk個(gè)點(diǎn)映射到一個(gè)布爾值。在知識(shí)圖譜上,關(guān)系則是一個(gè)把kk個(gè)圖節(jié)點(diǎn)(實(shí)體、語(yǔ)義類、屬性值)映射到布爾值的函數(shù)。 知識(shí)圖譜中一般用三元組的方式來(lái)表達(dá),三元組的基本形式主要包括(實(shí)體1-關(guān)系-實(shí)體2)和(實(shí)體-屬性-屬性值)等。每個(gè)實(shí)體可用一個(gè)全局唯一確定的ID來(lái)標(biāo)識(shí),每個(gè)屬性-屬性值對(duì)可用來(lái)刻畫(huà)實(shí)體的內(nèi)在特性。 這個(gè)是重點(diǎn),關(guān)注Tushare有一段時(shí)間了,想寫(xiě)點(diǎn)什么東西,一直沒(méi)有時(shí)間。 Tushare免費(fèi)提供各類金融數(shù)據(jù)和區(qū)塊鏈數(shù)據(jù),這篇文章用的就是Tushare的數(shù)據(jù)做展示。Tushare支持很多種類型的數(shù)據(jù),限于篇幅限制,我只能找最基礎(chǔ)的屬性建立一個(gè)簡(jiǎn)單的圖譜。 屬性為,股票所屬的地區(qū)(area),所屬的工業(yè)分類(industry),所屬的版塊(market)。 獲取該數(shù)據(jù)的API接口說(shuō)明 : 我們可以通過(guò)Python API獲取數(shù)據(jù),代碼如下: import tushare as ts
ts.set_token('...') # token需要注冊(cè)之后,然后獲取到的token,這里就不寫(xiě)明我的token了 pro = ts.pro_api() df = pro.stock_basic(exchange_id='', list_status='L', fields='ts_code,symbol, name,area,industry,fullname, enname, market,exchange, curr_type, list_status, list_date, delist_date,is_hs')
# 股票的基本信息,這里面有三個(gè)股票的基本信息,地區(qū)(area),工業(yè)類別(industry),市場(chǎng)(market)
此處推薦另一個(gè)不錯(cuò)的開(kāi)源項(xiàng)目InteractiveGraph,感謝原作者。 以下這是原項(xiàng)目的一個(gè)截圖,數(shù)據(jù)是紅樓夢(mèng)的人物關(guān)系。 InteractiveGraph數(shù)據(jù)格式 完整的數(shù)據(jù)比較大,此處只寫(xiě)個(gè)簡(jiǎn)單的數(shù)據(jù)格式。 我們需要把Tushare返回的數(shù)據(jù)結(jié)構(gòu),改造為InteractiveGraph認(rèn)識(shí)的數(shù)據(jù)結(jié)構(gòu)。 import json import os import uuid
import pandas as pd
from data_hive import BASIC_DATA_STORE_FOLDER, GRAPH_DATA_FULLNAME
def __init_graph_categories(): ''' 將基礎(chǔ)數(shù)據(jù)合并為圖數(shù)據(jù) :return: ''' # 加載地區(qū)數(shù)據(jù),工業(yè)指數(shù),概念
industry_fullname = os.path.join(os.environ['STOCK_DATA'], 'data_hive', 'basic_data', 'industry.csv') industry_series = pd.Series.from_csv(industry_fullname) industry_list = industry_series.tolist() concept_fullname = os.path.join(os.environ['STOCK_DATA'], 'data_hive', 'property_data', 'concept.csv') concept_dataframe = pd.read_csv(concept_fullname) concept_list = concept_dataframe['name'].tolist()
dic_categories = dict()
for concept in concept_list: dic_categories[concept] = concept for industry in industry_list: dic_categories[industry] = industry return dic_categories
def create_graph_data_job(): dic_categories = {'Stock': '股票', 'Area': '地區(qū)', 'Industry': '工業(yè)分類', 'Market': '市場(chǎng)'} basic_fullname = os.path.join(BASIC_DATA_STORE_FOLDER, 'basic.csv') nodes = [] edges = [] basic_dataframe = pd.read_csv(basic_fullname)
dic_area_id = __get_area_nodes(basic_dataframe, nodes) dic_industry_id = __get_industry_nodes(basic_dataframe, nodes) dic_market_id = __get_market_nodes(basic_dataframe, nodes) __get_stock_nodes(basic_dataframe, nodes)
__get_stock_edges_with_area(basic_dataframe, dic_area_id, edges) __get_stock_edges_with_industry(basic_dataframe, dic_industry_id, edges) __get_stock_edges_with_market(basic_dataframe, dic_market_id, edges)
dic = dict() dic['categories'] = dic_categories dic['data'] = dict() dic['data']['nodes'] = nodes dic['data']['edges'] = edges if os.path.exists(GRAPH_DATA_FULLNAME): os.remove(GRAPH_DATA_FULLNAME) with open(GRAPH_DATA_FULLNAME, 'w') as f: json.dump(dic, f, ensure_ascii=False)
InteractiveGraph數(shù)據(jù)格式: { 'categories': { 'Area': '地區(qū)', 'Market': '市場(chǎng)', 'Industry': '工業(yè)分類', 'Stock': '股票' }, 'data': { 'nodes': [ { 'info': '', 'value': 288, // value是該分類,有多少支股票 'label': '上海', 'categories': ['Area'], 'id': 186063112711690369465957503787509417235 }, { 'info': '', 'value': 130, 'label': '專用機(jī)械', 'categories': ['Industry'], 'id': 186084073314365143238378290935655761171 }, { 'info': '', 'value': 931, 'label': '中小板', 'categories': ['Market'], 'id': 186109520132514124716557123458730493203 }, { 'info': '', 'value': 1, 'label': '平安銀行', 'categories': ['Stock'], 'id': '000001.SZ' }, ... ], 'edges': [ { 'label': 'Area', 'from': '000001.SZ', 'to': 186078121060971771585817877132061902099, 'id': 187756920664596399771974970653013640467 }, ... ] } }
import os
from flask import Blueprint, request, redirect, render_template from jinja2 import Environment, FileSystemLoader
graph = Blueprint('graph', __name__)
@graph.route('/graph/relation', methods=['GET']) def get_relation(): ''' :return: ''' logger.info('獲取關(guān)系') stock1 = request.args.get('stock1') stock2 = request.args.get('stock2') return render_template('relation.html', stock1=stock1, stock2=stock2)
app = Flask(__name__) app.register_blueprint(graph)
if __name__ == '__main__': app.run()
運(yùn)行Flask服務(wù)后,我們可以在地址欄里輸入地址,可以傳入兩個(gè)股票作為參數(shù)。
|