Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
ia:desinformadores [2025/01/26 17:49] anonimo |
ia:desinformadores [2025/02/01 03:57] (actual) anonimo |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | 1º Tomar como base los principales desinformadores de España, que son los que proporcionan una información más heterogenea en datos\\ | ||
| + | 2º Extraer los títulos de los vídeos,shorts y directos de youtube mediante web scrapping\\ | ||
| + | 3º Limpiarlos de caracteres extraños, tildes, artículos y preposiciones que no sirven para el propósito mediante el editor de textos sed\\ | ||
| + | 4º Hacer pruebas midiendo el grado de similitud ideológica de diferentes usuarios/seguidores respecto a dichos desinformadores\\ | ||
| + | |||
| + | |||
| + | **Extraemos los títulos de los vídeos, shorts y directos mediante web scrapping** | ||
| <code python> | <code python> | ||
| """ | """ | ||
| Línea 29: | Línea 36: | ||
| import time | import time | ||
| - | def obtener_videos_con_scroll(url_canal): | + | def manejar_mensaje_cookies(driver): |
| - | # Inicializa el navegador (asegúrate de tener el driver de Chrome o Firefox) | + | #Maneja el mensaje de cookies en YouTube. |
| - | driver = webdriver.Chrome() # O webdriver.Firefox(), dependiendo de tu elección | + | try: |
| + | # Espera hasta que el botón de cookies sea visible | ||
| + | boton_cookies = WebDriverWait(driver, 10).until( | ||
| + | EC.element_to_be_clickable((By.XPATH, '//button[.//span[text()="Aceptar todo"]]')) | ||
| + | ) | ||
| + | boton_cookies.click() # Haz clic en el botón | ||
| + | print("Mensaje de cookies cerrado.") | ||
| + | except Exception as e: | ||
| + | print(f"No se encontró el mensaje de cookies o hubo un error: {e}") | ||
| - | # Navega a la página del canal | + | def iniciar_driver(): |
| + | """Inicializa el navegador de Selenium.""" | ||
| + | options = webdriver.ChromeOptions() | ||
| + | options.add_argument('--headless') # Modo sin interfaz gráfica (opcional) | ||
| + | options.add_argument('--disable-gpu') | ||
| + | options.add_argument('--no-sandbox') | ||
| + | options.add_argument('--disable-dev-shm-usage') | ||
| + | return webdriver.Chrome(options=options) | ||
| + | |||
| + | def obtener_videos_con_scroll(url_canal): | ||
| + | driver = iniciar_driver() | ||
| driver.get(url_canal) | driver.get(url_canal) | ||
| - | time.sleep(5) # Espera un poco más para que la página cargue completamente | + | time.sleep(5) # Espera un poco para que la página cargue completamente |
| + | |||
| + | # Manejar el mensaje de cookies | ||
| + | manejar_mensaje_cookies(driver) | ||
| - | # Simula el scroll hacia abajo para cargar más videos | + | SCROLL_PAUSE_TIME = 4 |
| - | SCROLL_PAUSE_TIME = 4 # Aumenta el tiempo de pausa | + | |
| last_height = driver.execute_script("return document.documentElement.scrollHeight") | last_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| - | | + | videos_cargados = set() |
| - | videos_cargados = set() # Usamos un conjunto para evitar duplicados | + | |
| while True: | while True: | ||
| - | # Desplaza hacia abajo | ||
| driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | ||
| time.sleep(SCROLL_PAUSE_TIME) | time.sleep(SCROLL_PAUSE_TIME) | ||
| - | |||
| - | # Calcula la nueva altura de la página y compara con la anterior | ||
| - | new_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| - | | ||
| - | # Recoge los videos visibles usando el nuevo selector | ||
| videos = driver.find_elements(By.XPATH, '//ytd-rich-grid-media//yt-formatted-string[@id="video-title"]') | videos = driver.find_elements(By.XPATH, '//ytd-rich-grid-media//yt-formatted-string[@id="video-title"]') | ||
| - | | ||
| - | # Depurar: Imprimir cuántos videos se encontraron en esta iteración | ||
| print(f"Videos encontrados en esta iteración: {len(videos)}") | print(f"Videos encontrados en esta iteración: {len(videos)}") | ||
| - | | + | |
| for video in videos: | for video in videos: | ||
| - | title = video.text # Usar .text para obtener el título visible | + | try: |
| - | link = video.find_element(By.XPATH, './ancestor::ytd-rich-grid-media//a').get_attribute('href') # Obtener el enlace | + | title = video.text |
| - | # Añade a un conjunto para evitar duplicados | + | link = video.find_element(By.XPATH, './ancestor::ytd-rich-grid-media//a').get_attribute('href') |
| - | videos_cargados.add((title, link)) | + | videos_cargados.add((title, link)) |
| + | except Exception as e: | ||
| + | print(f"Error al extraer un video: {e}") | ||
| - | # Si la altura no cambia, hemos llegado al final | + | new_height = driver.execute_script("return document.documentElement.scrollHeight") |
| if new_height == last_height: | if new_height == last_height: | ||
| break | break | ||
| - | | ||
| last_height = new_height | last_height = new_height | ||
| driver.quit() | driver.quit() | ||
| - | | ||
| - | # Convertir el conjunto a lista de diccionarios | ||
| lista_videos = [{'titulo': title, 'link': link} for title, link in videos_cargados] | lista_videos = [{'titulo': title, 'link': link} for title, link in videos_cargados] | ||
| - | | ||
| - | # Depurar: imprimir la cantidad total de videos recogidos | ||
| print(f"Total de videos recogidos: {len(lista_videos)}") | print(f"Total de videos recogidos: {len(lista_videos)}") | ||
| - | | ||
| return lista_videos | return lista_videos | ||
| def obtener_shorts_con_scroll(url_canal): | def obtener_shorts_con_scroll(url_canal): | ||
| - | # Inicializa el navegador (asegúrate de tener el driver de Chrome o Firefox) | + | driver = iniciar_driver() |
| - | driver = webdriver.Chrome() # O webdriver.Firefox(), dependiendo de tu elección | + | driver.get(url_canal) |
| + | time.sleep(5) | ||
| - | # Navega a la página de Shorts del canal | + | # Manejar el mensaje de cookies |
| - | driver.get(url_canal) | + | manejar_mensaje_cookies(driver) |
| - | time.sleep(5) # Espera un poco para que la página cargue completamente | + | |
| - | # Simula el scroll hacia abajo para cargar más shorts | ||
| SCROLL_PAUSE_TIME = 3 | SCROLL_PAUSE_TIME = 3 | ||
| last_height = driver.execute_script("return document.documentElement.scrollHeight") | last_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| - | | + | shorts_cargados = set() |
| - | shorts_cargados = set() # Usamos un conjunto para evitar duplicados | + | |
| while True: | while True: | ||
| - | # Desplaza hacia abajo | ||
| driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | ||
| time.sleep(SCROLL_PAUSE_TIME) | time.sleep(SCROLL_PAUSE_TIME) | ||
| - | + | shorts = driver.find_elements(By.XPATH, '//a[contains(@class, "shortsLockupViewModelHostEndpoint")]') | |
| - | # Esperar explícitamente hasta que los elementos de shorts estén presentes | + | |
| - | shorts = WebDriverWait(driver, 10).until( | + | |
| - | EC.presence_of_all_elements_located((By.XPATH, '//a[contains(@class, "shortsLockupViewModelHostEndpoint")]')) | + | |
| - | ) | + | |
| - | + | ||
| - | # Depurar: Imprimir cuántos shorts se encontraron en esta iteración | + | |
| print(f"Shorts encontrados en esta iteración: {len(shorts)}") | print(f"Shorts encontrados en esta iteración: {len(shorts)}") | ||
| for short in shorts: | for short in shorts: | ||
| try: | try: | ||
| - | # Extraer título y enlace de cada short | ||
| title = short.get_attribute('title') | title = short.get_attribute('title') | ||
| link = "https://www.youtube.com" + short.get_attribute('href') | link = "https://www.youtube.com" + short.get_attribute('href') | ||
| - | # Añadir al conjunto | ||
| shorts_cargados.add((title, link)) | shorts_cargados.add((title, link)) | ||
| except Exception as e: | except Exception as e: | ||
| print(f"Error al extraer un short: {e}") | print(f"Error al extraer un short: {e}") | ||
| - | # Calcular la nueva altura y compararla con la anterior | ||
| new_height = driver.execute_script("return document.documentElement.scrollHeight") | new_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| if new_height == last_height: | if new_height == last_height: | ||
| Línea 123: | Línea 125: | ||
| driver.quit() | driver.quit() | ||
| - | | ||
| - | # Convertir el conjunto a lista de diccionarios | ||
| lista_shorts = [{'titulo': title, 'link': link} for title, link in shorts_cargados] | lista_shorts = [{'titulo': title, 'link': link} for title, link in shorts_cargados] | ||
| - | | ||
| - | # Depurar: imprimir la cantidad total de shorts recogidos | ||
| print(f"Total de shorts recogidos: {len(lista_shorts)}") | print(f"Total de shorts recogidos: {len(lista_shorts)}") | ||
| - | | ||
| return lista_shorts | return lista_shorts | ||
| - | |||
| - | |||
| - | |||
| def obtener_streams_con_scroll(url_canal): | def obtener_streams_con_scroll(url_canal): | ||
| - | # Inicializa el navegador (asegúrate de tener el driver de Chrome o Firefox) | + | driver = iniciar_driver() |
| - | driver = webdriver.Chrome() # O webdriver.Firefox(), dependiendo de tu elección | + | |
| - | + | ||
| - | # Navega a la página de Streams del canal | + | |
| driver.get(url_canal) | driver.get(url_canal) | ||
| - | time.sleep(4) # Espera un poco más para que la página cargue completamente | + | time.sleep(5) |
| - | # Simula el scroll hacia abajo para cargar más streams | + | # Manejar el mensaje de cookies |
| - | SCROLL_PAUSE_TIME = 3 # Aumenta el tiempo de pausa | + | manejar_mensaje_cookies(driver) |
| + | |||
| + | SCROLL_PAUSE_TIME = 3 | ||
| last_height = driver.execute_script("return document.documentElement.scrollHeight") | last_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| - | | + | streams_cargados = set() |
| - | streams_cargados = set() # Usamos un conjunto para evitar duplicados | + | |
| while True: | while True: | ||
| - | # Desplaza hacia abajo | ||
| driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);") | ||
| time.sleep(SCROLL_PAUSE_TIME) | time.sleep(SCROLL_PAUSE_TIME) | ||
| - | |||
| - | # Calcula la nueva altura de la página y compara con la anterior | ||
| - | new_height = driver.execute_script("return document.documentElement.scrollHeight") | ||
| - | | ||
| - | # Recoge los streams visibles usando el nuevo selector | ||
| streams = driver.find_elements(By.XPATH, '//a[@id="video-title-link"]') | streams = driver.find_elements(By.XPATH, '//a[@id="video-title-link"]') | ||
| - | | ||
| - | # Depurar: Imprimir cuántos streams se encontraron en esta iteración | ||
| print(f"Streams encontrados en esta iteración: {len(streams)}") | print(f"Streams encontrados en esta iteración: {len(streams)}") | ||
| - | | + | |
| for stream in streams: | for stream in streams: | ||
| - | title = stream.get_attribute('title') # Obtener el título | + | try: |
| - | link = "https://www.youtube.com" + stream.get_attribute('href') # Obtener el enlace completo | + | title = stream.get_attribute('title') |
| - | # Añade a un conjunto para evitar duplicados | + | link = "https://www.youtube.com" + stream.get_attribute('href') |
| - | streams_cargados.add((title, link)) | + | streams_cargados.add((title, link)) |
| + | except Exception as e: | ||
| + | print(f"Error al extraer un stream: {e}") | ||
| - | # Si la altura no cambia, hemos llegado al final | + | new_height = driver.execute_script("return document.documentElement.scrollHeight") |
| if new_height == last_height: | if new_height == last_height: | ||
| break | break | ||
| - | | ||
| last_height = new_height | last_height = new_height | ||
| driver.quit() | driver.quit() | ||
| - | | ||
| - | # Convertir el conjunto a lista de diccionarios | ||
| lista_streams = [{'titulo': title, 'link': link} for title, link in streams_cargados] | lista_streams = [{'titulo': title, 'link': link} for title, link in streams_cargados] | ||
| - | | ||
| - | # Depurar: imprimir la cantidad total de streams recogidos | ||
| print(f"Total de streams recogidos: {len(lista_streams)}") | print(f"Total de streams recogidos: {len(lista_streams)}") | ||
| - | | ||
| return lista_streams | return lista_streams | ||
| - | # URL del canal (videos, shorts, streams) | + | # URLs de ejemplo |
| url_videos = "https://www.youtube.com/@geoestratego_oficial/videos" | url_videos = "https://www.youtube.com/@geoestratego_oficial/videos" | ||
| url_shorts = "https://www.youtube.com/@geoestratego_oficial/shorts" | url_shorts = "https://www.youtube.com/@geoestratego_oficial/shorts" | ||
| url_streams = "https://www.youtube.com/@geoestratego_oficial/streams" | url_streams = "https://www.youtube.com/@geoestratego_oficial/streams" | ||
| - | # Obtener videos, shorts y streams | + | titulos_videos = obtener_videos_con_scroll(url_videos) |
| titulos_shorts = obtener_shorts_con_scroll(url_shorts) | titulos_shorts = obtener_shorts_con_scroll(url_shorts) | ||
| - | titulos_videos = obtener_videos_con_scroll(url_videos) | ||
| titulos_streams = obtener_streams_con_scroll(url_streams) | titulos_streams = obtener_streams_con_scroll(url_streams) | ||
| - | # Combinar resultados | + | for titulo in titulos_videos + titulos_shorts + titulos_streams: |
| - | titulos_totales = titulos_videos + titulos_shorts + titulos_streams | + | print(f"Título: {titulo['titulo']}, Enlace: {titulo['link']}") |
| - | # Imprimir los títulos y enlaces de los videos, shorts y streams | ||
| - | for titulo in titulos_totales: | ||
| - | print(f"Título: {titulo['titulo']}, Enlace: {titulo['link']}") | ||
| | | ||
| python3 raspado.py > geoestratego.txt | python3 raspado.py > geoestratego.txt | ||
| </code> | </code> | ||
| + | El resultado está en éste archivo {{ :ia:desinformadores.gz |}}\\ | ||
| + | |||
| **El .txt hay que prepararlo y no lo está, ésto contienen las 4 primeras líneas** | **El .txt hay que prepararlo y no lo está, ésto contienen las 4 primeras líneas** | ||
| <code bash> | <code bash> | ||
| Línea 215: | Línea 193: | ||
| <code bash> | <code bash> | ||
| cat geoestratego.txt | grep Título | sed '/^Título: ,/d;s/^Título: //g;s/, Enlace: .*$//g;s/[A-Z]/\L&/g;y/áéíóú/aeiou/;s/[^a-zñ0-9 ]/ /g;s/ \+/ /g' | perl -ple 's/[^a-zñÑ0-9 ]//gi' | perl -ple '$_=lc' | sed 's/ \+/ /g;s/^ //g' > geoestratego_.txt | cat geoestratego.txt | grep Título | sed '/^Título: ,/d;s/^Título: //g;s/, Enlace: .*$//g;s/[A-Z]/\L&/g;y/áéíóú/aeiou/;s/[^a-zñ0-9 ]/ /g;s/ \+/ /g' | perl -ple 's/[^a-zñÑ0-9 ]//gi' | perl -ple '$_=lc' | sed 's/ \+/ /g;s/^ //g' > geoestratego_.txt | ||
| + | </code> | ||
| + | **volvemos a limpiar**\\ | ||
| + | <code bash> | ||
| + | sed -Ei 's/ de / /g;s/ la / /g;s/ los / /g;s/ las / /g;s/ y / /g;s/ el / /g;s/ del / /g;s/ al / /g;s/ a / /g;s/^el |^la |^los |^las //g;s/^lo //g;s/ en / /g;s/ un / /g;s/^ //g;' geoestratego_.txt | ||
| </code> | </code> | ||
| **El .txt ya está preparado, éstas son las 4 primeras líneas** | **El .txt ya está preparado, éstas son las 4 primeras líneas** | ||
| <code bash> | <code bash> | ||
| cat geoestratego_.txt | sed -n '1,4p' | cat geoestratego_.txt | sed -n '1,4p' | ||
| - | el plan final de biden para desestabilizar el mundo | + | plan final biden para desestabilizar mundo |
| marcha militar coronel pedro baños | marcha militar coronel pedro baños | ||
| - | pedro baños y la geopolitica 2 3 | + | pedro baños geopolitica 2 3 |
| - | los medios de comunicacion pierden el control | + | medios comunicacion pierden control |
| cat geoestratego_.txt | wc -l | cat geoestratego_.txt | wc -l | ||
| Línea 231: | Línea 214: | ||
| **Preparación de los datos**\\ | **Preparación de los datos**\\ | ||
| <code python> | <code python> | ||
| - | import os | + | """ |
| - | from transformers import AutoTokenizer | + | MIT License |
| - | + | ||
| - | # Ruta a la carpeta con los archivos | + | Copyright (c) 2025 wiki.acosadores.net |
| - | ruta_listados = "./listados" | + | |
| + | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + | of this software and associated documentation files (the "Software"), to deal | ||
| + | in the Software without restriction, including without limitation the rights | ||
| + | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + | copies of the Software, and to permit persons to whom the Software is | ||
| + | furnished to do so, subject to the following conditions: | ||
| + | |||
| + | The above copyright notice and this permission notice shall be included in all | ||
| + | copies or substantial portions of the Software. | ||
| + | |||
| + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| + | SOFTWARE. | ||
| + | """ | ||
| + | from sklearn.feature_extraction.text import TfidfVectorizer | ||
| + | from sklearn.metrics.pairwise import cosine_similarity | ||
| - | # Códigos asociados a cada listado | + | # 1. Leer los archivos .txt |
| - | codigos_asociados = { | + | with open("usuario.txt", "r", encoding="utf-8") as f1, open("geoestratego_.txt", "r", encoding="utf-8") as f2: |
| - | "geoestratego_.txt": [1, 2], | + | frases1 = f1.readlines() # Frases de usuario.txt |
| - | "listado2.txt": [1], | + | frases2 = f2.readlines() # Frases de geoestratego.txt |
| - | } | + | |
| - | # Tokenizer de BERT para procesar palabras | + | # 2. Vectorizar las frases de ambos ficheros con TF-IDF |
| - | tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") | + | vectorizer = TfidfVectorizer() |
| - | + | tfidf_matrix1 = vectorizer.fit_transform(frases1) # Matriz TF-IDF para fichero1 | |
| - | # Leer los listados y tokenizarlos | + | tfidf_matrix2 = vectorizer.transform(frases2) # Transformamos fichero2 con el mismo modelo |
| - | listados = {} | + | |
| - | for archivo in os.listdir(ruta_listados): | + | |
| - | if archivo.endswith(".txt"): | + | |
| - | with open(os.path.join(ruta_listados, archivo), "r", encoding="utf-8") as f: | + | |
| - | frases = f.read().splitlines() # Cada línea es una frase | + | |
| - | tokenized = [tokenizer(f, truncation=True, padding='max_length', max_length=20, return_tensors="pt") for f in frases] | + | |
| - | listados[archivo] = { | + | |
| - | "frases": tokenized, | + | |
| - | "codigos": codigos_asociados.get(archivo, []) | + | |
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | **Definición del modelo con LSTM**\\ | + | |
| - | <code python> | + | |
| - | import torch | + | |
| - | import torch.nn as nn | + | |
| - | + | ||
| - | class LSTMFrases(nn.Module): | + | |
| - | def __init__(self, embed_dim, hidden_dim, output_dim): | + | |
| - | super(LSTMFrases, self).__init__() | + | |
| - | self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True, bidirectional=True) | + | |
| - | self.fc = nn.Linear(hidden_dim * 2, output_dim) # Bidireccional, por eso 2x hidden_dim | + | |
| - | self.sigmoid = nn.Sigmoid() | + | |
| - | + | ||
| - | def forward(self, x): | + | |
| - | _, (hidden, _) = self.lstm(x) # hidden: (2, batch_size, hidden_dim) | + | |
| - | hidden = torch.cat((hidden[0], hidden[1]), dim=1) # Concatenar direcciones | + | |
| - | output = self.fc(hidden) | + | |
| - | return self.sigmoid(output) | + | |
| - | </code> | + | |
| - | + | ||
| - | **Entrenamiento** | + | |
| - | <code python> | + | |
| - | from torch.utils.data import DataLoader, Dataset | + | |
| - | + | ||
| - | # Dataset para manejar frases y etiquetas | + | |
| - | class FrasesDataset(Dataset): | + | |
| - | def __init__(self, frases, codigos, embed_dim): | + | |
| - | self.frases = frases | + | |
| - | self.codigos = codigos | + | |
| - | self.embed_dim = embed_dim | + | |
| - | + | ||
| - | def __len__(self): | + | |
| - | return len(self.frases) | + | |
| - | + | ||
| - | def __getitem__(self, idx): | + | |
| - | tokens = self.frases[idx]["input_ids"].squeeze(0) | + | |
| - | mask = self.frases[idx]["attention_mask"].squeeze(0) | + | |
| - | etiqueta = torch.tensor(self.codigos, dtype=torch.float) | + | |
| - | return tokens, mask, etiqueta | + | |
| - | + | ||
| - | # Configuración del modelo y entrenamiento | + | |
| - | embed_dim = 768 # Dimensión de BERT | + | |
| - | hidden_dim = 128 | + | |
| - | epochs = 5 | + | |
| - | batch_size = 4 | + | |
| - | learning_rate = 0.001 | + | |
| - | + | ||
| - | modelos = {} | + | |
| - | for nombre, datos in listados.items(): | + | |
| - | num_codigos = len(datos["codigos"]) | + | |
| - | modelo = LSTMFrases(embed_dim, hidden_dim, num_codigos) | + | |
| - | dataset = FrasesDataset(datos["frases"], datos["codigos"], embed_dim) | + | |
| - | dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) | + | |
| - | + | ||
| - | optimizer = torch.optim.Adam(modelo.parameters(), lr=learning_rate) | + | |
| - | criterio = nn.BCELoss() | + | |
| - | + | ||
| - | # Entrenamiento | + | |
| - | modelo.train() | + | |
| - | for epoch in range(epochs): | + | |
| - | for tokens, mask, etiquetas in dataloader: | + | |
| - | optimizer.zero_grad() | + | |
| - | salida = modelo(tokens.float()) # Los tokens deben estar en formato flotante | + | |
| - | loss = criterio(salida, etiquetas) | + | |
| - | loss.backward() | + | |
| - | optimizer.step() | + | |
| - | print(f"Listado {nombre}, Epoch {epoch+1}, Loss: {loss.item()}") | + | |
| - | + | ||
| - | modelos[nombre] = modelo | + | |
| - | </code> | + | |
| - | + | ||
| - | **Calcular similitud entre una frase nueva y los listados usando el modelo LSTM**\\ | + | |
| - | <code python> | + | |
| - | from torch.nn.functional import cosine_similarity | + | |
| - | def calcular_similitud(frase, listado, modelo): | + | # 3. Calcular la similitud coseno entre frases de fichero1 y fichero2 |
| - | modelo.eval() | + | cosine_sim = cosine_similarity(tfidf_matrix1, tfidf_matrix2) |
| - | tokens = tokenizer(frase, truncation=True, padding='max_length', max_length=20, return_tensors="pt") | + | |
| - | input_ids = tokens["input_ids"] | + | |
| - | mask = tokens["attention_mask"] | + | |
| - | with torch.no_grad(): | + | |
| - | vector_frase = modelo(input_ids.float()) | + | |
| - | total_similitud = 0 | + | |
| - | for tokens_listado in listado["frases"]: | + | |
| - | input_ids_listado = tokens_listado["input_ids"] | + | |
| - | with torch.no_grad(): | + | |
| - | vector_listado = modelo(input_ids_listado.float()) | + | |
| - | similitud = cosine_similarity(vector_frase, vector_listado).item() | + | |
| - | total_similitud += similitud | + | |
| - | return total_similitud / len(listado["frases"]) | + | |
| - | # Ejemplo de evaluación | + | # 4. Mostrar los resultados |
| - | nuevo_listado = ["la vida es hermosa", "estoy lleno de energía"] | + | print("Similitudes Coseno entre las frases de usuario.txt y geoestratego_.txt:") |
| - | for frase in nuevo_listado: | + | for i in range(len(frases1)): |
| - | for nombre, modelo in modelos.items(): | + | for j in range(len(frases2)): |
| - | similitud = calcular_similitud(frase, listados[nombre], modelo) | + | print(f"Similitud entre frase {i + 1} de usuario y frase {j + 1} de geoestratego_: {cosine_sim[i, j]:.2f}") |
| - | print(f"Similitud de '{frase}' con {nombre}: {similitud:.2f}") | + | |
| </code> | </code> | ||
| - | {{ :ia:desinformadores.gz |}} | ||