tushare數據建立圖譜

1.圖譜

之前看過米哥的一篇文章《知識圖譜及金融相關》,文章主要是一些介紹,所以一直打算寫個關於股票方面圖譜的東西。關於知識圖譜,概念有很多,具體大家可自行百度,我這裏只摘錄米哥之前的文章裏面的概念。

什麼是知識圖譜?
直接了當的說,知識圖譜是人工智能技術的重要組成部分,它是具有語義處理與信息互聯互通能力的知識庫。通常在智能搜索、機器人聊天、智能問答以及智能推薦方面有着廣泛的應用。
今天我們學習和探討的知識圖譜,實際是Google公司在2012年提出的爲了提高搜索引擎能力,增強用戶的搜索效率效果以及搜索體驗的一種技術實踐。
而在10年前,就已經提出了語義網的概念,呼籲業界推廣並完善利用本體(Ontology)模型來形式化表達數據中的隱含語義,便於知識的高效呈現和利用。知識圖譜技術的出現正是基於以上相關研究,是對語義網相關技術和標準的提升。

知識圖譜中的一些概念要素:
實體:是指具有可區別性且獨立存在的某種事物(有點像面向對象編程裏的Object)。如某一種動物、某一個城市、某一種水果、某一類商品等等。世界萬物有具體事物組成,此指實體。實體是知識圖譜中的最基本元素,不同的實體間存在不同的關係。
語義類(概念):概念主要指集合、類別、對象類型、事物的種類,例如人物、地理等。
屬性:主要指對象可能具有的屬性、特徵、特性、特點以及參數,例如國籍、生日等。
屬性值:主要指對象指定屬性的值,例如國籍對應的“中國”、生日對應1988-09-08等。每個屬性-屬性值對可用來刻畫實體的內在特性。
關係:用來連接兩個實體,刻畫它們之間的關聯。形式化爲一個函數,它把kk個點映射到一個布爾值。在知識圖譜上,關係則是一個把kk個圖節點(實體、語義類、屬性值)映射到布爾值的函數。

知識圖譜中一般用三元組的方式來表達,三元組的基本形式主要包括(實體1-關係-實體2)和(實體-屬性-屬性值)等。每個實體可用一個全局唯一確定的ID來標識,每個屬性-屬性值對可用來刻畫實體的內在特性。

2.利用tushare數據建立圖譜

這個是重點,關注tushare有一段時間了,一直想寫點什麼東西,一直沒有時間。tushare免費提供各類金融數據和區塊鏈數據,這篇文章用的就是tushare的數據,對米哥表示感謝。tushare支持很多的數據,限於篇幅限制,我只能找最基礎的屬性建立一個簡單的圖譜。
屬性爲,股票所屬的地區(area),所屬的工業分類(industry),所屬的版塊(market)。
獲取該數據的API接口說明
在這裏插入圖片描述
紅框爲需要用到的分類屬性
在這裏插入圖片描述

2.1. 利用python api獲取數據

import tushare as ts
ts.set_token('...')  # token需要註冊之後,然後獲取到的token,這裏就不寫明我的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')  # 股票的基本信息,這裏面有三個股票的基本信息,地區(area),工業類別(industry),市場(market)

具體的API接口請參考數據接口

3.利用InteractiveGraph建立圖譜

此處推薦另一個不錯的開源項目InteractiveGraph,感謝原作者。
demo鏈接
這是原項目的一個截圖。數據是紅樓夢。
在這裏插入圖片描述

3.1. InteractiveGraph數據格式

完整的數據比較大,此處只寫個簡單的數據格式。
我們需要把tushare返回的數據結構,改造爲InteractiveGraph認識的數據結構。

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():
    """
    將基礎數據合併爲圖數據
    :return:
    """
    # 加載地區數據,工業指數,概念

    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': '地區', 'Industry': '工業分類', 'Market': '市場'}
    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)


