ConectaODSco commited on
Commit
8ab2205
·
verified ·
1 Parent(s): 46a897e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -0
app.py CHANGED
@@ -27,6 +27,7 @@ import matplotlib.pyplot as plt
27
  import seaborn as sns
28
  from src.embeddings.modelos_nlp_db import search
29
  from src.embeddings.mass_modelos_nlp_db import search_mass
 
30
  from huggingface_hub import InferenceClient
31
  # import pandas as pd
32
  import re
@@ -848,6 +849,167 @@ def tab_inicio(df_ods, df_metas, df_indicador):
848
  """
849
  return html
850
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
851
  def tab_inicio_mass(df_ods=None, df_metas=None, df_indicador=None):
852
  # def tab_inicio():
853
  """Pestaña de inicio con resumen general"""
@@ -1875,6 +2037,68 @@ def crear_app():
1875
  return True
1876
 
1877
  # PESTAÑA: CONSULTA
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1878
  with gr.Tab("CONSULTA INDIVIDUAL"):
1879
 
1880
  txt_ods = gr.Textbox(value="ods", visible=False)
 
27
  import seaborn as sns
28
  from src.embeddings.modelos_nlp_db import search
29
  from src.embeddings.mass_modelos_nlp_db import search_mass
30
+ from src.llm_clasificador_HF import procesar_lote
31
  from huggingface_hub import InferenceClient
32
  # import pandas as pd
33
  import re
 
849
  """
850
  return html
851
 
