sedzhin commited on
Commit
056a00c
·
verified ·
1 Parent(s): 773d448

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +25 -34
app.js CHANGED
@@ -1,11 +1,11 @@
1
- // app.js (ES module version using transformers.js for local emotion classification)
2
 
3
  import { pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.7.6/dist/transformers.min.js";
4
 
5
  // Global variables
6
  let reviews = [];
7
  let apiToken = ""; // kept for UI compatibility, but not used with local inference
8
- let sentimentPipeline = null; // transformers.js text-classification pipeline (emotion)
9
 
10
  // DOM elements
11
  const analyzeBtn = document.getElementById("analyze-btn");
@@ -32,32 +32,31 @@ document.addEventListener("DOMContentLoaded", function () {
32
  apiToken = savedToken;
33
  }
34
 
35
- // Initialize transformers.js emotion model
36
  initSentimentModel();
37
  });
38
 
39
- // Initialize transformers.js text-classification pipeline with boltuix/bert-emotion
40
  async function initSentimentModel() {
41
  try {
42
- // Inform the user that we are downloading/loading the model
43
  if (statusElement) {
44
- statusElement.textContent = "Loading emotion model...";
45
  }
46
 
47
- // Allocate a pipeline for text-classification with the specified model
48
- // The model will be downloaded and cached in the browser
49
  sentimentPipeline = await pipeline(
50
  "text-classification",
51
- "boltuix/bert-emotion"
52
  );
53
 
54
  if (statusElement) {
55
- statusElement.textContent = "Emotion model ready";
56
  }
57
  } catch (error) {
58
- console.error("Failed to load emotion model:", error);
59
  showError(
60
- "Failed to load emotion model. Please check your network connection and try again."
61
  );
62
  if (statusElement) {
63
  statusElement.textContent = "Model load failed";
@@ -116,7 +115,7 @@ function analyzeRandomReview() {
116
  }
117
 
118
  if (!sentimentPipeline) {
119
- showError("Emotion model is not ready yet. Please wait a moment.");
120
  return;
121
  }
122
 
@@ -132,7 +131,7 @@ function analyzeRandomReview() {
132
  sentimentResult.innerHTML = ""; // Reset previous result
133
  sentimentResult.className = "sentiment-result"; // Reset classes
134
 
135
- // Call local emotion model (transformers.js)
136
  analyzeSentiment(selectedReview)
137
  .then((result) => displaySentiment(result))
138
  .catch((error) => {
@@ -145,33 +144,32 @@ function analyzeRandomReview() {
145
  });
146
  }
147
 
148
- // Call local transformers.js pipeline for emotion classification
149
  async function analyzeSentiment(text) {
150
  if (!sentimentPipeline) {
151
- throw new Error("Emotion model is not initialized.");
152
  }
153
 
154
- // transformers.js text-classification pipeline returns
155
- // an array of objects: [{ label: 'joy', score: 0.92 }, ...]
156
  const output = await sentimentPipeline(text);
157
 
158
- // For compatibility with the existing displaySentiment logic,
159
- // we convert it to the expected format: [[{ label, score }]]
160
  if (!Array.isArray(output) || output.length === 0) {
161
- throw new Error("Invalid emotion output from local model.");
162
  }
163
 
 
164
  return [output];
165
  }
166
 
167
- // Display sentiment (emotion) result
168
  function displaySentiment(result) {
169
- // Default to neutral-like state if we can't parse the result
170
  let sentiment = "neutral";
171
  let score = 0.5;
172
  let label = "NEUTRAL";
173
 
174
- // Parse the (normalized) response format: [[{label: 'JOY', score: 0.99}]]
175
  if (
176
  Array.isArray(result) &&
177
  result.length > 0 &&
@@ -190,17 +188,10 @@ function displaySentiment(result) {
190
  ? sentimentData.score
191
  : 0.5;
192
 
193
- // Map emotion labels to generic sentiment buckets (optional)
194
- // You can customize this mapping based on the model's label set.
195
- if (
196
- ["JOY", "LOVE", "OPTIMISM", "EXCITED", "HAPPY"].includes(label)
197
- ) {
198
  sentiment = "positive";
199
- } else if (
200
- ["ANGER", "SADNESS", "FEAR", "DISGUST", "PESSIMISM"].includes(
201
- label
202
- )
203
- ) {
204
  sentiment = "negative";
205
  } else {
206
  sentiment = "neutral";
 
1
+ // app.js (ES module version using transformers.js for local sentiment classification)
2
 
3
  import { pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.7.6/dist/transformers.min.js";
4
 
5
  // Global variables
6
  let reviews = [];
7
  let apiToken = ""; // kept for UI compatibility, but not used with local inference
8
+ let sentimentPipeline = null; // transformers.js text-classification pipeline
9
 
10
  // DOM elements
11
  const analyzeBtn = document.getElementById("analyze-btn");
 
32
  apiToken = savedToken;
33
  }
34
 
35
+ // Initialize transformers.js sentiment model
36
  initSentimentModel();
37
  });
38
 
39
+ // Initialize transformers.js text-classification pipeline with a supported model
40
  async function initSentimentModel() {
41
  try {
 
42
  if (statusElement) {
43
+ statusElement.textContent = "Loading sentiment model...";
44
  }
45
 
46
+ // Use a transformers.js-supported text-classification model.
47
+ // Xenova/distilbert-base-uncased-finetuned-sst-2-english is a common choice.
48
  sentimentPipeline = await pipeline(
49
  "text-classification",
50
+ "Xenova/distilbert-base-uncased-finetuned-sst-2-english"
51
  );
52
 
53
  if (statusElement) {
54
+ statusElement.textContent = "Sentiment model ready";
55
  }
56
  } catch (error) {
57
+ console.error("Failed to load sentiment model:", error);
58
  showError(
59
+ "Failed to load sentiment model. Please check your network connection and try again."
60
  );
61
  if (statusElement) {
62
  statusElement.textContent = "Model load failed";
 
115
  }
116
 
117
  if (!sentimentPipeline) {
118
+ showError("Sentiment model is not ready yet. Please wait a moment.");
119
  return;
120
  }
121
 
 
131
  sentimentResult.innerHTML = ""; // Reset previous result
132
  sentimentResult.className = "sentiment-result"; // Reset classes
133
 
134
+ // Call local sentiment model (transformers.js)
135
  analyzeSentiment(selectedReview)
136
  .then((result) => displaySentiment(result))
137
  .catch((error) => {
 
144
  });
145
  }
146
 
147
+ // Call local transformers.js pipeline for sentiment classification
148
  async function analyzeSentiment(text) {
149
  if (!sentimentPipeline) {
150
+ throw new Error("Sentiment model is not initialized.");
151
  }
152
 
153
+ // transformers.js text-classification pipeline returns:
154
+ // [{ label: 'POSITIVE', score: 0.99 }, ...]
155
  const output = await sentimentPipeline(text);
156
 
 
 
157
  if (!Array.isArray(output) || output.length === 0) {
158
+ throw new Error("Invalid sentiment output from local model.");
159
  }
160
 
161
+ // Wrap to match [[{ label, score }]] shape expected by displaySentiment
162
  return [output];
163
  }
164
 
165
+ // Display sentiment result
166
  function displaySentiment(result) {
167
+ // Default to neutral if we can't parse the result
168
  let sentiment = "neutral";
169
  let score = 0.5;
170
  let label = "NEUTRAL";
171
 
172
+ // Expected format: [[{label: 'POSITIVE', score: 0.99}]]
173
  if (
174
  Array.isArray(result) &&
175
  result.length > 0 &&
 
188
  ? sentimentData.score
189
  : 0.5;
190
 
191
+ // Determine sentiment bucket
192
+ if (label === "POSITIVE" && score > 0.5) {
 
 
 
193
  sentiment = "positive";
194
+ } else if (label === "NEGATIVE" && score > 0.5) {
 
 
 
 
195
  sentiment = "negative";
196
  } else {
197
  sentiment = "neutral";