edichief commited on
Commit
8ab7af3
1 Parent(s): 5511f86

Split apps

Browse files
Files changed (7) hide show
  1. README.md +1 -1
  2. app.py +135 -12
  3. requirements.txt +0 -5
  4. support_functions.py +56 -34
  5. visualize_dataset.py +0 -137
  6. visualize_pipeline.py +0 -157
  7. viz.html +100 -4
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Healthsea
3
  emoji: 🪐
4
  colorFrom: yellow
5
  colorTo: pink
1
  ---
2
+ title: HealthseaDemo
3
  emoji: 🪐
4
  colorFrom: yellow
5
  colorTo: pink
app.py CHANGED
@@ -1,11 +1,13 @@
1
  import streamlit as st
2
- from visualize_dataset import visualize_dataset
3
- from visualize_pipeline import visualize_pipeline
 
4
 
5
  # Header
6
  with open("style.css") as f:
7
  st.markdown("<style>" + f.read() + "</style>", unsafe_allow_html=True)
8
 
 
9
  st.title("Welcome to Healthsea 🪐")
10
 
11
  intro, jellyfish = st.columns(2)
@@ -15,23 +17,144 @@ intro.subheader("Create easier access to health✨")
15
 
16
  jellyfish.image("data/img/Jellymation.gif")
17
  intro.markdown(
18
- """Healthsea is a spaCy v3 pipeline that is capable of analyzing user-generated reviews to supplementary products by extracting their effects on health.
19
- The analysis is based on the written-text and context from the reviews."""
20
  )
21
  intro.markdown(
22
- """With this app, you're able to explore the pipeline and its analysis on productive data. You can choose between two different apps `Visualize dataset` and `Visualize pipeline`.
23
  """
24
  )