def __get_area_nodes(basic_dataframe, nodes):
    dict_area_id = dict()
    for name, group in basic_dataframe.groupby('area'):
        dic_node = dict()
        dic_node['label'] = name
        dic_node['value'] = group.shape[0]
        dic_node['id'] = int(uuid.uuid1())
        dic_node['categories'] = ['Area']
        dic_node['info'] = ''
        dict_area_id[name] = dic_node['id']
        nodes.append(dic_node)
    return dict_area_id


def __get_industry_nodes(basic_dataframe, nodes):
    dict_industry_id = dict()
    for name, group in basic_dataframe.groupby('industry'):
        dic_node = dict()
        dic_node['label'] = name
        dic_node['value'] = group.shape[0]
        dic_node['id'] = int(uuid.uuid1())
        dic_node['categories'] = ['Industry']
        dic_node['info'] = ''
        dict_industry_id[name] = dic_node['id']
        nodes.append(dic_node)
    return dict_industry_id


def __get_market_nodes(basic_dataframe, nodes):
    dict_market_id = dict()
    for name, group in basic_dataframe.groupby('market'):
        dic_node = dict()
        dic_node['label'] = name
        dic_node['value'] = group.shape[0]
        dic_node['id'] = int(uuid.uuid1())
        dic_node['categories'] = ['Market']
        dic_node['info'] = ''
        dict_market_id[name] = dic_node['id']
        nodes.append(dic_node)
    return dict_market_id


def __get_stock_nodes(basic_dataframe, nodes):
    for i in range(basic_dataframe.shape[0]):
        dic_node = dict()
        dic_node['label'] = basic_dataframe.iloc[i]['name']
        dic_node['value'] = 1
        dic_node['id'] = basic_dataframe.iloc[i]['ts_code']
        dic_node['info'] = ''
        dic_node['categories'] = ['Stock']
        nodes.append(dic_node)


def __get_stock_edges_with_area(basic_dataframe, dic_area_id, edges):
    for i in range(basic_dataframe.shape[0]):
        edge = dict()
        edge['id'] = int(uuid.uuid1())
        edge['label'] = 'Area'
        edge['from'] = basic_dataframe.iloc[i]['ts_code']
        edge['to'] = dic_area_id[basic_dataframe.iloc[i]['area']]
        edges.append(edge)


def __get_stock_edges_with_industry(basic_dataframe, dic_area_id, edges):
    for i in range(basic_dataframe.shape[0]):
        edge = dict()
        edge['id'] = int(uuid.uuid1())
        edge['label'] = 'Industry'
        edge['from'] = basic_dataframe.iloc[i]['ts_code']
        edge['to'] = dic_area_id[basic_dataframe.iloc[i]['industry']]
        edges.append(edge)


def __get_stock_edges_with_market(basic_dataframe, dic_area_id, edges):
    for i in range(basic_dataframe.shape[0]):
        edge = dict()
        edge['id'] = int(uuid.uuid1())
        edge['label'] = 'Market'
        edge['from'] = basic_dataframe.iloc[i]['ts_code']
        edge['to'] = dic_area_id[basic_dataframe.iloc[i]['market']]
        edges.append(edge)


if __name__ == '__main__':
    create_graph_data_job()

InteractiveGraph數據格式:

{
	"categories": 
	{
		"Area": "地區",
		"Market": "市場",
		"Industry": "工業分類",
		"Stock": "股票"
	},
	"data":
	{
		"nodes": 
		[
			{
				"info": "",
				"value": 288,  // value是該分類,有多少支股票
				"label": "上海",
				"categories": ["Area"],
				"id": 186063112711690369465957503787509417235
			},
			{
				"info": "",
				"value": 130,
				"label": "專用機械",
				"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
			}, 
			...
		]
	}
}

3.2 flask發佈服務

3.2.1 flask代碼

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('獲取關係')
    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()

4.效果

歡迎實驗,此鏈接爲GET請求,可以自己寫兩個股票名稱
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章