-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
115 lines (84 loc) · 3.45 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import pandas as pd
import streamlit as st
from src.config import APP_PAGE_HEADER
from src.utils import search_df
APP_PAGE_HEADER()
@st.cache(allow_output_mutation=True)
class LoadData:
train: pd.DataFrame = pd.read_csv("data/train.csv")
train = train.sample(frac=1).reset_index(drop=True) # shuffle data
test: pd.DataFrame = pd.read_csv("data/test.csv")
titles: pd.DataFrame = pd.read_csv("data/titles.csv")
# add code titles to train data
merged = train.merge(titles, left_on="context", right_on="code")
train_df = merged[['id', 'anchor', 'context', 'target', 'title', 'score']].copy()
# add relations / edges for knowledge graph
train_kg: pd.DataFrame = train_df.copy()
train_kg['relation'] = train_kg['context'] + " || " + train_kg['title'] + " || " + train_kg['score'].astype(str)
class App:
def __init__(self):
self.data = LoadData()
def run(self, debug=False):
self.render_header(debug)
self.render_body(debug)
self.render_footer(debug)
def render_header(self, *args, **kwargs):
pass
@staticmethod
def render_body(*args, **kwargs):
Helper().display_train_data()
Helper().visualize()
def render_footer(self, *args, **kwargs):
pass
class Helper(App):
def display_train_data(self):
data = self.data.train_df
st.write(f"> Train data `{data.shape[0]}` rows")
filter_ = st.text_input("search phrases", "")
if filter_:
data = search_df(data, filter_)
st.write(data)
def visualize(self, *args, **kwargs):
st.subheader("Visualize Phrases as a Network Graph")
data = self.data.train_kg
# filter data for visualization
# -- sampling
MAX_EDGES = 200
sample = data[:MAX_EDGES]
st1, st2 = st.columns(2)
score = st1.selectbox("visualize phrases by similarity score", [""] + data["score"].unique().tolist())
if score:
sample = data[data["score"] == float(score)][:MAX_EDGES]
filter_ = st2.text_input("search term to visualize matching phrases")
if filter_:
sample = search_df(data, filter_)[:MAX_EDGES]
# create graph
nodes = list(sample["anchor"].unique()) + list(sample["target"].unique())
edges = [(h, t) for h, t in zip(sample["anchor"].tolist(), sample["target"].tolist())]
labels = sample["relation"].tolist()
edge_labels = dict(zip(edges, labels))
# create PyVis network from the graph data
self.pyvis_network(nodes, edge_labels)
st.write(f"> the visualized sample size: {sample.shape[0]}")
st.write(sample)
def pyvis_network(self, nodes, edge_labels):
from stvis import pv_static
g = self.build_network(edge_labels, nodes)
pv_static(g)
@staticmethod
@st.experimental_singleton
def build_network(edge_labels, nodes):
# src: https://stackoverflow.com/a/67279471/2839786
from pyvis.network import Network
g = Network(height="800px", width="1400px", heading="U.S. Patent Phrase/Context Network",
bgcolor="#bbbffz") # notebook=True,
for node in nodes:
g.add_node(node)
for e in edge_labels:
n1, n2 = e[0], e[1]
label = edge_labels[e]
g.add_edge(n1, n2, title=label, show_edge_weights=True) # weight 42
return g
if __name__ == "__main__":
app = App()
app.run(debug=True)