import numpy as np import pandas as pd import streamlit as st import streamlit.components.v1 as components from transformers import * from carga_articulos import cargar_articulos from preprocesamiento_articulos import limpieza_articulos, remove_URL, remove_html_markup, remove_emoji, remover_casos_especiales, frases_remover, obtener_kpes from entrenamiento_modelo import term_document_matrix, tf_idf_score from resultados_consulta import resultados_consulta, detalles_resultados import tensorflow as tf import tensorflow.python.ops.numpy_ops.np_config as np_config from math import ceil from datetime import datetime def split_frame(input_df, rows): df=[] for i in range(0, len(input_df), rows): df.append(input_df.iloc[i : i + rows, :]) return df def paginar_frame(df): N_cards_per_row = 1 for n_row, row in df.reset_index().iterrows(): i = n_row%N_cards_per_row if i==0: st.write("---") cols = st.columns(N_cards_per_row, gap="large") # draw the card with cols[n_row%N_cards_per_row]: if 'answer' in row: if (row['answer']): t= row['answer'] + ' (score: ' + str(row['score']) + ')' st.info(t) row['resumen']=remove_html_markup(row['resumen']) row['resumen']=remove_URL(row['resumen']) if (len(row['resumen'])>600): row['resumen']=row['resumen'][0:600] st.caption(f"{row['feed'].strip()} - {row['seccion'].strip()} - {row['fecha'].strip()} ") st.markdown(f"**{row['titulo'].strip()}**") st.markdown(f"{row['resumen'].strip()}") st.markdown(f"{row['link']}") def load_qa_model(): tokenizer = AutoTokenizer.from_pretrained('dccuchile/bert-base-spanish-wwm-uncased', use_fast="false") model = TFAutoModelForQuestionAnswering.from_pretrained("Lisibonny/modelo_qa_beto_squad_es_pdqa") return tokenizer, model # 4. Use streamlit to create a web app def main(): st.set_page_config(page_title="Buscador de noticias periodicos dominicanos", page_icon="📰", layout="centered") st.image('repartidor_periodicos.jpeg', width=150) st.header('El Repartidor Dominicano :red[experimental]') df, fecha_min, fecha_max=cargar_articulos() fecha_min=fecha_min[:19] fecha_max=fecha_max[:19] fecha_min=datetime.strptime(fecha_min, '%Y-%m-%d %H:%M:%S') fecha_max=datetime.strptime(fecha_max, '%Y-%m-%d %H:%M:%S') days=(fecha_max-fecha_min).days fecha_min=fecha_min.strftime("%d-%m-%Y %I:%M %p") fecha_max=fecha_max.strftime("%d-%m-%Y %I:%M %p") usar_barra_progreso=1 # Sidebar st.sidebar.header("Acerca De") st.sidebar.markdown( "El Repartidor Dominicano es un sistema de recuperación de información desde periódicos dominicanos que usa técnicas de aprendizaje automático." ) st.sidebar.markdown("Desarrollado por [Lisibonny Beato-Castro](https://scholar.google.com/citations?user=KSzjfeUAAAAJ&hl=es&oi=ao)") st.sidebar.header("Artículos Indexados") st.sidebar.markdown( """ Fuentes: - [Diario Libre](https://www.diariolibre.com/) - [El Nacional](https://www.elnacional.com.do/) - [Remolacha.net](https://www.remolacha.net/) - [AlMomento.net](https://almomento.net/) - [Gente Tuya](http://www.gentetuya.com) """ ) st.sidebar.markdown(f"Noticias de los últimos: **{days} días**") st.sidebar.markdown(f"Fecha más antigua: **{fecha_min}**") st.sidebar.markdown(f"Fecha más reciente: **{fecha_max}**") st.sidebar.header("Aviso Legal Sobre Uso de Datos") st.sidebar.markdown( """ El uso de los artículos en este sitio tiene fines no comerciales, respetando los derechos de autor. Implementamos las mejores prácticas para el uso de RSS, tal y como son recomendadas por el Berkman Klein Center for Internet & Society de la Universidad de Harvard. Si quieres saber más acerca de los feeds RSS o de las mejores prácticas para el uso de RSS, haz clic en los siguientes enlaces: - [RSS](https://es.wikipedia.org/wiki/RSS) - [Uso legal de feeds RSS](https://cyber.harvard.edu/publications/2010/news_aggregator_legal_implications_best_practices) """ ) st.sidebar.header("¡Cómprame un Café!") st.sidebar.markdown("Si te gusta este sitio y quieres darme las gracias o animarme a hacer más, puedes hacer una pequeña donación.") with st.sidebar: st.markdown("[![Haz clic aquí](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate/?hosted_button_id=VK5ZAB52ZYDNA)") articulos_indexados = pd.read_csv('articulos_indexados.csv') articulos_indexados = articulos_indexados.set_index('Unnamed: 0') tokenizer, qa_model = load_qa_model() kpes=obtener_kpes(df) query = st.text_input( "Escribe tus términos de búsqueda o haz una pregunta usando los caracteres ¿?:" ) # Topicos populares st.write("Tópicos populares en los artículos indexados:") cadena = ':blue[' for value in kpes: cadena = cadena + ' - ' + str(value[0]) cadena=cadena + ']' st.write(cadena) if query: # Si se especifico una pregunta if (('¿' == query[0]) and ('?' == query[len(query)-1])): st.write("Contestando a: ", query) # Verificando cada resumen de los articulos como contexto a la pregunta cantidad_respuestas = 0 lista_noticias_respuestas = [] all_results = pd.DataFrame(columns=["id","answer","score","start","end"]) df_answer=df df_answer['answer']='' df_answer['score'] =0 progress_text = "Buscando respuestas. Por favor, espere." my_bar = st.progress(0, text=progress_text) total_respuestas = len(df_answer) for i in range(total_respuestas): text=remove_html_markup(df_answer.loc[i, "resumen"]) text=remove_URL(text) text=remove_emoji(text) text=frases_remover(text) text=remover_casos_especiales(text) inputs = tokenizer(query, text[0:512], return_tensors='tf') input_ids = inputs["input_ids"].numpy()[0] text_tokens = tokenizer.convert_ids_to_tokens(input_ids) outputs = qa_model(inputs) answer_start = tf.argmax(outputs.start_logits, axis=1).numpy()[0] answer_end = (tf.argmax(outputs.end_logits, axis=1) + 1).numpy()[0] answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])) all_results.loc[i] = i,answer, max(outputs.start_logits.numpy()[0]), 0, 0 # Barra de progreso if (usar_barra_progreso==1): porcentaje_progreso = round((i/total_respuestas)*100) if (porcentaje_progreso in range (1,101)): my_bar.progress(porcentaje_progreso, text=progress_text) my_bar.empty() usar_barra_progreso = 0 # Obteniendo las respuestas con los 10 scores mas altos all_results=all_results.sort_values(by=['score'], ascending=False).head(5) # Si hay alguna de ellas que diga que no hay respuesta, no se traera ninguna if not (all_results['answer'].isnull().any()): for index, row in all_results.iterrows(): if (len(row['answer'])>0): cantidad_respuestas = cantidad_respuestas + 1 i=row['id'] df_answer.loc[i, "answer"] = row.loc['answer'] df_answer.loc[i, "score"]= row.loc['score'] lista_noticias_respuestas.append(df_answer.loc[i].to_frame().T) df_noticias_respuestas=pd.concat(lista_noticias_respuestas) batch_size = 5 pages = split_frame(df_noticias_respuestas, batch_size) top_menu = st.columns(3) pagination = st.container() bottom_menu = st.columns((3)) with pagination: with bottom_menu[2]: total_pages = (ceil(cantidad_respuestas / batch_size) if ceil(cantidad_respuestas / batch_size) > 0 else 1) current_page = st.number_input("Página", min_value=1, max_value=total_pages, step=1) with bottom_menu[1]: st.write("---") st.markdown(f"Página **{current_page}** de **{total_pages}** ") with top_menu[0]: pagina_res_fin= batch_size*current_page if batch_size*current_page <= cantidad_respuestas else cantidad_respuestas st.markdown(f"Respuestas **{(current_page*batch_size)-batch_size+1}-{pagina_res_fin}** de **{cantidad_respuestas}** ") paginar_frame(pages[current_page - 1]) # Si se especificaron keywords else: st.write("Buscando: ", query) result = resultados_consulta(df,articulos_indexados, query) if result.empty: st.info("No se encontraron artículos para la búsqueda solicitada") else: df_results=detalles_resultados(df,result) cantidad_resultados=len(df_results) batch_size = 5 pages = split_frame(df_results, batch_size) top_menu = st.columns(3) pagination = st.container() bottom_menu = st.columns((3)) with bottom_menu[2]: total_pages = (ceil(cantidad_resultados / batch_size) if ceil(cantidad_resultados / batch_size) > 0 else 1) current_page = st.number_input("Página", min_value=1, max_value=total_pages, step=1) with bottom_menu[1]: st.write("---") st.markdown(f"Página **{current_page}** de **{total_pages}** ") with top_menu[0]: pagina_res_fin= batch_size*current_page if batch_size*current_page <= cantidad_resultados else cantidad_resultados st.markdown(f"Artículos **{(current_page*batch_size)-batch_size+1}-{pagina_res_fin}** de **{cantidad_resultados}** ") with pagination: paginar_frame(pages[current_page - 1]) if __name__ == "__main__": main()