Cómo integrar Azure Text Analytics en una aplicación de análisis de feedback

Rmag Breaking News

En la era digital, comprender las percepciones y emociones de los usuarios es esencial para mejorar productos y servicios. Microsoft Azure Text Analytics ofrece una solución robusta para analizar el sentimiento y las frases clave de los textos. En este post, te guiaré a través de una prueba de concepto para integrar Azure Text Analytics en una aplicación de análisis de feedback.

Paso 1: Configurar el entorno de desarrollo

Antes de comenzar, asegúrate de tener las siguientes herramientas y servicios configurados:

Node.js y npm instalados en tu máquina local.
Una cuenta de Azure con acceso al servicio Text Analytics.
Un entorno de base de datos PostgreSQL.

Paso 2: Preparar el frontend

Nuestra aplicación de feedback se construirá usando React. Crearemos un componente para enviar feedback y visualizar el análisis de sentimientos.

Crea un nuevo proyecto React : Utiliza create-react-app para configurar tu entorno de frontend.

Integra el componente AnalyzeFeedback : Este componente es responsable de enviar el título del feedback y mostrar los resultados del análisis.

‘use client’

import { useEffect, useState } from ‘react’;
import styles from ‘./AnalyzeFeedback.module.scss’;
import ClassName from ‘@/types/ClassName’;

interface AnalyzeFeedbackProps extends ClassName {
title: string;
}

const AnalyzeFeedback = ({ className, title }: AnalyzeFeedbackProps) => {
const [score, setScore] = useState<number | null>(null);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
setIsLoading(true);
fetch(‘https://api.danieljsaldana.dev/api/getfeedbackscores’, {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify({ title }),
})
.then(response => response.json())
.then(data => {
if (data.compositeScore !== undefined) {
setScore(data.compositeScore);
} else {
setScore(null);
}
})
.catch(() => setScore(null))
.finally(() => setIsLoading(false));
}, [title]);

const getBackgroundColor = (score: number | null) => {
if (score === null) {
return ‘#d3d3d3’;
} else if (score > 80) {
return ‘#0ac769’;
} else if (score >= 50 && score <= 79) {
return ‘#ffad00’;
} else {
return ‘#ea001e’;
}
};

const backgroundColor = getBackgroundColor(score);
const circumference = 301.59289474462014;
const offset = score !== null ? ((100 – score) / 100) * circumference : 0;

return (
<div className={`rounded-full h-[24px] w-[22px] ${className ?? ”}`}>
<svg width=”24″ height=”24″ viewBox=”0 0 128 128″ xmlns=”http://www.w3.org/2000/svg”>
<g shapeRendering=”geometricPrecision”>
<circle cx=”64″ cy=”64″ fill={backgroundColor} r=”64″ />
<circle cx=”64″ cy=”64″ fill=”none” r=”48″ stroke=”rgba(0,0,0,.1)” strokeWidth=”10″ />
{!isLoading && score !== null && (
<circle
cx=”64″
cy=”64″
fill=”none”
r=”48″
stroke=”white”
strokeDasharray={`${circumference} ${circumference}`}
strokeDashoffset={offset}
strokeLinecap=”round”
strokeLinejoin=”round”
strokeWidth=”10″
className=”score_progress__quTNG”
/>
)}
{(isLoading || score === null) && (
<svg className={`${styles.withIconIcon__MHUeb} ${styles.fadeIn}`} data-testid=”geist-icon” fill=”none” height=”70″ shapeRendering=”geometricPrecision” stroke=”#999″ strokeLinecap=”round” strokeLinejoin=”round” strokeWidth=”2″ viewBox=”0 0 24 24″ width=”70″ x=”29″ y=”29″>
<path d=”M22 12h-4l-3 9L9 3l-3 9H2″></path>
</svg>
)}
{!isLoading && score !== null && (
<text
fill=”white”
fontSize=”42″
fontWeight=”500″
textAnchor=”middle”
x=”64″
y=”79″
>
{score}
</text>
)}
</g>
</svg>
</div>
);
};

export default AnalyzeFeedback;