25
- intro.markdown(
26
- """The code for Healthsea is provided in this [github repository](https://github.com/thomashacker/healthsea) and if you're interested you can read more about the project in our [blog post]().
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  )
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  st.markdown("""---""")
31
 
32
- app_type = st.selectbox("Choose app", ["Visualize dataset", "Visualize pipeline"])
 
 
33
 
34
- if app_type == "Visualize dataset":
35
- visualize_dataset()
36
- else:
37
- visualize_pipeline()
 
 
 
1
  import streamlit as st
2
+ from pathlib import Path
3
+ import json
4
+ from support_functions import HealthseaSearch
5
 
6
  # Header
7
  with open("style.css") as f:
8
  st.markdown("<style>" + f.read() + "</style>", unsafe_allow_html=True)
9
 
10
+ # Intro
11
  st.title("Welcome to Healthsea 🪐")
12
 
13
  intro, jellyfish = st.columns(2)
17
 
18
  jellyfish.image("data/img/Jellymation.gif")
19
  intro.markdown(
20
+ """Healthsea is an end-to-end spaCy v3 pipeline for analyzing user reviews to supplementary products and extracting their potential effects on health."""
 
21
  )
22
  intro.markdown(
23
+ """The code for Healthsea is provided in this [github repository](https://github.com/thomashacker/healthsea). For more information about Healthsea, you can visit our [blog post](https://explosion.ai/).
24
  """
25
  )
26
+
27
+ st.write(
28
+ """This app visualizes the results of Healthsea on a dataset of up to 1 million reviews to 10.000 products. You can use the app to search for any health aspect, whether it's a disease (e.g. joint pain) or a positive state of health (e.g. energy), the app returns a list of products and substances.
29
+ """
30
+ )
31
+
32
+ st.warning("""Healthsea is an experimental project and the results should not be used as a foundation for solving health problems. Nor do we want to give the impression that supplements are the answer to anyone's health issues.""")
33
+
34
+ # Configuration
35
+ health_aspect_path = Path("data/health_aspects.json")
36
+ product_path = Path("data/products.json")
37
+ condition_path = Path("data/condition_vectors.json")
38
+ benefit_path = Path("data/benefit_vectors.json")
39
+
40
+ # Load data
41
+ @st.cache(allow_output_mutation=True)
42
+ def load_data(
43
+ _health_aspect_path: Path,
44
+ _product_path: Path,
45
+ _condition_path: Path,
46
+ _benefit_path: Path,
47
+ ):
48
+ with open(_health_aspect_path) as reader:
49
+ health_aspects = json.load(reader)
50
+ with open(_product_path) as reader:
51
+ products = json.load(reader)
52
+ with open(_condition_path) as reader:
53
+ conditions = json.load(reader)
54
+ with open(_benefit_path) as reader:
55
+ benefits = json.load(reader)
56
+ return health_aspects, products, conditions, benefits
57
+
58
+
59
+ # Functions
60
+ def kpi(n, text):
61
+ html = f"""
62
+ <div class='kpi'>
63
+ <h1 class='kpi_header'>{n}</h1>
64
+ <span>{text}</span>
65
+ </div>
66
  """
67
+ return html
68
+
69
+
70
+ def central_text(text):
71
+ html = f"""<h2 class='central_text'>{text}</h2>"""
72
+ return html
73
+
74
+ # Loading data
75
+ health_aspects, products, conditions, benefits = load_data(
76
+ health_aspect_path, product_path, condition_path, benefit_path
77
+ )
78
+ search_engine = HealthseaSearch(health_aspects, products, conditions, benefits)
79
+
80
+ # KPI
81
+ st.markdown("""---""")
82
+
83
+ st.markdown(central_text("🎀 Dataset"), unsafe_allow_html=True)
84
+
85
+ kpi_products, kpi_reviews, kpi_condition, kpi_benefit = st.columns(4)
86
+
87
+ def round_to_k(value):
88
+ return str(round(value/1000,1))+"k"
89
+
90
+ kpi_products.markdown(kpi(round_to_k(len(products)), "Products"), unsafe_allow_html=True)
91
+ kpi_reviews.markdown(kpi(round_to_k(int(933240)), "Reviews"), unsafe_allow_html=True)
92
+ kpi_condition.markdown(kpi(round_to_k(len(conditions)), "Conditions"), unsafe_allow_html=True)
93
+ kpi_benefit.markdown(kpi(round_to_k(len(benefits)), "Benefits"), unsafe_allow_html=True)
94
+
95
+ st.markdown("""---""")
96
+
97
+ # Expander
98
+ show_conditions, show_benefits = st.columns(2)
99
+
100
+ with show_conditions.expander("Top mentioned Conditions"):
101
+ st.write(search_engine.get_all_conditions_df())
102
+
103
+ with show_benefits.expander("Top mentioned Benefits"):
104
+ st.write(search_engine.get_all_benefits_df())
105
+
106
+ st.markdown("""---""")
107
+
108
+ # Search
109
+ search = st.text_input(label="Search for an health aspect", value="joint pain")
110
+ n = st.slider("Show top n results", min_value=10, max_value=1000, value=25)
111
+
112
+ st.markdown("""---""")
113
+ st.markdown(central_text("🧃 Products"), unsafe_allow_html=True)
114
+
115
+ st.info("""The product score is based on the results of Healthsea. Variables used for the score are: health effect prediction, product rating, helpful count and whether the review is considered a 'fake review'. """)
116
+
117
+ # DataFrame
118
+ st.write(search_engine.get_products_df(search, n))
119
+
120
+ # KPI & Alias
121
+ aspect_alias = search_engine.get_aspect(search)["alias"]
122
+
123
+ kpi_product_mentions, kpi_alias = st.columns(2)
124
+
125
+ kpi_product_mentions.markdown(kpi(len(search_engine.get_aspect(search)["products"]), "Products"), unsafe_allow_html=True)
126
+
127
+
128
+ kpi_alias.markdown(
129
+ kpi(len(aspect_alias), "Similar health aspects"),
130
+ unsafe_allow_html=True,
131
  )
132
 
133
+ depth = st.slider("Depth", min_value=0, max_value=5, value=2)
134
+
135
+ recursive_alias, recursive_edges = search_engine.get_recursive_alias(search,0,{},[],depth)
136
+
137
+ vectors = []
138
+ main_aspect = search_engine.get_aspect_meta(search)
139
+ vectors.append((main_aspect["name"], main_aspect["vector"]))
140
+ for aspect in aspect_alias:
141
+ current_aspect = search_engine.get_aspect_meta(aspect)
142
+ vectors.append((current_aspect["name"], current_aspect["vector"]))
143
+ st.markdown("\n")
144
+ st.info("""Health aspects with a high similarity (>=90%) are clustered together.""")
145
+ #search_engine.pyvis(vectors)
146
+ search_engine.pyvis2(recursive_alias,recursive_edges)
147
+
148
  st.markdown("""---""")
149
 
150
+ # Substances
151
+ st.markdown(central_text("🍯 Substances"), unsafe_allow_html=True)
152
+ st.info("""Substance scores are based on product scores""")
153
 
154
+ # DataFrame
155
+ st.write(search_engine.get_substances_df(search, n))
156
+ kpi_substances, empty = st.columns(2)
157
+ kpi_substances.markdown(
158
+ kpi(len(search_engine.get_aspect(search)["substance"]), "Substances"),
159
+ unsafe_allow_html=True,
160
+ )
requirements.txt CHANGED
@@ -1,9 +1,4 @@
1
  streamlit>=1.2.0
2
- spacy-streamlit>=1.0.2
3
- spacy>=3.1.4
4
- benepar>=0.2.0
5
  pyvis
6
  numpy
7
  pandas
8
-
9
- https://huggingface.co/edichief/en_healthsea/resolve/main/en_healthsea-any-py3-none-any.whl
1
  streamlit>=1.2.0
 
 
 
2
  pyvis
3
  numpy
4
  pandas
 
 
support_functions.py CHANGED
@@ -9,6 +9,20 @@ from numpy.linalg import norm
9
  from pyvis.network import Network
10
  import streamlit.components.v1 as components
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  class HealthseaSearch:
14
  def __init__(self, _health_aspects, _products, _conditions, _benefits):
@@ -145,6 +159,48 @@ class HealthseaSearch:
145
  # net.add_edge(vectors[0][0],_vector[0], weight=sim, value=sim*0.1, title=sim)
146
 
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  net.save_graph("viz.html")
149
  HtmlFile = open("viz.html", 'r', encoding='utf-8')
150
  source_code = HtmlFile.read()
@@ -256,7 +312,6 @@ class HealthseaSearch:
256
 
257
  return df
258
 
259
-
260
  def get_all_benefits(self):
261
  benefit_list = []
262
  for benefit_key in self.benefits:
@@ -292,36 +347,3 @@ class HealthseaSearch:
292
  df = df.astype(datatypes)
293
 
294
  return df
295
-
296
-
297
- class HealthseaPipe:
298
-
299
- # Get Clauses and their predictions
300
- def get_clauses(self, doc):
301
- clauses = []
302
- for clause in doc._.clauses:
303
- words = []
304
- spaces = []
305
- clause_slice = doc[clause["split_indices"][0] : clause["split_indices"][1]]
306
-
307
- if clause["has_ent"]:
308
- for token in clause_slice:
309
- if token.i == clause["ent_indices"][0]:
310
- words.append(
311
- clause["blinder"].replace(">", "").replace("<", "")
312
- )
313
- spaces.append(True)
314
- elif token.i not in range(
315
- clause["ent_indices"][0], clause["ent_indices"][1]
316
- ):
317
- words.append(token.text)
318
- spaces.append(token.whitespace_)
319
- clauses.append(Doc(doc.vocab, words=words, spaces=spaces))
320
-
321
- else:
322
- for token in clause_slice:
323
- words.append(token.text)
324
- spaces.append(token.whitespace_)
325
- clauses.append(Doc(doc.vocab, words=words, spaces=spaces))
326
-
327
- return clauses
9
  from pyvis.network import Network
10
  import streamlit.components.v1 as components
11
 
12
+ color_code_node = {
13
+ 0: '#4B9EFF',
14
+ 1: '#4BD4FF',
15
+ 2: '#3CDFCB',
16
+ 3: '#37DF8E',
17
+ 4: '#A0C159',
18
+ 5: '#CA804B',
19
+ 6: '#CA524B',
20
+ 7: '#CA4B97',
21
+ 8: '#C04BCA',
22
+ 9: '#5D4BCA',
23
+ 10: '#213ABA',
24
+ 11: '#0E6697',
25
+ }
26
 
27
  class HealthseaSearch:
28
  def __init__(self, _health_aspects, _products, _conditions, _benefits):
159
  # net.add_edge(vectors[0][0],_vector[0], weight=sim, value=sim*0.1, title=sim)
160
 
161
 
162
+ net.save_graph("viz.html")
163
+ HtmlFile = open("viz.html", 'r', encoding='utf-8')
164
+ source_code = HtmlFile.read()
165
+ components.html(source_code, height = 500, width=700)
166
+
167
+ # Experimental
168
+ def get_recursive_alias(self, _aspect, n, node_list, edge_list, _max):
169
+ aspect = self.get_aspect(_aspect)
170
+
171
+ aspect_name = aspect["name"].replace(" ","_")
172
+
173
+ if aspect_name not in node_list:
174
+ node_list[aspect_name] = {"level":n}
175
+
176
+ aspect_alias = aspect["alias"]
177
+
178
+ if len(aspect_alias) > 0 and n <= _max:
179
+ for alias in aspect_alias:
180
+ if alias not in node_list:
181
+ edge_list.append((aspect_name,alias,n))
182
+ self.get_recursive_alias(alias, n+1, node_list, edge_list,_max)
183
+
184
+ return node_list, edge_list
185
+ else:
186
+ return node_list, edge_list
187
+
188
+ def add_to_network(self, network, node_list, edge_list):
189
+ for node in node_list:
190
+ value = 100-(15*node_list[node]["level"])
191
+ network.add_node(node, label=node, color=color_code_node[node_list[node]["level"]], value=value, shape="dot", title = str(node_list[node]["level"]))
192
+
193
+ for edge in edge_list:
194
+ value = 1-(0.15*edge[2])
195
+ network.add_edge(edge[0], edge[1], value=value)
196
+
197
+ def pyvis2(self, node_list, edge_list):
198
+ net = Network(height='500px', width='700px', bgcolor="#0E1117", font_color="#ffffff")
199
+ net.barnes_hut(gravity=-2500-(len(node_list)*2))
200
+ net.set_edge_smooth("dynamic")
201
+
202
+ self.add_to_network(net, node_list, edge_list)
203
+
204
  net.save_graph("viz.html")
205
  HtmlFile = open("viz.html", 'r', encoding='utf-8')
206
  source_code = HtmlFile.read()
312
 
313
  return df
314
 
 
315
  def get_all_benefits(self):
316
  benefit_list = []
317
  for benefit_key in self.benefits:
347
  df = df.astype(datatypes)
348
 
349
  return df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
visualize_dataset.py DELETED
@@ -1,137 +0,0 @@
1
- import streamlit as st
2
- from pathlib import Path
3
- import json
4
- from support_functions import HealthseaSearch
5
-
6
- def visualize_dataset():
7
- # Configuration
8
- health_aspect_path = Path("data/health_aspects.json")
9
- product_path = Path("data/products.json")
10
- condition_path = Path("data/condition_vectors.json")
11
- benefit_path = Path("data/benefit_vectors.json")
12
-
13
- # Load data
14
- @st.cache(allow_output_mutation=True)
15
- def load_data(
16
- _health_aspect_path: Path,
17
- _product_path: Path,
18
- _condition_path: Path,
19
- _benefit_path: Path,
20
- ):
21
- with open(_health_aspect_path) as reader:
22
- health_aspects = json.load(reader)
23
- with open(_product_path) as reader:
24
- products = json.load(reader)
25
- with open(_condition_path) as reader:
26
- conditions = json.load(reader)
27
- with open(_benefit_path) as reader:
28
- benefits = json.load(reader)
29
- return health_aspects, products, conditions, benefits
30
-
31
-
32
- # Functions
33
- def kpi(n, text):
34
- html = f"""
35
- <div class='kpi'>
36
- <h1 class='kpi_header'>{n}</h1>
37
- <span>{text}</span>
38
- </div>
39
- """
40
- return html
41
-
42
-
43
- def central_text(text):
44
- html = f"""<h2 class='central_text'>{text}</h2>"""
45
- return html
46
-
47
- # Loading data
48
- health_aspects, products, conditions, benefits = load_data(
49
- health_aspect_path, product_path, condition_path, benefit_path
50
- )
51
- search_engine = HealthseaSearch(health_aspects, products, conditions, benefits)
52
-
53
- # KPI
54
-
55
- st.info("""This app showcases a dataset of up to one million reviews that was analyzed by the Healthsea pipeline. You can search for any health aspect, whether it's a disease (e.g. joint pain) or a positive state of health (e.g. energy), the app will output a list of products and substances.
56
- These products have a score which is calculated by the content of their reviews.""")
57
-
58
- st.warning("""Please note that Healthsea is a research project and a proof-of-concept that presents a technical approach on analyzing user-generated reviews.
59
- The results produced by Healthsea should not be used as a foundation for treating health problems and neither do we want to advocate that supplementary products are able to solve all health issues.""")
60
-
61
-
62
- st.markdown("""---""")
63
-
64
- st.markdown(central_text("🎀 Dataset"), unsafe_allow_html=True)
65
-
66
- kpi_products, kpi_reviews, kpi_condition, kpi_benefit = st.columns(4)
67
-
68
- def round_to_k(value):
69
- return str(round(value/1000,1))+"k"
70
-
71
- kpi_products.markdown(kpi(round_to_k(len(products)), "Products"), unsafe_allow_html=True)
72
- kpi_reviews.markdown(kpi(round_to_k(int(933240)), "Reviews"), unsafe_allow_html=True)
73
- kpi_condition.markdown(kpi(round_to_k(len(conditions)), "Conditions"), unsafe_allow_html=True)
74
- kpi_benefit.markdown(kpi(round_to_k(len(benefits)), "Benefits"), unsafe_allow_html=True)
75
-
76
- st.markdown("""---""")
77
-
78
- # Expander
79
- show_conditions, show_benefits = st.columns(2)
80
-
81
- with show_conditions.expander("Top mentioned Conditions"):
82
- st.write(search_engine.get_all_conditions_df())
83
-
84
- with show_benefits.expander("Top mentioned Benefits"):
85
- st.write(search_engine.get_all_benefits_df())
86
-
87
- st.markdown("""---""")
88
-
89
- # Search
90
- search = st.text_input(label="Search for an health aspect", value="joint pain")
91
- n = st.slider("Show top n results", min_value=10, max_value=1000, value=25)
92
-
93
- st.markdown("""---""")
94
- st.markdown(central_text("🧃 Products"), unsafe_allow_html=True)
95
-
96
- st.info("""The products are scored based on what reviewers say. Additional variables in the scoring function are product rating, helpful count and whether the review is considered 'fake'. """)
97
-
98
- # DataFrame
99
- st.write(search_engine.get_products_df(search, n))
100
-
101
- # KPI & Alias
102
- aspect_alias = search_engine.get_aspect(search)["alias"]
103
-
104
- kpi_product_mentions, kpi_alias = st.columns(2)
105
-
106
- kpi_product_mentions.markdown(kpi(len(search_engine.get_aspect(search)["products"]), "Products"), unsafe_allow_html=True)
107
-
108
- if len(aspect_alias) > 0:
109
- kpi_alias.markdown(
110
- kpi(len(aspect_alias), "Similar health aspects"),
111
- unsafe_allow_html=True,
112
- )
113
-
114
- vectors = []
115
- main_aspect = search_engine.get_aspect_meta(search)
116
- vectors.append((main_aspect["name"], main_aspect["vector"]))
117
- for aspect in aspect_alias:
118
- current_aspect = search_engine.get_aspect_meta(aspect)
119
- vectors.append((current_aspect["name"], current_aspect["vector"]))
120
- st.markdown("\n")
121
- st.info("""To improve the search, the table also shows results of other health aspects with a high similarity""")
122
- #st.write(search_engine.tsne_plot(vectors))
123
- search_engine.pyvis(vectors)
124
-
125
- st.markdown("""---""")
126
-
127
- # Substances
128
- st.markdown(central_text("🍯 Substances"), unsafe_allow_html=True)
129
- st.info("""The scores of the substances are based on the products""")
130
-
131
- # DataFrame
132
- st.write(search_engine.get_substances_df(search, n))
133
- kpi_substances, empty = st.columns(2)
134
- kpi_substances.markdown(
135
- kpi(len(search_engine.get_aspect(search)["substance"]), "Substances"),
136
- unsafe_allow_html=True,
137
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
visualize_pipeline.py DELETED
@@ -1,157 +0,0 @@
1
- import streamlit as st
2
- import spacy
3
- from spacy_streamlit import visualize_ner
4
- from support_functions import HealthseaPipe
5
- import operator
6
-
7
- def visualize_pipeline():
8
- healthsea_pipe = HealthseaPipe()
9
-
10
- color_code = {
11
- "POSITIVE": ("#3C9E58", "#1B7735"),
12
- "NEGATIVE": ("#FF166A", "#C0094B"),
13
- "NEUTRAL": ("#7E7E7E", "#4E4747"),
14
- "ANAMNESIS": ("#E49A55", "#AD6B2D"),
15
- }
16
-
17
- example_reviews = [
18
- "This is great for joint pain.",
19
- "Product helped my joint pain but it also caused rashes.",
20
- "I'm diagnosed with gastritis. This product helped!",
21
- "This has made my insomnia even worse.",
22
- "It didn't help my joint pain.",
23
- ]
24
-
25
- # Functions
26
- def kpi(n, text):
27
- html = f"""
28
- <div class='kpi'>
29
- <h1>{n}</h1>
30
- <span>{text}</span>
31
- </div>
32
- """
33
- return html
34
-
35
-
36
- def central_text(text):
37
- html = f"""<h2 class='central_text'>{text}</h2>"""
38
- return html
39
-
40
-
41
- def format_clause(text, meta, pred):
42
- html = f"""
43
- <div>
44
- <div class="clause" style="background-color:{color_code[pred][0]} ; box-shadow: 0px 5px {color_code[pred][1]}; border-color:{color_code[pred][1]};">
45
- <div class="clause_text">{text}</div>
46
- </div>
47
- <div class="clause_meta">
48
- <div>{meta}</div>
49
- </div>
50
- </div>"""
51
- return html
52
-
53
-
54
- def format_effect(text, pred):
55
- html = f"""
56
- <div>
57
- <div class="clause" style="background-color:{color_code[pred][0]} ; box-shadow: 0px 5px {color_code[pred][1]}; border-color:{color_code[pred][1]};">
58
- <div class="clause_text">{text}</div>
59
- </div>
60
- </div>"""
61
- return html
62
-
63
- load_state = st.info("Loading...")
64
- # Load model
65
- try:
66
- load_state.info("Loading model...")
67
- if "model" not in st.session_state:
68
- nlp = spacy.load("en_healthsea")
69
- st.session_state["model"] = nlp
70
-
71
- # Download model
72
- except LookupError:
73
- import nltk
74
- import benepar
75
- load_state.info ("Downloading model...")
76
- benepar.download('benepar_en3')
77
- if "model" not in st.session_state:
78
- nlp = spacy.load("en_healthsea")
79
- st.session_state["model"] = nlp
80
- load_state.success ("Loading complete!")
81
-
82
- # Pipeline
83
- st.info("""This app visualizes the processing steps of the Healthsea pipeline. You can test it by writing an example review.""")
84
-
85
- st.markdown("""---""")
86
-
87
- st.markdown(central_text("⚙️ Pipeline"), unsafe_allow_html=True)
88
-
89
- check = st.checkbox("Use predefined examples")
90
-
91
- if not check:
92
- text = st.text_input(label="Write a review", value="This is great for joint pain!")
93
- else:
94
- text = st.selectbox("Predefined example reviews", example_reviews)
95
-
96
- nlp = st.session_state["model"]
97
- doc = nlp(text)
98
-
99
- # NER
100
- visualize_ner(
101
- doc,
102
- labels=nlp.get_pipe("ner").labels,
103
- show_table=False,
104
- title="✨ Named Entity Recognition",
105
- colors={"CONDITION": "#FF4B76", "BENEFIT": "#629B68"},
106
- )
107
-
108
- st.info("""The first processing step is to identify Conditions or Benefits with Named Entity Recognition. Conditions are diseases, symptoms and general health problems (e.g. joint pain), while Benefits are positive desired health aspects (e.g. energy)""")
109
-
110
- st.markdown("""---""")
111
-
112
- # Segmentation, Blinding, Classification
113
- st.markdown("## 🔮 Segmentation, Blinding, Classification")
114
-
115
- clauses = healthsea_pipe.get_clauses(doc)
116
- for doc_clause, clause in zip(clauses, doc._.clauses):
117
- classification = max(clause["cats"].items(), key=operator.itemgetter(1))[0]
118
- percentage = round(float(clause["cats"][classification]) * 100, 2)
119
- meta = f"{clause['ent_name']} ({classification} {percentage}%)"
120
-
121
- st.markdown(
122
- format_clause(doc_clause.text, meta, classification), unsafe_allow_html=True
123
- )
124
- st.markdown("\n")
125
-
126
- st.info("""The review is segmented into sub-clauses and then classified by a Text Classification model. We additionally blind the found entities to improve generalization and also to inform the model about our current target entity of which we want to get the prediction of.
127
- The Text Classification predicts four exclusive classes: 'Positive', 'Negative', 'Neutral', 'Anamnesis', they represent the health effect.""")
128
-
129
- st.info("""The 'Anamnesis' class is defined as the current state of health of a reviewer (e.g. 'I am diagnosed with joint pain'). It is used to link stated health effects that are mentioned in later sentences.""")
130
-
131
- st.markdown("""---""")
132
-
133
- # Aggregation
134
- st.markdown("## 🔗 Aggregation")
135
-
136
- for effect in doc._.health_effects:
137
- st.markdown(
138
- format_effect(
139
- f"{doc._.health_effects[effect]['effect']} effect on {effect}",
140
- doc._.health_effects[effect]["effect"],
141
- ),
142
- unsafe_allow_html=True,
143
- )
144
- st.markdown("\n")
145
-
146
- st.info("""Multiple classification are aggregated into one final classification.""")
147
-
148
- st.markdown("""---""")
149
- # Indepth
150
- st.markdown("## 🔧 Pipeline attributes")
151
- clauses_col, effect_col = st.columns(2)
152
-
153
- clauses_col.markdown("### doc._.clauses")
154
- for clause in doc._.clauses:
155
- clauses_col.json(clause)
156
- effect_col.markdown("### doc._.health_effects")
157
- effect_col.json(doc._.health_effects)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
viz.html CHANGED
@@ -21,6 +21,75 @@
21
  }
22
 
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
 
26
 
@@ -32,6 +101,15 @@
32
  <body>
33
  <div id = "mynetwork"></div>
34
 
 
 
 
 
 
 
 
 
 
35
 
36
  <script type="text/javascript">
37
 
@@ -50,8 +128,8 @@
50
 
51
 
52
  // parsing and collecting nodes and edges from the python
53
- nodes = new vis.DataSet([{"color": "#4EA0DB", "font": {"color": "#ffffff"}, "id": "joint pain", "label": "joint pain", "shape": "circle", "value": 100}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "knee pain", "label": "knee pain", "shape": "circle", "value": 70}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "joint pains", "label": "joint pains", "shape": "circle", "value": 70}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "hip pain", "label": "hip pain", "shape": "circle", "value": 70}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "joint swelling", "label": "joint swelling", "shape": "circle", "value": 70}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "joint spasms", "label": "joint spasms", "shape": "circle", "value": 70}, {"color": "#FE51B9", "font": {"color": "#ffffff"}, "id": "hip joint pain", "label": "hip joint pain", "shape": "circle", "value": 70}]);
54
- edges = new vis.DataSet([{"from": "joint pain", "title": 0.9572226566398657, "to": "knee pain", "value": 0.9572226566398657, "weight": 0.9572226566398657}, {"from": "joint pain", "title": 0.9625375209664775, "to": "joint pains", "value": 0.9625375209664775, "weight": 0.9625375209664775}, {"from": "joint pain", "title": 0.95503555027131, "to": "hip pain", "value": 0.95503555027131, "weight": 0.95503555027131}, {"from": "joint pain", "title": 0.9502244303109445, "to": "joint swelling", "value": 0.9502244303109445, "weight": 0.9502244303109445}, {"from": "joint pain", "title": 0.9501415183125163, "to": "joint spasms", "value": 0.9501415183125163, "weight": 0.9501415183125163}, {"from": "joint pain", "title": 0.954950292429293, "to": "hip joint pain", "value": 0.954950292429293, "weight": 0.954950292429293}, {"from": "knee pain", "title": 0.9418004072308424, "to": "joint pains", "value": 0.4709002036154212, "weight": 0.9418004072308424}, {"from": "knee pain", "title": 0.9728595739961697, "to": "hip pain", "value": 0.48642978699808487, "weight": 0.9728595739961697}, {"from": "knee pain", "title": 0.9295580615322443, "to": "joint swelling", "value": 0.46477903076612215, "weight": 0.9295580615322443}, {"from": "knee pain", "title": 0.9360705784202505, "to": "joint spasms", "value": 0.46803528921012527, "weight": 0.9360705784202505}, {"from": "knee pain", "title": 0.9537760229169578, "to": "hip joint pain", "value": 0.4768880114584789, "weight": 0.9537760229169578}, {"from": "joint pains", "title": 0.9267684505176702, "to": "hip pain", "value": 0.4633842252588351, "weight": 0.9267684505176702}, {"from": "joint pains", "title": 0.949263384012155, "to": "joint swelling", "value": 0.4746316920060775, "weight": 0.949263384012155}, {"from": "joint pains", "title": 0.9767091604713536, "to": "joint spasms", "value": 0.4883545802356768, "weight": 0.9767091604713536}, {"from": "joint pains", "title": 0.9271664961331827, "to": "hip joint pain", "value": 0.46358324806659135, "weight": 0.9271664961331827}, {"from": "hip pain", "title": 0.9171146529864702, "to": "joint swelling", "value": 0.4585573264932351, "weight": 0.9171146529864702}, {"from": "hip pain", "title": 0.9164231845869644, "to": "joint spasms", "value": 0.4582115922934822, "weight": 0.9164231845869644}, {"from": "hip pain", "title": 0.9591815632838274, "to": "hip joint pain", "value": 0.4795907816419137, "weight": 0.9591815632838274}, {"from": "joint swelling", "title": 0.9714236421275902, "to": "joint spasms", "value": 0.4857118210637951, "weight": 0.9714236421275902}, {"from": "joint swelling", "title": 0.9166539186706262, "to": "hip joint pain", "value": 0.4583269593353131, "weight": 0.9166539186706262}, {"from": "joint spasms", "title": 0.9179037086580787, "to": "hip joint pain", "value": 0.45895185432903934, "weight": 0.9179037086580787}]);
55
 