852
+ def tab_inicio_prompt(df_ods, df_metas, df_indicador):
853
+ # def tab_inicio():
854
+ """Pestaña de inicio con resumen general"""
855
+ if not DATOS_CARGADOS:
856
+ return "⚠️ Error: No se pudieron cargar los datos."
857
+
858
+ # Estadísticas básicas
859
+
860
+ # total_ods = df_ods['ODS_ID'].nunique()
861
+ # total_metas = df_metas['META_ID'].nunique()
862
+ # total_indicadores = df_indicador['INDICADOR_ID'].nunique()
863
+ # sim_media = df_ods['ods_similaridad_cos_normalized'].mean()
864
+ # sim_max = df_ods['ods_similaridad_cos_normalized'].max()
865
+ # sim_min = df_ods['ods_similaridad_cos_normalized'].min()
866
+ # correlacion = df_ods['ods_rank'].corr(df_ods['ods_similaridad_cos_normalized'])
867
+
868
+ # Top 4 ODS
869
+ top_ods = df_ods.nsmallest(4, 'ods_rank')[['rank', 'ODS_ID', 'score', 'frecuencia']]
870
+ top_ods['logo_id'] = top_ods['ODS_ID'].apply(lambda _: f"ods_{str(_)}")
871
+ # top_ods = df_ods.groupby('ODS_ID').agg({
872
+ # 'ods_similaridad_cos_normalized': 'mean'
873
+ # }).sort_values('ods_similaridad_cos_normalized', ascending=False).head(3)[['ods_similaridad_cos_normalized']]
874
+
875
+ # Top ODS referencia
876
+ ods_ref = top_ods.ODS_ID
877
+
878
+ # Top 3 METAS
879
+
880
+ top_metas = df_metas.nsmallest(4, 'ods_rank')[['rank', 'META_ID', 'score', 'frecuencia']]
881
+ # for i in ods_ref:
882
+ # top_metas_lcl = df_metas[df_metas.ODS_ID == i]
883
+ # top_metas_lcl = top_metas_lcl.nsmallest(2, 'meta_rank')[['META_ID','meta_rank','META','meta_similaridad_cos_normalized', 'ODS_ID']]
884
+ # top_metas = pd.concat([top_metas, top_metas_lcl], axis=0)
885
+ # top_metas['logo_id'] = top_metas['ODS_ID'].apply(lambda _: f"ods_{_}")
886
+ top_metas['logo_id'] = top_metas['META_ID'].apply(lambda _: f"meta_{str(_).upper()}")
887
+
888
+ recomendaciones_tblinput = Path('data/raw/ODS_169_metas_recomendaciones_detalladas.xlsx')
889
+ df_recomendaciones = pd.read_excel(recomendaciones_tblinput)
890
+ top_metas = top_metas.merge(df_recomendaciones[['Meta_ODS', 'Recomendaciones_territoriales']], left_on='META_ID', right_on='Meta_ODS', how='left')
891
+ # top_metas = df_metas.groupby('META_ID').agg({
892
+ # 'meta_similaridad_cos_normalized': 'mean'
893
+ # }).sort_values('meta_similaridad_cos_normalized', ascending=False).head(5)[['META_ID','META','meta_similaridad_cos_normalized']]
894
+
895
+ # Top 5 indicadores
896
+ # top_indicador = df_metas.nsmallest(4, 'ods_rank')[['rank', 'INDICADOR_ID', 'score', 'frecuencia']]
897
+ # top_indicador['ODS_ID'] = top_indicador['INDICADOR_ID'].apply(lambda x: str(x).split('.')[0] if pd.notna(x) else None)
898
+ # top_indicador['logo_id'] = top_indicador['ODS_ID'].apply(lambda _: f"ods_{str(_)}")
899
+
900
+
901
+ html = f"""
902
+ <div style="font-family: Arial, sans-serif; padding: 20px;">
903
+ <h1 style="color: #2E5090; text-align: center;">
904
+ 📊 Tu texto en clave de ODS
905
+ </h1>
906
+ <h2 style="color: #4472C4; text-align: center;">
907
+ El análisis
908
+ identifica que tu texto se relaciona principalmente
909
+ con estos Objetivos de Desarrollo Sostenible ODS
910
+ </h2>
911
+
912
+
913
+
914
+
915
+ <div class="important-box" style="background-color: #009EDB; padding: 20px; border-radius: 10px; margin: 20px 0; border-left: 5px solid #E6F7E6;">
916
+ <h3 style="color: #E6F7E6;">🏆 Top 4 ODS Más Relevantes</h3>
917
+ <div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: space-around; align-items: flex-start;">
918
+ {''.join([f'''
919
+ <div style="display: flex; flex-direction: column; align-items: center; text-align: center; flex: 1; min-width: 150px;">
920
+ <img src="{dict_logos[row['logo_id']]}"
921
+ alt="ODS {row['ODS_ID']}"
922
+ width="{int(400*(row['score']**2))}"
923
+ style="margin: 0 auto; display: block;" />
924
+ <!-- <p style="margin: 10px 0; color: #333; font-weight: bold;">{row['OBJETIVO']}</p> -->
925
+ </div>''' for _, row in top_ods.iterrows()])}
926
+ </div>
927
+ </div>
928
+
929
+ <div class="important-box" style="background-color: #F0F0F0; padding: 20px; border-radius: 10px; margin: 20px 0; border-left: 5px solid #FFD700;">
930
+ <h3 style="color: #009EDB;">🎯 Metas Más Relevantes Por ODS Top</h3>
931
+ <div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: space-around; align-items: flex-start;">
932
+ {''.join([f'''
933
+ <div style="display: flex; flex-direction: column; align-items: center; text-align: center; flex: 1; min-width: 150px;">
934
+ <img src="{dict_logos[row['logo_id']]}"
935
+ alt="ODS {row['ODS_ID']}"
936
+ width="{int(200*(row['score']**2))}"
937
+ style="margin: 0 auto; display: block;" />
938
+ <p style="margin: 10px 0 5px 0; color: #333; font-size: 12px;"><strong style="color: #333;">Meta:</strong> {row['META_ID']}</p>
939
+ <!-- <p style="margin: 0; color: #666; font-size: 12px;">{row['META']}</p> -->
940
+ <!-- <p style="margin: 5px 0 0 0; color: #999; font-size: 11px;">Sim: {row['score']:.3f}</p> -->
941
+ <!-- <p style="margin: 5px 0 0 0; color: #333; font-size: 11px;">Rank: {row['meta_rank']}</p> -->
942
+ </div>''' for _, row in top_metas.iterrows()])}
943
+ </div>
944
+ </div>
945
+
946
+ <div class="important-box" style="background-color: #F0F0F0; padding: 20px; border-radius: 10px; margin: 20px 0; border-left: 5px solid #FFD700;">
947
+ <h3 style="color: #FF8C00;">🎯 Indicadores Más Relevantes Por ODS Top</h3>
948
+ <div style="display: flex; flex-wrap: wrap; gap: 20px; justify-content: space-around; align-items: flex-start;">
949
+ {''.join([f'''
950
+ <div style="display: flex; flex-direction: column; align-items: center; text-align: center; flex: 1; min-width: 150px;">
951
+ <img src="{dict_logos[row['logo_id']]}"
952
+ alt="ODS {row['ODS_ID']}"
953
+ width="{int(200*(row['score']**2))}"
954
+ style="margin: 0 auto; display: block;" />
955
+ <p style="margin: 10px 0 5px 0; color: #333; font-size: 12px;"><strong style="color: #333;">Ind:</strong> {row['INDICADOR_ID']}</p>
956
+ <!-- <p style="margin: 0; color: #666; font-size: 12px;">{row['INDICADOR']}</p> -->
957
+ <!-- <p style="margin: 5px 0 0 0; color: #333; font-size: 11px;">Sim: {row['score']:.3f}</p> -->
958
+ <p style="margin: 5px 0 0 0; color: #333; font-size: 11px;">Rank: {row['indicador_rank']}</p>
959
+ </div>''' for _, row in top_metas.iterrows()])}
960
+ </div>
961
+ </div>
962
+
963
+ <div class="important-box" style="background-color: #E8F4F8; padding: 20px; border-radius: 10px; margin: 20px 0; border-left: 5px solid #4472C4;">
964
+ <h3 style="color: #2E5090;">📋 Recomendaciones Territoriales por Meta</h3>
965
+ <table style="width: 100%; border-collapse: collapse; background-color: white;">
966
+ <thead>
967
+ <tr style="background-color: #2E5090; color: white;">
968
+ <th style="padding: 12px; text-align: left; border-bottom: 2px solid #2E5090;">ODS</th>
969
+ <th style="padding: 12px; text-align: left; border-bottom: 2px solid #2E5090;">Meta ID</th>
970
+ <th style="padding: 12px; text-align: left; border-bottom: 2px solid #2E5090;">Recomendaciones Territoriales</th>
971
+ </tr>
972
+ </thead>
973
+ <tbody>
974
+ {''.join([f'''
975
+ <tr style="border-bottom: 1px solid #ddd;">
976
+ <td style="padding: 12px; text-align: center;">
977
+ <img src="{dict_logos[f'ods_{row['ODS_ID']}']}"
978
+ alt="ODS {row['ODS_ID']}"
979
+ width="50"
980
+ style="vertical-align: middle;" />
981
+ </td>
982
+ <td style="padding: 12px; font-weight: bold; color: #2E5090;">{row['META_ID']}</td>
983
+ <td style="padding: 12px; color: #333;">{row.get('Recomendaciones_territoriales', 'N/A')}</td>
984
+ </tr>''' for _, row in df_metas.iterrows() if not pd.isna(row.get('Recomendaciones_territoriales'))])}
985
+ </tbody>
986
+ </table>
987
+ </div>
988
+
989
+ <!--
990
+ <div style="background-color: #F0F0F0; padding: 20px; border-radius: 10px; margin: 20px 0;">
991
+ <h3 style="color: #2E5090;">📚 Cómo usar esta aplicación</h3>
992
+ <ol style="line-height: 1.8;">
993
+ <li><strong>Explora las pestañas:</strong> Cada pestaña contiene una visualización diferente</li>
994
+ <li><strong>Lee las explicaciones:</strong> Cada gráfica incluye una guía de interpretación</li>
995
+ <li><strong>Interactúa:</strong> Las visualizaciones HTML permiten zoom, hover y exploración</li>
996
+ <li><strong>Descarga:</strong> Puedes descargar las imágenes desde las pestañas</li>
997
+ </ol>
998
+ </div>
999
+
1000
+ <div style="text-align: center; margin-top: 30px; padding: 20px; background-color: #E8F4F8; border-radius: 10px;">
1001
+ <p style="font-size: 18px; color: #2E5090;">
1002
+ <strong>¡Comienza explorando las visualizaciones en las pestañas superiores!</strong>
1003
+ </p>
1004
+ <p style="color: #666;">
1005
+ Recomendación: Empieza con el "Dashboard Integrado" para una vista general
1006
+ </p>
1007
+ </div>
1008
+ -->
1009
+ </div>
1010
+ """
1011
+ return html
1012
+
1013
  def tab_inicio_mass(df_ods=None, df_metas=None, df_indicador=None):