Estiliza tu componente : Usa los estilos predefinidos para hacer que tu componente sea visualmente atractivo y claro para los usuarios.

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

.fadeIn {
animation: fadeIn ease-in 1s;
animation-fill-mode: forwards;
}

Paso 3: Configurar el backend

El backend de nuestra aplicación se construirá con Node.js y se comunicará con los servicios de Azure para analizar el feedback.

Establece la API de análisis de feedback : Crea una API que reciba el feedback, analice el sentimiento y las frases clave usando Azure Text Analytics, e inserte los resultados en la base de datos.

import { TextAnalyticsClient, AzureKeyCredential } from ‘@azure/ai-text-analytics’;
import { enableCors } from “@/src/middleware/enableCors”;
import { methodValidator } from “@/src/utils/methodValidator”;
import { insertFeedback } from “@/src/core/insertFeedback”;
import dotenv from ‘dotenv’;

dotenv.config();

const textAnalyticsClient = new TextAnalyticsClient(
process.env.AZURE_TEXT_ANALYTICS_ENDPOINT,
new AzureKeyCredential(process.env.AZURE_TEXT_ANALYTICS_KEY)
);

async function analyzeFeedback(req, res) {
try {
await methodValidator(req, res, ‘POST’);
if (res.headersSent) return;

const { title, text, user } = req.body;
if (!title || !text || !user) {
return res.status(400).json({ error: ‘Faltan datos requeridos para el análisis’ });
}

const sentimentResult = await textAnalyticsClient.analyzeSentiment([text]);
const sentiment = sentimentResult[0];

const keyPhrasesResult = await textAnalyticsClient.extractKeyPhrases([text]);
const keyPhrases = keyPhrasesResult[0];

await insertFeedback(
title,
sentiment.sentiment,
sentiment.confidenceScores.positive,
sentiment.confidenceScores.neutral,
sentiment.confidenceScores.negative,
user
);

res.status(200).json({
title,
user,
sentiment: sentiment.sentiment,
confidenceScores: sentiment.confidenceScores,
keyPhrases: keyPhrases.keyPhrases,
});
} catch (error) {
console.error(‘Error al analizar el feedback:’, error);
res.status(500).json({ error: `Error al analizar el feedback: ${error.message}` });
}
}

export default enableCors(analyzeFeedback);

Desarrolla la API para obtener puntajes de feedback : Esta API recupera los promedios de los puntajes de feedback basados en el título proporcionado.

import { enableCors } from “@/src/middleware/enableCors”;
import { methodValidator } from “@/src/utils/methodValidator”;
import { sanitizeTitleForFilename } from “@/src/utils/sanitizeTitleForFilename”;
import { getAverageFeedbackScores } from “@/src/core/getAverageFeedbackScores”;
import dotenv from ‘dotenv’;

dotenv.config();

export async function getFeedbackScores(req, res) {
await methodValidator(req, res, ‘POST’);
if (res.headersSent) return;

const { title } = req.body;
if (!title) {
return res.status(400).json({ error: ‘Falta el título para el análisis’ });
}

const sanitizedTitle = sanitizeTitleForFilename(title);
console.log(‘Título sanitizado:’, sanitizedTitle);

try {
const averages = await getAverageFeedbackScores(sanitizedTitle);

if (!averages || averages.average_positive === 0 && averages.average_neutral === 0 && averages.average_negative === 0) {
return res.status(200).json({ error: ‘No se encontraron datos para el título proporcionado’, compositeScore: null });
}

const avgPositive = parseFloat(averages.average_positive);
const avgNeutral = parseFloat(averages.average_neutral);
const avgNegative = parseFloat(averages.average_negative);

console.log(‘Promedios convertidos:’, avgPositive, avgNeutral, avgNegative);

let compositeScore = (avgPositive + 0.5 * avgNeutral – avgNegative);
compositeScore = Math.max(0, Math.min(1, compositeScore)) * 100;

compositeScore = Math.round(compositeScore);

console.log(‘Puntuación compuesta:’, compositeScore);
res.status(200).json({ compositeScore: compositeScore });
} catch (error) {
console.error(‘Error al obtener los promedios del feedback:’, error);
res.status(500).json({ error: `Error al obtener los promedios del feedback: ${error.message}` });
}
}