56
  // adding nodes and edges to the graph
57
  data = {nodes: nodes, edges: edges};
@@ -79,13 +157,13 @@
79
  "avoidOverlap": 0,
80
  "centralGravity": 0.3,
81
  "damping": 0.09,
82
- "gravitationalConstant": -2500,
83
  "springConstant": 0.001,
84
  "springLength": 250
85
  },
86
  "enabled": true,
87
  "stabilization": {
88
- "enabled": false,
89
  "fit": true,
90
  "iterations": 1000,
91
  "onlyDynamicEdges": false,
@@ -104,6 +182,24 @@
104
 
105
 
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  return network;
109
 
21
  }
22
 
23
 
24
+ #loadingBar {
25
+ position:absolute;
26
+ top:0px;
27
+ left:0px;
28
+ width: 700px;
29
+ height: 500px;
30
+ background-color:rgba(200,200,200,0.8);
31
+ -webkit-transition: all 0.5s ease;
32
+ -moz-transition: all 0.5s ease;
33
+ -ms-transition: all 0.5s ease;
34
+ -o-transition: all 0.5s ease;
35
+ transition: all 0.5s ease;
36
+ opacity:1;
37
+ }
38
+
39
+ #bar {
40
+ position:absolute;
41
+ top:0px;
42
+ left:0px;
43
+ width:20px;
44
+ height:20px;
45
+ margin:auto auto auto auto;
46
+ border-radius:11px;
47
+ border:2px solid rgba(30,30,30,0.05);
48
+ background: rgb(0, 173, 246); /* Old browsers */
49
+ box-shadow: 2px 0px 4px rgba(0,0,0,0.4);
50
+ }
51
+
52
+ #border {
53
+ position:absolute;
54
+ top:10px;
55
+ left:10px;
56
+ width:500px;
57
+ height:23px;
58
+ margin:auto auto auto auto;
59
+ box-shadow: 0px 0px 4px rgba(0,0,0,0.2);
60
+ border-radius:10px;
61
+ }
62
+
63
+ #text {
64
+ position:absolute;
65
+ top:8px;
66
+ left:530px;
67
+ width:30px;
68
+ height:50px;
69
+ margin:auto auto auto auto;
70
+ font-size:22px;
71
+ color: #000000;
72
+ }
73
+
74
+ div.outerBorder {
75
+ position:relative;
76
+ top:400px;
77
+ width:600px;
78
+ height:44px;
79
+ margin:auto auto auto auto;
80
+ border:8px solid rgba(0,0,0,0.1);
81
+ background: rgb(252,252,252); /* Old browsers */
82
+ background: -moz-linear-gradient(top, rgba(252,252,252,1) 0%, rgba(237,237,237,1) 100%); /* FF3.6+ */
83
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(252,252,252,1)), color-stop(100%,rgba(237,237,237,1))); /* Chrome,Safari4+ */
84
+ background: -webkit-linear-gradient(top, rgba(252,252,252,1) 0%,rgba(237,237,237,1) 100%); /* Chrome10+,Safari5.1+ */
85
+ background: -o-linear-gradient(top, rgba(252,252,252,1) 0%,rgba(237,237,237,1) 100%); /* Opera 11.10+ */
86
+ background: -ms-linear-gradient(top, rgba(252,252,252,1) 0%,rgba(237,237,237,1) 100%); /* IE10+ */
87
+ background: linear-gradient(to bottom, rgba(252,252,252,1) 0%,rgba(237,237,237,1) 100%); /* W3C */
88
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */
89
+ border-radius:72px;
90
+ box-shadow: 0px 0px 10px rgba(0,0,0,0.2);
91
+ }
92
+
93
 
