healthsea-demo / support_functions.py
edichief's picture
Fix dependencies
9107c03
import pandas as pd
import difflib
import numpy as np
from numpy import dot
from numpy.linalg import norm
from pyvis.network import Network
import streamlit.components.v1 as components
color_code_node = {
0: '#4B9EFF',
1: '#4BD4FF',
2: '#3CDFCB',
3: '#37DF8E',
4: '#A0C159',
5: '#CA804B',
6: '#CA524B',
7: '#CA4B97',
8: '#C04BCA',
9: '#5D4BCA',
10: '#213ABA',
11: '#0E6697',
}
class HealthseaSearch:
def __init__(self, _health_aspects, _products, _conditions, _benefits):
self.health_aspects = _health_aspects
self.products = _products
self.conditions = _conditions
self.benefits = _benefits
def __call__(self, query):
return query
# Load product meta
def get_products(self, _aspect, n):
product_list = []
product_ids = {}
_n = n
_aspect = _aspect.replace(" ", "_")
if _aspect in self.health_aspects:
aspect = self.health_aspects[_aspect]
else:
_aspect = difflib.get_close_matches("_aspect", self.health_aspects.keys())[
0
]
aspect = self.health_aspects[_aspect]
product_scoring = aspect["products"]
if n != 0:
if n > len(product_scoring):
n = len(product_scoring)
product_scoring = aspect["products"][:n]
for product in product_scoring:
if product[1] not in product_ids:
product_list.append((product[0], self.products[product[1]], _aspect))
product_ids[product[1]] = 1
for alias in aspect["alias"]:
n = _n
_product_scoring = self.health_aspects[alias]["products"]
if n != 0:
if n > len(_product_scoring):
n = len(_product_scoring)
_product_scoring = self.health_aspects[alias]["products"][:n]
for product in _product_scoring:
if product[1] not in product_ids:
product_list.append((product[0], self.products[product[1]], alias))
product_ids[product[1]] = 1
n = _n
if len(product_list) > n and n != 0:
product_list = product_list[:n]
product_list = sorted(product_list, key=lambda tup: tup[0], reverse=True)
return product_list
# Load product meta and return as DataFrame
def get_products_df(self, _aspect, n):
product_list = self.get_products(_aspect, n)
product_data = {
"product": [],
"score": [],
"health_aspect": [],
"rating": [],
"reviews": [],
}
for product in product_list:
product_data["score"].append(product[0])
product_data["product"].append(product[1]["name"])
product_data["health_aspect"].append(product[2])
product_data["rating"].append(product[1]["rating"])
product_data["reviews"].append(product[1]["review_count"])
datatypes = {
"product": str,
"score": int,
"health_aspect": str,
"rating": str,
"reviews": int,
}
df = pd.DataFrame(data=product_data)
df = df.astype(datatypes)
return df
# Get health aspect
def get_aspect(self, _aspect):
_aspect = _aspect.replace(" ", "_")
if _aspect in self.health_aspects:
return self.health_aspects[_aspect]
else:
_aspect = difflib.get_close_matches("_aspect", self.health_aspects.keys())[
0
]
return self.health_aspects[_aspect]
# Get health aspect meta
def get_aspect_meta(self, _aspect):
_aspect = _aspect.replace(" ", "_")
if _aspect in self.conditions:
return self.conditions[_aspect]
elif _aspect in self.benefits:
return self.benefits[_aspect]
else:
_aspect = difflib.get_close_matches("_aspect", self.conditions.keys())[0]
return self.conditions[_aspect]
def pyvis(self, vectors):
net = Network(height='500px', width='700px', bgcolor="#0E1117", font_color="#ffffff")
net.barnes_hut(gravity=-2500)
net.set_edge_smooth("dynamic")
net.toggle_stabilization(False)
net.add_node(vectors[0][0], label=vectors[0][0], color="#4EA0DB", value=100, shape="circle") # node id = 1 and label = Node 1
for vector in vectors[1:]:
net.add_node(vector[0], label=vector[0], color="#FE51B9", value=70, shape="circle") # node id = 1 and label = Node 1
for i, vector in enumerate(vectors):
current_vector = vectors[i]
if i < len(vectors):
if i == 0:
for _vector in vectors[i+1:]:
sim = self.calculate_cosine_sim(current_vector[1],_vector[1])
net.add_edge(current_vector[0],_vector[0], weight=sim, value=sim, title=sim)
else:
for _vector in vectors[i+1:]:
sim = self.calculate_cosine_sim(current_vector[1],_vector[1])
net.add_edge(current_vector[0],_vector[0], weight=sim, value=sim/2, title=sim)
#for _vector in vectors[1:]:
# sim = self.calculate_cosine_sim(vectors[0][1],_vector[1])
# net.add_edge(vectors[0][0],_vector[0], weight=sim, value=sim*0.1, title=sim)
net.save_graph("viz.html")
HtmlFile = open("viz.html", 'r', encoding='utf-8')
source_code = HtmlFile.read()
components.html(source_code, height = 500, width=700)
# Experimental
def get_recursive_alias(self, _aspect, n, node_list, edge_list, _max):
aspect = self.get_aspect(_aspect)
aspect_name = aspect["name"].replace(" ","_")
if aspect_name not in node_list:
node_list[aspect_name] = {"level":n}
aspect_alias = aspect["alias"]
if len(aspect_alias) > 0 and n <= _max:
for alias in aspect_alias:
if alias not in node_list:
edge_list.append((aspect_name,alias,n))
self.get_recursive_alias(alias, n+1, node_list, edge_list,_max)
return node_list, edge_list
else:
return node_list, edge_list
def add_to_network(self, network, node_list, edge_list):
for node in node_list:
value = 100-(15*node_list[node]["level"])
network.add_node(node, label=node, color=color_code_node[node_list[node]["level"]], value=value, shape="dot", title = str(node_list[node]["level"]))
for edge in edge_list:
value = 1-(0.15*edge[2])
network.add_edge(edge[0], edge[1], value=value)
def pyvis2(self, node_list, edge_list):
net = Network(height='500px', width='700px', bgcolor="#0E1117", font_color="#ffffff")
net.barnes_hut(gravity=-2500-(len(node_list)*2))
net.set_edge_smooth("dynamic")
self.add_to_network(net, node_list, edge_list)
net.save_graph("viz.html")
HtmlFile = open("viz.html", 'r', encoding='utf-8')
source_code = HtmlFile.read()
components.html(source_code, height = 500, width=700)
def calculate_cosine_sim(self,a,b):
cos_sim = dot(a, b)/(norm(a)*norm(b))
return cos_sim
# Load substance meta
def get_substances(self, _aspect, n):
substance_list = []
substance_ids = {}
exclude = ["sodium", "sugar", "sugar_alcohol"]
_n = n
_aspect = _aspect.replace(" ", "_")
if _aspect in self.health_aspects:
aspect = self.health_aspects[_aspect]
else:
_aspect = difflib.get_close_matches("_aspect", self.health_aspects.keys())[
0
]
aspect = self.health_aspects[_aspect]
substance_scoring = aspect["substance"]
if n != 0:
if n > len(substance_scoring):
n = len(substance_scoring)
substance_scoring = aspect["substance"][:n]
for substance in substance_scoring:
if substance[1] in exclude:
continue
if substance[1] not in substance_ids:
substance_list.append((substance[0], substance[1], _aspect))
substance_ids[substance[1]] = 1
for alias in aspect["alias"]:
n = _n
_substance_scoring = self.health_aspects[alias]["substance"]
if n != 0:
if n > len(_substance_scoring):
n = len(_substance_scoring)
_substance_scoring = self.health_aspects[alias]["substance"][:n]
for substance in _substance_scoring:
if substance[1] in exclude:
continue
if substance[1] not in substance_ids:
substance_list.append((substance[0], substance[1], alias))
substance_ids[substance[1]] = 1
n = _n
if len(substance_list) > n and n != 0:
substance_list = substance_list[:n]
substance_list = sorted(substance_list, key=lambda tup: tup[0], reverse=True)
return substance_list
# Load substance meta and return as DataFrame
def get_substances_df(self, _aspect, n):
substance_list = self.get_substances(_aspect, n)
substance_data = {"substance": [], "score": [], "health_aspect": []}
for substance in substance_list:
substance_data["score"].append(substance[0])
substance_data["substance"].append(substance[1])
substance_data["health_aspect"].append(substance[2])
datatypes = {"substance": str, "score": int, "health_aspect": str}
df = pd.DataFrame(data=substance_data)
df = df.astype(datatypes)
return df
# Get all health aspect indices
def get_all_conditions(self):
condition_list = []
for condition_key in self.conditions:
if condition_key in self.health_aspects:
alias = len(self.health_aspects[condition_key]["alias"])
else:
alias = 0
condition_list.append((self.conditions[condition_key]["frequency"],condition_key,alias))
condition_list = sorted(condition_list, key=lambda tup: tup[0], reverse=True)
return condition_list
def get_all_conditions_df(self):
condition_list = self.get_all_conditions()[:100]
condition_data = {
"Condition": [],
"Frequency": [],
"Alias": []
}
for condition in condition_list:
condition_data["Frequency"].append(condition[0])
condition_data["Condition"].append(condition[1])
condition_data["Alias"].append(condition[2])
datatypes = {
"Frequency": int,
"Condition": str,
"Alias": int
}
df = pd.DataFrame(data=condition_data)
df = df.astype(datatypes)
return df
def get_all_benefits(self):
benefit_list = []
for benefit_key in self.benefits:
if benefit_key in self.health_aspects:
alias = len(self.health_aspects[benefit_key]["alias"])
else:
alias = 0
benefit_list.append((self.benefits[benefit_key]["frequency"],benefit_key,alias))
benefit_list = sorted(benefit_list, key=lambda tup: tup[0], reverse=True)
return benefit_list
def get_all_benefits_df(self):
benefit_list = self.get_all_benefits()[:100]
benefit_data = {
"Benefit": [],
"Frequency": [],
"Alias": []
}
for benefit in benefit_list:
benefit_data["Frequency"].append(benefit[0])
benefit_data["Benefit"].append(benefit[1])
benefit_data["Alias"].append(benefit[2])
datatypes = {
"Frequency": int,
"Benefit": str,
"Alias": int
}
df = pd.DataFrame(data=benefit_data)
df = df.astype(datatypes)
return df