export default enableCors(getFeedbackScores);

Implementa funciones de base de datos : Usa estas funciones para interactuar con tu base de datos PostgreSQL y manejar la inserción y recuperación de datos de feedback.

import { sql } from ‘@vercel/postgres’;

export async function getAverageFeedbackScores(title) {
try {
const result = await sql`
SELECT
AVG(positive) AS average_positive,
AVG(neutral) AS average_neutral,
AVG(negative) AS average_negative
FROM post_feedback
WHERE title = ${title}
GROUP BY title;
`;

if (result.rows && result.rows.length > 0) {
return result.rows[0];
} else {
return { average_positive: 0, average_neutral: 0, average_negative: 0 };
}
} catch (error) {
console.error(`Error al obtener los promedios de feedback para el título: ${title}`, error);
throw error;
}
}

y

import { sql } from ‘@vercel/postgres’;

export async function insertFeedback(title, sentiment, positive, neutral, negative, user) {
console.log(`Insertando feedback para el título: ${title}`);

try {
await sql`
INSERT INTO post_feedback
(title, sentiment, positive, neutral, negative, “user”, last_updated)
VALUES
(${title}, ${sentiment}, ${positive}, ${neutral}, ${negative}, ${user}, CURRENT_TIMESTAMP)
ON CONFLICT (title, “user”) — Actualiza esto para que coincida con la nueva restricción única
DO UPDATE SET
sentiment = EXCLUDED.sentiment,
positive = EXCLUDED.positive,
neutral = EXCLUDED.neutral,
negative = EXCLUDED.negative,
last_updated = CURRENT_TIMESTAMP;
`;
console.log(`Feedback insertado con éxito para el título: ${title}`);
} catch (error) {
console.error(`Error al insertar feedback para el título: ${title}`, error);
throw new Error(`Error al insertar feedback: ${error.message}`);
}
}

Paso 4: Configuración de la base de datos

Antes de que puedas comenzar a almacenar y recuperar datos de feedback, necesitas configurar tu base de datos PostgreSQL. Usa la siguiente query SQL para crear la tabla necesaria para almacenar los datos de feedback:

CREATE TABLE post_feedback (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
sentiment VARCHAR(50) NOT NULL,
positive NUMERIC NOT NULL,
neutral NUMERIC NOT NULL,
negative NUMERIC NOT NULL,
“user” VARCHAR(255) NOT NULL,
last_updated TIMESTAMP NOT NULL,
UNIQUE(title, “user”)
);

Esta tabla almacenará cada pieza de feedback junto con el análisis de sentimientos y la marca de tiempo de la última actualización. Asegúrate de que tu base de datos esté en funcionamiento y accesible desde tu backend antes de continuar.

Paso 5: Prueba de concepto

Para probar la integración completa de tu sistema, utiliza Postman para simular solicitudes de cliente a tu backend. A continuación, te proporciono una guía para configurar las solicitudes en Postman:

Configuración en Postman:

POST para analizar feedback :

POST para obtener puntajes de feedback :

Asegúrate de tener tu servidor backend en ejecución antes de enviar las solicitudes desde Postman. Estas solicitudes simularán la interacción entre el frontend y el backend, permitiéndote evaluar la funcionalidad completa de tu aplicación de análisis de feedback.

Después de configurar y ejecutar estas pruebas, deberías poder ver cómo tu aplicación procesa y responde al feedback, cómo se almacena en la base de datos y cómo se recuperan y calculan los promedios de los puntajes de sentimiento. Esto completará tu prueba de concepto, demostrando la funcionalidad y la integración entre todas las partes de tu aplicación.

Y con esto, has completado la integración de Azure Text Analytics en tu aplicación de análisis de feedback. ¡Felicidades por llegar hasta aquí! Si tienes alguna pregunta o comentario, no dudes en dejarlo a continuación.

Leave a Reply

Your email address will not be published. Required fields are marked *