La forma más ágil de predecir el impacto de un texto sin entrenar nuestros propios modelos desde cero, es mediante la API de Inferencia gratuita de Hugging Face. Evaluaremos un texto y obtendremos un array de probabilidades para clasificaciones: POSITIVE, NEGATIVE y NEUTRAL.
Serverless Hub Inference
Usaremos un modelo multilingüe como `pysentimiento/robertuito-sentiment-analysis`. Este modelo ya está capado y afinado en tweets/reseñas en Castellano.
// Frontend JS o Endpoint de Worker
async function analyzeSentiment(text) {
// Reemplaza con tu token HF de Hugging Face (Settings -> Access Tokens)
const HUGGING_FACE_TOKEN = "hf_XXXXXXXXXXXXXXXX";
const MODEL_ID = "pysentimiento/robertuito-sentiment-analysis";
const response = await fetch(\`https://api-inference.huggingface.co/models/\${MODEL_ID}\`, {
method: "POST",
headers: {
"Authorization": \`Bearer \${HUGGING_FACE_TOKEN}\`,
"Content-Type": "application/json",
},
body: JSON.stringify({ inputs: text }),
});
// HF puede "dormir" modelos inactivos. Tendremos que manejar errores "Model loading".
const result = await response.json();
return result;
}
Parseando la Matriz JSON
La API devuelve un array aninado de diccionarios, ordenado por probabilidad (del 0 al 1). El objetivo es mapear esto a una estructura entendible para la interfaz gráfica:
// Estructura de Salida devuelta por 'pysentimiento':
// [ [ {label: "NEG", score: 0.98}, {label: "NEU", score: 0.01}, {label: "POS", score: 0.001} ] ]
function parseAndRender(hfResponse) {
if(hfResponse.error) {
return console.warn("Modelo cargando, reintentando...", hfResponse.estimated_time);
}
const predictions = hfResponse[0];
const topSentiment = predictions[0].label; // El que sacó más puntaje
// Asignar Emojis
const emojiMap = {
"POS": "😊 Excelente",
"NEG": "😡 Malo",
"NEU": "😐 Neutral"
};
// Renderizado Dom
const statusDiv = document.getElementById("sentimentResult");
statusDiv.innerHTML = \`\${emojiMap[topSentiment]}\`;
// Actualizar barras progresivas...
updateBars(predictions);
}
Frontend: Barras de Probabilidad Animadas
Utilizaremos HTML5 puro y TailwindCSS en un pequeño widget de análisis que actualiza directamente el ancho visual de los "bars":
<!-- Widget UI -->
<div class="bg-gray-900 border border-gray-700 p-6 rounded-2xl w-full max-w-md shadow-xl">
<textarea class="w-full bg-gray-800 text-white p-3 rounded-xl border border-gray-600 mb-4 h-24" placeholder="Escribe tu opinión sobre el producto..."></textarea>
<button class="w-full bg-rose-600 hover:bg-rose-500 font-bold text-white py-2 rounded-xl mb-6 shadow-rose-500/30 shadow-lg">Analizar Opinión</button>
<!-- Resultados Gráficos -->
<div class="space-y-4">
<!-- POSITIVA -->
<div class="flex items-center text-sm font-bold text-gray-300">
<span class="w-8">POS</span>
<div class="flex-1 bg-gray-800 rounded-full h-3 mx-3 overflow-hidden">
<div id="bar-pos" class="bg-emerald-500 h-3 w-0 transition-all duration-1000"></div>
</div>
<span id="pct-pos" class="w-10 text-right text-emerald-400">0%</span>
</div>
<!-- NEGATIVA -->
<div class="flex items-center text-sm font-bold text-gray-300">
<span class="w-8">NEG</span>
<div class="flex-1 bg-gray-800 rounded-full h-3 mx-3 overflow-hidden">
<div id="bar-neg" class="bg-rose-500 h-3 w-0 transition-all duration-1000"></div>
</div>
<span id="pct-neg" class="w-10 text-right text-rose-400">0%</span>
</div>
</div>
</div>
<script>
// Cuando obtienes las predicciones del HF:
function updateBars(preds) {
preds.forEach(p => {
const factor = (p.score * 100).toFixed(1);
if(p.label === 'POS') {
document.getElementById('bar-pos').style.width = factor + "%";
document.getElementById('pct-pos').innerText = factor + "%";
}
if(p.label === 'NEG') {
document.getElementById('bar-neg').style.width = factor + "%";
document.getElementById('pct-neg').innerText = factor + "%";
}
});
}
</script>
Hugging Face limita mediante IP sus APIs gratuitas. Re-encamina estas llamadas (Proxy Endpoint) para ocultar también el Token de autorización, de modo que el usuario sólo envía "texto" y recibe "números".