diff --git a/.gitignore b/.gitignore index 5c17688..0474a51 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,15 @@ nameshf/* photo_2023-09-24_00-25-17.jpg __pycache__/FindinDB.cpython-38.pyc embeddings/* -tuned_models/* \ No newline at end of file +tuned_models/* +Copies3/* +Copies2/* +Tnames/* +TCopies/* +names2/* +Intencionality3/* +__pycache__/FindinDB.cpython-311.pyc +__pycache__/main.cpython-311.pyc +sns_violin* +NewData* +motor05102023.csv diff --git a/retrainEmbbeding.py b/DownloadModels.py similarity index 100% rename from retrainEmbbeding.py rename to DownloadModels.py diff --git a/finetrainmodel.py b/finetrainmodel.py new file mode 100644 index 0000000..4cf5990 --- /dev/null +++ b/finetrainmodel.py @@ -0,0 +1,76 @@ +from sentence_transformers import SentenceTransformer, losses, InputExample +from torch.utils.data import DataLoader +model="embeddings/all-mpnet-base-v2" +modelST = SentenceTransformer(model) + + +train_loss = losses.MultipleNegativesRankingLoss(model=model) + +queries=["reportar un bache en mi comunidad", + "¿Como reporto un bacheo en mi comunidad?", + "Quiero informar sobre un hoyo en la calle cerca de mi hogar.", + "Necesito reportar un bache en la vía cercana a mi residencia.", + "Estoy preocupado por un hueco en la carretera que está cerca de donde vivo.", + "Me gustaría notificar sobre un desnivel en la carretera en las inmediaciones de mi domicilio.", + "Quiero presentar una queja sobre un socavón en la vía que conduce a mi casa.", + "Estoy interesado en denunciar una irregularidad en la calle cercana a mi vivienda.", + "Necesito dar aviso sobre un problema en la carretera próxima a mi residencia.", + "Estoy observando un inconveniente en la carretera cerca de donde vivo y quisiera reportarlo.", + "Me gustaría informar sobre un obstáculo en la vía que está cerca de mi casa.", + "Quiero señalar un desperfecto en la carretera cercana a mi hogar.", + "Necesito poner en conocimiento de las autoridades un bache en la calle adyacente a mi domicilio.", + "Estoy solicitando la atención de las autoridades viales para solucionar un problema en la vía cerca de mi vivienda.", + "Me gustaría expresar mi preocupación acerca de un bache en la carretera que está cerca de donde resido.", + "Quiero dejar constancia de un deterioro en la calle cercana a mi casa.", + "Estoy interesado en informar sobre un desperfecto vial en la carretera cercana a mi hogar.", + "Necesito notificar sobre un agujero en la carretera que conduce a mi residencia.", + "Me gustaría alertar sobre un bache en la vía cerca de mi hogar.", + "Quiero dar aviso sobre un desnivel en la calle próxima a mi vivienda.", + "Estoy buscando reportar un problema vial en la carretera cercana a mi casa.", + "Necesito informar sobre un obstáculo en la vía que está cerca de mi domicilio.", + "Me gustaría señalar una irregularidad en la carretera adyacente a mi residencia.", + "Quiero presentar una queja sobre un desperfecto en la calle cercana a mi hogar.", + "Estoy interesado en denunciar un socavón en la vía que conduce a mi casa.", + "Necesito notificar sobre un inconveniente en la carretera próxima a mi residencia.", + "Me gustaría informar sobre un deterioro en la carretera cerca de donde vivo.", + "Quiero expresar mi preocupación acerca de un bache en la calle que está cerca de mi domicilio.", + "Estoy solicitando la atención de las autoridades para solucionar un problema vial en las inmediaciones de mi casa.", + "Necesito poner en conocimiento de las autoridades competentes un bache en la vía cercana a mi residencia.", + "Me gustaría alertar sobre un agujero en la carretera cerca de mi hogar.", + "Quiero notificar sobre un desnivel en la calle adyacente a mi domicilio.", + "Estoy buscando reportar un desperfecto en la carretera que está cerca de mi casa.", + "Necesito dar aviso sobre un obstáculo en la vía próxima a mi hogar.", + "Me gustaría señalar una irregularidad en la carretera cercana a mi residencia.", + "Quiero presentar una queja sobre un socavón en la vía que conduce a mi residencia.", + "Estoy interesado en denunciar un inconveniente en la carretera próxima a mi casa.", + "Necesito informar sobre un deterioro en la carretera cerca de donde vivo.", + "Quiero expresar mi preocupación acerca de un bache en la calle que está cerca de mi domicilio.", + "Estoy solicitando la atención de las autoridades para solucionar un problema vial en las inmediaciones de mi vivienda.", + "Necesito poner en conocimiento de las autoridades competentes un bache en la vía cercana a mi residencia.", + "Me gustaría alertar sobre un agujero en la carretera cerca de mi hogar.", + "Quiero notificar sobre un desnivel en la calle adyacente a mi domicilio.", + "Estoy buscando reportar un desperfecto en la carretera que está cerca de mi casa.", + "Necesito dar aviso sobre un obstáculo en la vía próxima a mi hogar.", + "Me gustaría señalar una irregularidad en la carretera cercana a mi residencia.", + "Quiero presentar una queja sobre un socavón en la vía que conduce a mi residencia.", + "Estoy interesado en denunciar un inconveniente en la carretera próxima a mi casa.", + "Necesito informar sobre un deterioro en la carretera cerca de donde vivo.", + "Quiero expresar mi preocupación acerca de un bache en la calle que está cerca de mi domicilio.", + "Estoy solicitando la atención de las autoridades para solucionar un problema vial en las inmediaciones de mi vivienda.", + "Necesito poner en conocimiento de las autoridades competentes un bache en la vía cercana a mi residencia." + ] + +train_examples = [] +for q in queries: + train_examples.append(InputExample(texts=[q, 'Reportar un bacheo'])) + +print(train_examples) +train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=5) +print(train_dataloader) +num_epochs = 2 + +warmup_steps = int(len(train_dataloader) * num_epochs * 0.1) #10% of train data + +modelST.fit(train_objectives=[(train_dataloader, train_loss)], + epochs=num_epochs, + warmup_steps=warmup_steps) diff --git a/FindinDB.py b/main.py similarity index 84% rename from FindinDB.py rename to main.py index 466b619..e40d40f 100644 --- a/FindinDB.py +++ b/main.py @@ -24,12 +24,21 @@ from nltk.corpus import stopwords #from cleantext import clean import re -def loadmodelEmb(model_name = "embeddings/all-mpnet-base-v2",model_kwargs = {'device': 'cpu'}): - hf = HuggingFaceEmbeddings( - model_name=model_name, - model_kwargs=model_kwargs - ) - return hf +class CustomEmbedding(Embeddings, BaseModel,): + """embedding model with preprocessing""" + def _get_embedding(self,text) -> List[float]: + #print(text,"text") + text=remove_unwanted(text,punctuationOK=True,stopOK=True) + Sal=emb.encode(text) + return Sal + def embed_documents(self, texts: List[str]) -> List[List[float]]: + Sal=[] + for text in texts: + Sal.append(self._get_embedding(text)) + + return Sal + def embed_query(self, text: str) -> List[float]: + return self._get_embedding(text) def remove_emoji(string): emoji_pattern = re.compile("[" @@ -42,56 +51,51 @@ def remove_emoji(string): "]+", flags=re.UNICODE) return emoji_pattern.sub(r' ', string) -def remove_unwanted(document,stopOk=False): - - # remove user mentions - document = re.sub("@[A-Za-z0-9_]+"," ", document) - # remove URLS - document = re.sub(r'http\S+', ' ', document) - # remove hashtags - document = re.sub("#[A-Za-z0-9_]+","", document) - # remove emoji's - document = remove_emoji(document) +def remove_unwanted(document,stopOK=False,punctuationOK=False,xtrasOK=False, emojiOk=False, unidecodeOK=False): + if punctuationOK: # remove punctuation - for sig in [".",",","!","¿","?","=","(",")"]: - document=document.replace(sig," ") + for sig in [".",",","!","¿","?","=","(",")"]: + document=document.replace(sig," ") + + if xtrasOK: + # remove user mentions + document = re.sub("@[A-Za-z0-9_]+"," ", document) + # remove URLS + document = re.sub(r'http\S+', ' ', document) + # remove hashtags + document = re.sub("#[A-Za-z0-9_]+","", document) + if emojiOk: + # remove emoji's + document = remove_emoji(document) + #document = re.sub("[^0-9A-Za-z ]", "" , document) # remove double spaces #print(document) - document=unidecode(document) - words=document.split(" ") + if unidecodeOK: + document=unidecode(document) + - if stopOk: + if stopOK: + words=document.split(" ") stop_words = set(stopwords.words('spanish')) words = [w for w in words if not w in stop_words] document=" ".join(words) + + document = document.replace(' ',"") #print(document) return document.strip().lower() - -class CustomEmbedding(Embeddings, BaseModel): - """embedding model with preprocessing""" - size=20 - def _get_embedding(self,text) -> List[float]: - #print(text,"text") - text=remove_unwanted(text) - Sal=emb.embed_query(text) - return Sal - def embed_documents(self, texts: List[str]) -> List[List[float]]: - Sal=[] - for text in texts: - Sal.append(self._get_embedding(text)) - - return Sal - def embed_query(self, text: str) -> List[float]: - return self._get_embedding(text) +def loadmodelEmb(model_name = "embeddings/all-MiniLM-L6-v2",model_kwargs = {'device': 'cpu'}): + st = SentenceTransformer(model_name) + return st emb=loadmodelEmb() CUSTOM_PATH = "/angela" app = FastAPI() + @app.get("/") def read_main(): return {"message": "This is your main app"} @@ -155,7 +159,7 @@ def FinderDbs(query,dbs,filtred=False,th=1.2): def QARequest(Pregunta,filtred=False): query = Pregunta - AllData=FinderDbs(query,[db,db2],filtred) + AllData=FinderDbs(query,[db2],filtred) if AllData: import markdown @@ -165,7 +169,9 @@ def QARequest(Pregunta,filtred=False): for k,i in enumerate(AllData[0].items()): titulo = f"

Respuesta {k+1}

" to_append = markdown.markdown(i[1]['page_content']) - lista = lista + titulo + to_append + '
' + to_append2 =markdown.markdown(str(i[1]['d'])) + print(i) + lista = lista + titulo + to_append +to_append2+ '' #lista.append('
') #lista = lista + '' diff --git a/loadModelinlocal.py b/metrics.py similarity index 57% rename from loadModelinlocal.py rename to metrics.py index 776a7cf..4b407ae 100644 --- a/loadModelinlocal.py +++ b/metrics.py @@ -4,6 +4,7 @@ from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import FAISS from langchain.pydantic_v1 import BaseModel from langchain.schema.embeddings import Embeddings +from sentence_transformers import SentenceTransformer from scipy.spatial import distance from typing import List import sqlite3 @@ -15,13 +16,24 @@ import inspect import time from unidecode import unidecode from nltk.corpus import stopwords -class CustomEmbedding(Embeddings, BaseModel): +import seaborn as sns +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("-f", "--file", help="Nombre de archivo a procesar") +parser.add_argument("-d", "--distance", default="distance") +parser.add_argument("-m", "--models", default="All") +args = parser.parse_args() + + +# if args.file: +# print ("El nombre de archivo a procesar es: ", ) +class CustomEmbedding(Embeddings, BaseModel,): """embedding model with preprocessing""" - size=20 def _get_embedding(self,text) -> List[float]: #print(text,"text") - text=remove_unwanted(text) - Sal=emb.embed_query(text) + text=remove_unwanted(text,punctuationOK=True,stopOK=True) + Sal=emb.encode(text) return Sal def embed_documents(self, texts: List[str]) -> List[List[float]]: Sal=[] @@ -43,40 +55,45 @@ def remove_emoji(string): "]+", flags=re.UNICODE) return emoji_pattern.sub(r' ', string) -def remove_unwanted(document,stopOk=False): - - # remove user mentions - document = re.sub("@[A-Za-z0-9_]+"," ", document) - # remove URLS - document = re.sub(r'http\S+', ' ', document) - # remove hashtags - document = re.sub("#[A-Za-z0-9_]+","", document) - # remove emoji's - document = remove_emoji(document) +def remove_unwanted(document,stopOK=False,punctuationOK=False,xtrasOK=False, emojiOk=False, unidecodeOK=False): + if punctuationOK: # remove punctuation - for sig in [".",",","!","¿","?","=","(",")"]: - document=document.replace(sig," ") + for sig in [".",",","!","¿","?","=","(",")"]: + document=document.replace(sig," ") + + if xtrasOK: + # remove user mentions + document = re.sub("@[A-Za-z0-9_]+"," ", document) + # remove URLS + document = re.sub(r'http\S+', ' ', document) + # remove hashtags + document = re.sub("#[A-Za-z0-9_]+","", document) + if emojiOk: + # remove emoji's + document = remove_emoji(document) + #document = re.sub("[^0-9A-Za-z ]", "" , document) # remove double spaces #print(document) - document=unidecode(document) - words=document.split(" ") + if unidecodeOK: + document=unidecode(document) + - if stopOk: + if stopOK: + words=document.split(" ") stop_words = set(stopwords.words('spanish')) words = [w for w in words if not w in stop_words] document=" ".join(words) + + document = document.replace(' ',"") #print(document) return document.strip().lower() def loadmodelEmb(model_name = "embeddings/all-MiniLM-L6-v2",model_kwargs = {'device': 'cpu'}): - hf = HuggingFaceEmbeddings( - model_name=model_name, - model_kwargs=model_kwargs - ) - return hf + st = SentenceTransformer(model_name) + return st def loadCopysAndData(pathsqlite="motor.sqlite"): @@ -123,10 +140,11 @@ def FinderDbs(query,dbs,filtred=False,th=1.2): else: AllData=dict(sorted(AllData.items(), key=lambda item: item[1]["d"])) return AllData,AllData.keys() - -models=["all-MiniLM-L12-v2","paraphrase-MiniLM-L3-v2" , "all-MiniLM-L6-v2","all-mpnet-base-v2","multi-qa-mpnet-base-dot-v1"] - -queries=["Quiero reportar un bacheo", +if args.models=="All": + models=["all-MiniLM-L12-v2","paraphrase-MiniLM-L3-v2" , "all-MiniLM-L6-v2","all-mpnet-base-v2","multi-qa-mpnet-base-dot-v1"] +else: + models=["all-mpnet-base-v2"] +queries_bacheo=["Quiero reportar un bacheo", "reportar un bache en mi comunidad", "¿Como reporto un bacheo en mi comunidad?", "Quiero informar sobre un hoyo en la calle cerca de mi hogar.", @@ -205,36 +223,7 @@ queries=["Quiero reportar un bacheo", # print(AllData[1],point) - -copies_text=["Saber sobre actividades culturales.", -"Saber sobre talleres.", -"Información sobre talleres de literatura.", -"Información sobre talleres de formación artistica.", -"Obtener la certificación de uso de suelos.", -"Reportar un bacheo.", -"Saber dónde pago un parquímetro.", -] -for model in models: - print(model) - print(""" - - - """) - t=time.time() - for copy_text in copies_text: - emb=loadmodelEmb(model_name = model) - emb2=CustomEmbedding() - sal=[] - for query in queries: - sal.append(distance.cosine(emb2.embed_query(query),emb2.embed_query(copy_text))) - print(model,",",copy_text,",",np.mean(sal),",",np.std(sal),",",(time.time()-t)/len(queries)) - - - - - - -{ +queries_Categoricos={ "formas_de_reportar_bache": [ "Quiero informar sobre un hoyo en la calle cerca de mi hogar.", "Necesito reportar un bache en la vía cercana a mi residencia.", @@ -286,5 +275,173 @@ for model in models: "Quiero expresar mi preocupación acerca de un bache en la calle que está cerca de mi domicilio.", "Estoy solicitando la atención de las autoridades para solucionar un problema vial en las inmediaciones de mi vivienda.", "Necesito poner en conocimiento de las autoridades competentes un bache en la vía cercana a mi residencia." + ], + "formas_de_preguntar_agenda_cultural_puebla": [ + "¿Me podrías proporcionar información sobre los eventos culturales en Puebla?", + "Quiero estar al tanto de lo que está pasando en la escena cultural de Puebla.", + "¿Dónde puedo encontrar detalles sobre las actividades culturales en Puebla?", + "Estoy interesado en saber qué eventos culturales hay en Puebla.", + "Me gustaría conocer la programación cultural de Puebla.", + "¿Puedes decirme cuáles son los eventos culturales próximos en Puebla?", + "Estoy buscando información sobre la oferta cultural en Puebla.", + "¿Dónde puedo obtener información sobre la vida cultural de Puebla?", + "Estoy buscando recomendaciones sobre eventos culturales en Puebla.", + "¿Qué está pasando en el ámbito cultural en Puebla?", + "Me gustaría estar al tanto de los eventos culturales en Puebla.", + "¿Puedes proporcionarme la agenda de la cultura en Puebla?", + "Quiero saber cuáles son las propuestas culturales en Puebla.", + "¿Cuáles son los eventos culturales destacados en Puebla?", + "Estoy interesado en la escena cultural de Puebla, ¿dónde puedo encontrar información?", + "¿Dónde puedo consultar los eventos culturales que se celebrarán en Puebla?", + "Necesito saber qué actividades culturales puedo disfrutar en Puebla.", + "¿Me puedes indicar los acontecimientos culturales en Puebla?", + "Quiero informarme acerca de la oferta cultural de Puebla.", + "¿Dónde puedo obtener un listado de los eventos culturales en Puebla?", + "Estoy buscando información sobre la vida artística en Puebla.", + "¿Qué opciones culturales hay disponibles en Puebla en estos momentos?", + "Me gustaría conocer los eventos culturales previstos en Puebla.", + "¿Puedes recomendarme actividades culturales en Puebla?", + "Quiero enterarme de las novedades culturales de Puebla.", + "¿Cuál es la agenda de eventos culturales en Puebla?", + "Estoy interesado en asistir a eventos culturales en Puebla, ¿dónde puedo encontrar información?", + "¿Dónde puedo consultar la programación cultural actual de Puebla?", + "Necesito saber cuáles son las propuestas culturales más recientes en Puebla.", + "¿Me puedes decir qué eventos culturales están en marcha en Puebla?", + "Estoy buscando opciones para disfrutar de la cultura en Puebla.", + "¿Qué actividades culturales se ofrecen en Puebla en este momento?", + "Me gustaría estar al tanto de los espectáculos culturales en Puebla.", + "¿Puedes proporcionarme información sobre los eventos culturales próximos en Puebla?", + "Quiero saber qué está pasando en la escena cultural de Puebla.", + "¿Cuál es la oferta cultural actual en Puebla?", + "Estoy interesado en conocer los eventos culturales destacados de Puebla.", + "¿Dónde puedo encontrar la programación cultural más completa de Puebla?", + "Necesito detalles sobre la agenda cultural de Puebla.", + "¿Me podrías decir cuáles son las opciones culturales en Puebla en estos días?", + "Quiero informarme sobre los eventos culturales que no me puedo perder en Puebla.", + "¿Puedes recomendarme eventos culturales en Puebla?", + "Estoy buscando información sobre la agenda cultural y artística de Puebla." + ], + "formas_de_solicitar_informacion_musica": [ + "Estoy interesado en obtener datos sobre talleres de música.", + "Necesito información acerca de cursos de música.", + "Quiero conocer más sobre talleres de formación musical.", + "¿Puede proporcionarme detalles sobre programas de música?", + "Me gustaría recibir información sobre clases de música.", + "Estoy buscando datos acerca de talleres para aprender música.", + "¿Puede darme detalles sobre cursos de instrucción musical?", + "Quiero saber más sobre oportunidades de aprendizaje musical.", + "Estoy interesado en talleres para desarrollar habilidades musicales.", + "Necesito información sobre clases prácticas de música.", + "¿Puede brindarme datos sobre programas de formación musical?", + "Me gustaría conocer opciones para aprender música.", + "Estoy en busca de talleres musicales, ¿puede ayudarme?", + "Quiero obtener detalles sobre cursos de música disponibles.", + "Necesito información sobre talleres de instrucción musical.", + "¿Puede proporcionarme datos sobre clases para músicos?", + "Me gustaría saber más sobre oportunidades de formación musical.", + "Estoy interesado en aprender música, ¿puede orientarme?", + "Quiero conocer más sobre talleres para mejorar en música.", + "Necesito información sobre programas de capacitación musical.", + "¿Puede darme detalles sobre cursos de formación en música?", + "Estoy buscando opciones para aprender a tocar instrumentos.", + "Me gustaría recibir información sobre clases de educación musical.", + "Estoy interesado en talleres de música, ¿puede asesorarme?", + "Quiero obtener datos sobre oportunidades de estudio musical.", + "Necesito información sobre talleres de música en mi área.", + "¿Puede proporcionarme detalles sobre cursos de música locales?", + "Me gustaría saber más sobre clases de música para principiantes.", + "Estoy en busca de talleres de formación musical asequibles.", + "Quiero conocer opciones para mejorar mis habilidades musicales.", + "Estoy interesado en aprender música de manera profesional.", + "Necesito información sobre talleres de música para niños.", + "¿Puede darme datos sobre cursos de música para adultos?", + "Me gustaría recibir información sobre clases de canto.", + "Estoy buscando oportunidades de instrucción musical avanzada.", + "Quiero obtener detalles sobre talleres de producción musical.", + "Necesito información sobre programas de educación musical en línea.", + "¿Puede proporcionarme detalles sobre cursos de música en vivo?", + "Me gustaría saber más sobre clases de composición musical.", + "Estoy interesado en talleres de música clásica.", + "Quiero conocer opciones para estudiar teoría musical.", + "Necesito información sobre talleres de música contemporánea.", + "¿Puede darme datos sobre cursos de improvisación musical?", + "Me gustaría recibir información sobre clases de jazz.", + "Estoy buscando oportunidades de formación en música electrónica.", + "Quiero obtener detalles sobre talleres de guitarra.", + "Necesito información sobre programas de educación musical para la infancia.", + "¿Puede proporcionarme detalles sobre cursos de producción de música electrónica?", + "Me gustaría saber más sobre clases de música para adultos mayores.", + "Estoy interesado en talleres de música étnica y world music." ] -} \ No newline at end of file +} + + +copies_text=["Saber agenda cultural de Puebla", +"Información de talleres de musica", +"Informacion de talleres de danza urbana", +"Obtener uso de suelo", +"Reportar un bacheo.", +"Informacion general de parquimetros", +"Informacion Parque Benito Juárez" +] + +def plotVioin(Sal,Listqueries): + NewData=pd.DataFrame.from_dict(Sal) + + plt=sns.violinplot(data=NewData, x="model", y="distance", hue="copy_test",fill=False,inner=None,width=0.5) + + plt.set_xticklabels(plt.get_xticklabels(), rotation=45,horizontalalignment='right') + + fig=plt.get_figure() + fig.set_size_inches(17.7, 12.27) + fig.savefig('sns_violin_plot%s.png'%(Listqueries), dpi=300) + NewData.to_csv("NewData%s.csv"%(Listqueries)) +def plotViointime(Sal,Listqueries): + NewData=pd.DataFrame.from_dict(Sal) + + plt=sns.violinplot(data=NewData, x="model", y="time",fill=False,inner=None,width=0.5) + + plt.set_xticklabels(plt.get_xticklabels(), rotation=45,horizontalalignment='right') + + fig=plt.get_figure() + fig.set_size_inches(17.7, 12.27) + fig.savefig('sns_violin_plot_time%s.png'%(Listqueries), dpi=300) + NewData.to_csv("NewData%s.csv"%(Listqueries)) +def queries_CatPlot(Listqueries): + Sal=[] + queries=queries_Categoricos[Listqueries] + for model in models: + for copy_text in copies_text: + global emb + emb=loadmodelEmb(model_name = model) + emb2=CustomEmbedding() + emb2.embed_query("test 123321") + sal=[] + for query in queries: + t=time.time() + A={"model":model, + "query":query, + "copy_test":copy_text, + "distance":distance.cosine(emb2.embed_query(query),emb2.embed_query(copy_text)), + "time":time.time()-t + } + Sal.append(A) + if args.distance=="distance": + plotVioin(Sal,Listqueries) + if args.distance=="time": + plotViointime(Sal,Listqueries) + + + +queries_CatPlot(args.file) + + + + + + + + + + +