94
 
95
 
101
  <body>
102
  <div id = "mynetwork"></div>
103
 
104
+ <div id="loadingBar">
105
+ <div class="outerBorder">
106
+ <div id="text">0%</div>
107
+ <div id="border">
108
+ <div id="bar"></div>
109
+ </div>
110
+ </div>
111
+ </div>
112
+
113
 
114
  <script type="text/javascript">
115
 
128
 
129
 
130
  // parsing and collecting nodes and edges from the python
131
+ nodes = new vis.DataSet([{"color": "#4B9EFF", "font": {"color": "#ffffff"}, "id": "joint_pain", "label": "joint_pain", "shape": "dot", "title": "0", "value": 100}, {"color": "#4BD4FF", "font": {"color": "#ffffff"}, "id": "knee_pain", "label": "knee_pain", "shape": "dot", "title": "1", "value": 85}, {"color": "#3CDFCB", "font": {"color": "#ffffff"}, "id": "foot_pain", "label": "foot_pain", "shape": "dot", "title": "2", "value": 70}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_pain", "label": "hip_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_pain", "label": "shoulder_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ankle_pain", "label": "ankle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "neck_pain", "label": "neck_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "wrist_pain", "label": "wrist_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "forearm_pain", "label": "forearm_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_pain", "label": "leg_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "foot_cramps", "label": "foot_cramps", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "legs_pain", "label": "legs_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "chest_pain", "label": "chest_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "elbow_pain", "label": "elbow_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "waist_pain", "label": "waist_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "finger_joint_pain", "label": "finger_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "toe_pain", "label": "toe_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "arm_pain", "label": "arm_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "thumb_pain", "label": "thumb_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "heel_pain", "label": "heel_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "head_pain", "label": "head_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knuckle_pain", "label": "knuckle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "finger_pain", "label": "finger_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "foot_swelling", "label": "foot_swelling", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "feet_pain", "label": "feet_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "jaw_pain", "label": "jaw_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulders_pain", "label": "shoulders_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "thigh_pain", "label": "thigh_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "arms_pain", "label": "arms_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#3CDFCB", "font": {"color": "#ffffff"}, "id": "knee_joint_pain", "label": "knee_joint_pain", "shape": "dot", "title": "2", "value": 70}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_joints_pain", "label": "knee_joints_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "aching_joint_pain", "label": "aching_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_joint_pains", "label": "knee_joint_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_joint_pain", "label": "hip_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_ligament_pain", "label": "knee_ligament_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_muscle_pain", "label": "shoulder_muscle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "wrist_joint_pain", "label": "wrist_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee__pain", "label": "knee__pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_joint_ache", "label": "knee_joint_ache", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_muscle_pain", "label": "joint_muscle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "arthritic_joint_pain", "label": "arthritic_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "fingers_joint_pain", "label": "fingers_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ankle_joint__pain", "label": "ankle_joint__pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_joint_aches", "label": "hip_joint_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "elbow_joint_pains", "label": "elbow_joint_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knees_joint_pain", "label": "knees_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_joint_stiffness", "label": "knee_joint_stiffness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "arm_muscle_pain", "label": "arm_muscle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_arm_pain", "label": "shoulder_arm_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "thumb_joint_pain", "label": "thumb_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_finger_pain", "label": "joint_finger_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_joints_pain", "label": "shoulder_joints_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_bone_joint_pain", "label": "shoulder_bone_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_knee_pain", "label": "hip_knee_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_joint_discomfort", "label": "hip_joint_discomfort", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee\njoint_pain", "label": "knee\njoint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "jaw_hindge_joint_pain", "label": "jaw_hindge_joint_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_joints_pain", "label": "hip_joints_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#3CDFCB", "font": {"color": "#ffffff"}, "id": "knee_pains", "label": "knee_pains", "shape": "dot", "title": "2", "value": 70}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_pains", "label": "joint_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_cramps", "label": "leg_cramps", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_aches", "label": "knee_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knees_pain", "label": "knees_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_pains", "label": "shoulder_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_aches", "label": "hip_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "chest_pains", "label": "chest_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_spasms", "label": "leg_spasms", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_pains", "label": "leg_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hip_pains", "label": "hip_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_discomfort", "label": "knee_discomfort", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_cramps", "label": "knee_cramps", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "elbow_aches", "label": "elbow_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_soreness", "label": "shoulder_soreness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ankle_pains", "label": "ankle_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "feet_pains", "label": "feet_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "legs_pains", "label": "legs_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_aches", "label": "leg_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "neck_spasms", "label": "neck_spasms", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_swelling", "label": "knee_swelling", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "leg_numbness", "label": "leg_numbness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_cramps", "label": "joint_cramps", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "neck_pains", "label": "neck_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "tendon_pains", "label": "tendon_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knees_pains", "label": "knees_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_tendonitis", "label": "shoulder_tendonitis", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knees_joint_pains", "label": "knees_joint_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "head_pains", "label": "head_pains", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_aches", "label": "shoulder_aches", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "shoulder_discomfort", "label": "shoulder_discomfort", "shape": "dot", "title": "3", "value": 55}, {"color": "#3CDFCB", "font": {"color": "#ffffff"}, "id": "spine_pain", "label": "spine_pain", "shape": "dot", "title": "2", "value": 70}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joints_pain", "label": "joints_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ligaments_pain", "label": "ligaments_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "bone_pain", "label": "bone_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "nerve_pain", "label": "nerve_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "limb_pain", "label": "limb_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "hips_pain", "label": "hips_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "vertebral_pain", "label": "vertebral_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "pelvic_pain", "label": "pelvic_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "spinal_pain", "label": "spinal_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "bony_pain", "label": "bony_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ear_pain", "label": "ear_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "ligament_pain", "label": "ligament_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "abdomen_pain", "label": "abdomen_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "kneecap_pain", "label": "kneecap_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "groin_pain", "label": "groin_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "extremity_pain", "label": "extremity_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "tendon_pain", "label": "tendon_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "testicle_pain", "label": "testicle_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "tailbone_pain", "label": "tailbone_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "lumbar_pain", "label": "lumbar_pain", "shape": "dot", "title": "3", "value": 55}, {"color": "#4BD4FF", "font": {"color": "#ffffff"}, "id": "joint_swelling", "label": "joint_swelling", "shape": "dot", "title": "1", "value": 85}, {"color": "#3CDFCB", "font": {"color": "#ffffff"}, "id": "joint_stiffness", "label": "joint_stiffness", "shape": "dot", "title": "2", "value": 70}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_soreness", "label": "joint_soreness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_discomfort", "label": "joint_discomfort", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "knee_stiffness", "label": "knee_stiffness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_spasms", "label": "joint_spasms", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_weakness", "label": "joint_weakness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_tightness", "label": "joint_tightness", "shape": "dot", "title": "3", "value": 55}, {"color": "#37DF8E", "font": {"color": "#ffffff"}, "id": "joint_tenderness", "label": "joint_tenderness", "shape": "dot", "title": "3", "value": 55}]);
132
+ edges = new vis.DataSet([{"from": "joint_pain", "to": "knee_pain", "value": 1.0}, {"from": "knee_pain", "to": "foot_pain", "value": 0.85}, {"from": "foot_pain", "to": "hip_pain", "value": 0.7}, {"from": "foot_pain", "to": "shoulder_pain", "value": 0.7}, {"from": "foot_pain", "to": "ankle_pain", "value": 0.7}, {"from": "foot_pain", "to": "neck_pain", "value": 0.7}, {"from": "foot_pain", "to": "wrist_pain", "value": 0.7}, {"from": "foot_pain", "to": "forearm_pain", "value": 0.7}, {"from": "foot_pain", "to": "leg_pain", "value": 0.7}, {"from": "foot_pain", "to": "foot_cramps", "value": 0.7}, {"from": "foot_pain", "to": "legs_pain", "value": 0.7}, {"from": "foot_pain", "to": "chest_pain", "value": 0.7}, {"from": "foot_pain", "to": "elbow_pain", "value": 0.7}, {"from": "foot_pain", "to": "waist_pain", "value": 0.7}, {"from": "foot_pain", "to": "finger_joint_pain", "value": 0.7}, {"from": "foot_pain", "to": "toe_pain", "value": 0.7}, {"from": "foot_pain", "to": "arm_pain", "value": 0.7}, {"from": "foot_pain", "to": "thumb_pain", "value": 0.7}, {"from": "foot_pain", "to": "heel_pain", "value": 0.7}, {"from": "foot_pain", "to": "head_pain", "value": 0.7}, {"from": "foot_pain", "to": "knuckle_pain", "value": 0.7}, {"from": "foot_pain", "to": "finger_pain", "value": 0.7}, {"from": "foot_pain", "to": "foot_swelling", "value": 0.7}, {"from": "foot_pain", "to": "feet_pain", "value": 0.7}, {"from": "foot_pain", "to": "jaw_pain", "value": 0.7}, {"from": "foot_pain", "to": "shoulders_pain", "value": 0.7}, {"from": "foot_pain", "to": "thigh_pain", "value": 0.7}, {"from": "foot_pain", "to": "arms_pain", "value": 0.7}, {"from": "knee_pain", "to": "knee_joint_pain", "value": 0.85}, {"from": "knee_joint_pain", "to": "knee_joints_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "aching_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee_joint_pains", "value": 0.7}, {"from": "knee_joint_pain", "to": "hip_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee_ligament_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "shoulder_muscle_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "wrist_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee__pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee_joint_ache", "value": 0.7}, {"from": "knee_joint_pain", "to": "joint_muscle_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "arthritic_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "fingers_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "ankle_joint__pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "hip_joint_aches", "value": 0.7}, {"from": "knee_joint_pain", "to": "elbow_joint_pains", "value": 0.7}, {"from": "knee_joint_pain", "to": "knees_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee_joint_stiffness", "value": 0.7}, {"from": "knee_joint_pain", "to": "arm_muscle_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "shoulder_arm_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "thumb_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "joint_finger_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "shoulder_joints_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "shoulder_bone_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "hip_knee_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "hip_joint_discomfort", "value": 0.7}, {"from": "knee_joint_pain", "to": "knee\njoint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "jaw_hindge_joint_pain", "value": 0.7}, {"from": "knee_joint_pain", "to": "hip_joints_pain", "value": 0.7}, {"from": "knee_pain", "to": "knee_pains", "value": 0.85}, {"from": "knee_pains", "to": "joint_pains", "value": 0.7}, {"from": "knee_pains", "to": "leg_cramps", "value": 0.7}, {"from": "knee_pains", "to": "knee_aches", "value": 0.7}, {"from": "knee_pains", "to": "knees_pain", "value": 0.7}, {"from": "knee_pains", "to": "shoulder_pains", "value": 0.7}, {"from": "knee_pains", "to": "hip_aches", "value": 0.7}, {"from": "knee_pains", "to": "chest_pains", "value": 0.7}, {"from": "knee_pains", "to": "leg_spasms", "value": 0.7}, {"from": "knee_pains", "to": "leg_pains", "value": 0.7}, {"from": "knee_pains", "to": "hip_pains", "value": 0.7}, {"from": "knee_pains", "to": "knee_discomfort", "value": 0.7}, {"from": "knee_pains", "to": "knee_cramps", "value": 0.7}, {"from": "knee_pains", "to": "elbow_aches", "value": 0.7}, {"from": "knee_pains", "to": "shoulder_soreness", "value": 0.7}, {"from": "knee_pains", "to": "ankle_pains", "value": 0.7}, {"from": "knee_pains", "to": "feet_pains", "value": 0.7}, {"from": "knee_pains", "to": "legs_pains", "value": 0.7}, {"from": "knee_pains", "to": "leg_aches", "value": 0.7}, {"from": "knee_pains", "to": "neck_spasms", "value": 0.7}, {"from": "knee_pains", "to": "knee_swelling", "value": 0.7}, {"from": "knee_pains", "to": "leg_numbness", "value": 0.7}, {"from": "knee_pains", "to": "joint_cramps", "value": 0.7}, {"from": "knee_pains", "to": "neck_pains", "value": 0.7}, {"from": "knee_pains", "to": "tendon_pains", "value": 0.7}, {"from": "knee_pains", "to": "knees_pains", "value": 0.7}, {"from": "knee_pains", "to": "shoulder_tendonitis", "value": 0.7}, {"from": "knee_pains", "to": "knees_joint_pains", "value": 0.7}, {"from": "knee_pains", "to": "head_pains", "value": 0.7}, {"from": "knee_pains", "to": "shoulder_aches", "value": 0.7}, {"from": "knee_pains", "to": "shoulder_discomfort", "value": 0.7}, {"from": "knee_pain", "to": "spine_pain", "value": 0.85}, {"from": "spine_pain", "to": "joints_pain", "value": 0.7}, {"from": "spine_pain", "to": "ligaments_pain", "value": 0.7}, {"from": "spine_pain", "to": "bone_pain", "value": 0.7}, {"from": "spine_pain", "to": "nerve_pain", "value": 0.7}, {"from": "spine_pain", "to": "limb_pain", "value": 0.7}, {"from": "spine_pain", "to": "hips_pain", "value": 0.7}, {"from": "spine_pain", "to": "vertebral_pain", "value": 0.7}, {"from": "spine_pain", "to": "pelvic_pain", "value": 0.7}, {"from": "spine_pain", "to": "spinal_pain", "value": 0.7}, {"from": "spine_pain", "to": "bony_pain", "value": 0.7}, {"from": "spine_pain", "to": "ear_pain", "value": 0.7}, {"from": "spine_pain", "to": "ligament_pain", "value": 0.7}, {"from": "spine_pain", "to": "abdomen_pain", "value": 0.7}, {"from": "spine_pain", "to": "kneecap_pain", "value": 0.7}, {"from": "spine_pain", "to": "groin_pain", "value": 0.7}, {"from": "spine_pain", "to": "extremity_pain", "value": 0.7}, {"from": "spine_pain", "to": "tendon_pain", "value": 0.7}, {"from": "spine_pain", "to": "testicle_pain", "value": 0.7}, {"from": "spine_pain", "to": "tailbone_pain", "value": 0.7}, {"from": "spine_pain", "to": "lumbar_pain", "value": 0.7}, {"from": "joint_pain", "to": "joint_swelling", "value": 1.0}, {"from": "joint_swelling", "to": "joint_stiffness", "value": 0.85}, {"from": "joint_stiffness", "to": "joint_soreness", "value": 0.7}, {"from": "joint_stiffness", "to": "joint_discomfort", "value": 0.7}, {"from": "joint_stiffness", "to": "knee_stiffness", "value": 0.7}, {"from": "joint_stiffness", "to": "joint_spasms", "value": 0.7}, {"from": "joint_stiffness", "to": "joint_weakness", "value": 0.7}, {"from": "joint_stiffness", "to": "joint_tightness", "value": 0.7}, {"from": "joint_stiffness", "to": "joint_tenderness", "value": 0.7}]);
133
 
134
  // adding nodes and edges to the graph
135
  data = {nodes: nodes, edges: edges};
157
  "avoidOverlap": 0,
158
  "centralGravity": 0.3,
159
  "damping": 0.09,
160
+ "gravitationalConstant": -2738,
161
  "springConstant": 0.001,
162
  "springLength": 250
163
  },
164
  "enabled": true,
165
  "stabilization": {
166
+ "enabled": true,
167
  "fit": true,
168
  "iterations": 1000,
169
  "onlyDynamicEdges": false,
182
 
183
 
184
 
185
+ network.on("stabilizationProgress", function(params) {
186
+ document.getElementById('loadingBar').removeAttribute("style");
187
+ var maxWidth = 496;
188
+ var minWidth = 20;
189
+ var widthFactor = params.iterations/params.total;
190
+ var width = Math.max(minWidth,maxWidth * widthFactor);
191
+
192
+ document.getElementById('bar').style.width = width + 'px';
193
+ document.getElementById('text').innerHTML = Math.round(widthFactor*100) + '%';
194
+ });
195
+ network.once("stabilizationIterationsDone", function() {
196
+ document.getElementById('text').innerHTML = '100%';
197
+ document.getElementById('bar').style.width = '496px';
198
+ document.getElementById('loadingBar').style.opacity = 0;
199
+ // really clean the dom element
200
+ setTimeout(function () {document.getElementById('loadingBar').style.display = 'none';}, 500);
201
+ });
202
+
203
 
204
  return network;
205