1014
  # def tab_inicio():
1015
  """Pestaña de inicio con resumen general"""
 
2037
  return True
2038
 
2039
  # PESTAÑA: CONSULTA
2040
+ with gr.Tab("CONSULTA INDIVIDUAL PROMPT"):
2041
+
2042
+ # txt_ods = gr.Textbox(value="ods", visible=False)
2043
+ # txt_meta = gr.Textbox(value="meta", visible=False)
2044
+ # txt_indicador = gr.Textbox(value="indicador", visible=False)
2045
+
2046
+ with gr.Column():
2047
+ gr.Markdown(f"""
2048
+
2049
+ ### Cuéntanos una iniciativa, problema o propuesta de tu territorio.
2050
+
2051
+ *La herramienta analizará el texto y mostrará con qué
2052
+ Objetivos de Desarrollo Sostenible (ODS) se
2053
+ relaciona.*
2054
+ """)
2055
+ query_in_prt = gr.Textbox(lines=5, placeholder="Escribe aquí tu consulta...", label="Iniciativa a analizar")
2056
+ lst_query_in_prt = gr.State() #gr.Textbox(value="[]", visible=False)
2057
+ def add_query_list(query):
2058
+ return gr.update(value=[query])
2059
+ query_in_prt.change(
2060
+ fn = add_query_list,
2061
+ inputs = query_in_prt,
2062
+ outputs = lst_query_in_prt)
2063
+ query_out_prt = gr.Textbox(lines=5, label="Texto ajustado para lenguaje natural", visible=False)
2064
+
2065
+ btn_prt = gr.Button(value="Analizar mi iniciativa")
2066
+ msj_procesamiento_prt = gr.Textbox(value="... preparando análisis de iniciativa.", visible=True)
2067
+
2068
+ with gr.Tab("🔍 Resultado"):
2069
+
2070
+
2071
+ with gr.Row():
2072
+ ods_prt = gr.Dataframe( label="ODS", visible=False)#, buttons=["fullscreen"])
2073
+ meta_prt = gr.Dataframe( label="METAS", visible=False)#, buttons=["fullscreen"])
2074
+ indicador_prt = gr.Dataframe( label="INDICADORES", visible=False)#, buttons=["fullscreen"])
2075
+
2076
+
2077
+ html_inicio_ods_prt = gr.HTML() #tab_inicio(ods.value)
2078
+
2079
+ #### Actualizando resultados iniciales
2080
+ ods_prt.change(
2081
+ fn=tab_inicio_prompt,
2082
+ inputs=[ods_prt,meta_prt,indicador_prt],
2083
+ outputs=[html_inicio_ods_prt]
2084
+ )
2085
+ meta_prt.change(
2086
+ fn=tab_inicio_prompt,
2087
+ inputs=[ods_prt,meta_prt,indicador_prt],
2088
+ outputs=[html_inicio_ods_prt]
2089
+ )
2090
+ indicador_prt.change(
2091
+ fn=tab_inicio_prompt,
2092
+ inputs=[ods_prt,meta_prt,indicador_prt],
2093
+ outputs=[html_inicio_ods_prt]
2094
+ )
2095
+
2096
+
2097
+
2098
+
2099
+ btn_prt.click(procesar_lote, query_in_prt, [ods_prt,meta_prt,indicador_prt], show_progress=True)
2100
+
2101
+
2102
  with gr.Tab("CONSULTA INDIVIDUAL"):
2103
 
2104
  txt_ods = gr.Textbox(value="ods", visible=False)