Vokturz commited on
Commit
daa5539
·
1 Parent(s): 85a4687

Implement sentiment analysis feature and update pipeline selection

Browse files
src/App.tsx CHANGED
@@ -2,7 +2,7 @@
2
  import { useState } from "react";
3
  import PipelineSelector from "./components/PipelineSelector";
4
  import ZeroShotClassification from "./components/ZeroShotClassification";
5
- import TextClassification from "./components/TextClassification";
6
 
7
  function App() {
8
  const [pipeline, setPipeline] = useState("zero-shot-classification");
@@ -11,7 +11,7 @@ function App() {
11
  <div className="flex flex-col h-screen w-screen p-1">
12
  <PipelineSelector pipeline={pipeline} setPipeline={setPipeline} />
13
  {pipeline === "zero-shot-classification" && <ZeroShotClassification />}
14
- {pipeline === "text-classification" && <TextClassification />}
15
  </div>
16
  );
17
  }
 
2
  import { useState } from "react";
3
  import PipelineSelector from "./components/PipelineSelector";
4
  import ZeroShotClassification from "./components/ZeroShotClassification";
5
+ import SentimentAnalysis from "./components/SentimentAnalysis";
6
 
7
  function App() {
8
  const [pipeline, setPipeline] = useState("zero-shot-classification");
 
11
  <div className="flex flex-col h-screen w-screen p-1">
12
  <PipelineSelector pipeline={pipeline} setPipeline={setPipeline} />
13
  {pipeline === "zero-shot-classification" && <ZeroShotClassification />}
14
+ {pipeline === "sentiment-analysis" && <SentimentAnalysis />}
15
  </div>
16
  );
17
  }
src/components/PipelineSelector.tsx CHANGED
@@ -3,7 +3,7 @@ import React from 'react';
3
 
4
  const pipelines = [
5
  'zero-shot-classification',
6
- 'text-classification',
7
  'image-classification',
8
  'question-answering',
9
  'translation',
 
3
 
4
  const pipelines = [
5
  'zero-shot-classification',
6
+ 'sentiment-analysis',
7
  'image-classification',
8
  'question-answering',
9
  'translation',
src/components/{TextClassification.tsx → SentimentAnalysis.tsx} RENAMED
@@ -1,19 +1,5 @@
1
  import { useState, useRef, useEffect, useCallback } from "react";
2
-
3
- interface ClassificationResult {
4
- sequence: string;
5
- label: string;
6
- score: number;
7
- }
8
-
9
- interface TextClassificationWorkerMessage {
10
- status: "initiate" | "ready" | "output" | "complete";
11
- output?: ClassificationResult;
12
- }
13
-
14
- interface TextClassificationWorkerInput {
15
- text: string;
16
- }
17
 
18
  const PLACEHOLDER_TEXTS: string[] = [
19
  "I absolutely love this product! It exceeded all my expectations.",
@@ -28,9 +14,9 @@ const PLACEHOLDER_TEXTS: string[] = [
28
  "Outstanding! This company really knows how to treat their customers.",
29
  ].sort(() => Math.random() - 0.5);
30
 
31
- function TextClassification() {
32
  const [text, setText] = useState<string>(PLACEHOLDER_TEXTS.join("\n"));
33
- const [results, setResults] = useState<ClassificationResult[]>([]);
34
  const [status, setStatus] = useState<string>("idle");
35
 
36
  // Create a reference to the worker object.
@@ -41,7 +27,7 @@ function TextClassification() {
41
  if (!worker.current) {
42
  // Create the worker if it does not yet exist.
43
  worker.current = new Worker(
44
- new URL("../workers/text-classification.js", import.meta.url),
45
  {
46
  type: "module",
47
  }
@@ -49,7 +35,7 @@ function TextClassification() {
49
  }
50
 
51
  // Create a callback function for messages from the worker thread.
52
- const onMessageReceived = (e: MessageEvent<TextClassificationWorkerMessage>) => {
53
  const status = e.data.status;
54
  if (status === "initiate") {
55
  setStatus("loading");
@@ -74,7 +60,7 @@ function TextClassification() {
74
  const classify = useCallback(() => {
75
  setStatus("processing");
76
  setResults([]); // Clear previous results
77
- const message: TextClassificationWorkerInput = { text };
78
  worker.current?.postMessage(message);
79
  }, [text]);
80
 
@@ -166,14 +152,14 @@ function TextClassification() {
166
  {results.map((result, index) => (
167
  <div
168
  key={index}
169
- className={`p-3 rounded border-2 ${getSentimentColor(result.label)}`}
170
  >
171
  <div className="flex justify-between items-start mb-2">
172
  <span className="font-semibold text-sm">
173
- {formatLabel(result.label)}
174
  </span>
175
  <span className="text-sm font-mono">
176
- {(result.score * 100).toFixed(1)}%
177
  </span>
178
  </div>
179
  <div className="text-sm text-gray-700">
@@ -190,4 +176,4 @@ function TextClassification() {
190
  );
191
  }
192
 
193
- export default TextClassification;
 
1
  import { useState, useRef, useEffect, useCallback } from "react";
2
+ import { ClassificationOutput, SentimentAnalysisWorkerInput, WorkerMessage } from "../types";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  const PLACEHOLDER_TEXTS: string[] = [
5
  "I absolutely love this product! It exceeded all my expectations.",
 
14
  "Outstanding! This company really knows how to treat their customers.",
15
  ].sort(() => Math.random() - 0.5);
16
 
17
+ function SentimentAnalysis() {
18
  const [text, setText] = useState<string>(PLACEHOLDER_TEXTS.join("\n"));
19
+ const [results, setResults] = useState<ClassificationOutput[]>([]);
20
  const [status, setStatus] = useState<string>("idle");
21
 
22
  // Create a reference to the worker object.
 
27
  if (!worker.current) {
28
  // Create the worker if it does not yet exist.
29
  worker.current = new Worker(
30
+ new URL("../workers/sentiment-analysis.js", import.meta.url),
31
  {
32
  type: "module",
33
  }
 
35
  }
36
 
37
  // Create a callback function for messages from the worker thread.
38
+ const onMessageReceived = (e: MessageEvent<WorkerMessage>) => {
39
  const status = e.data.status;
40
  if (status === "initiate") {
41
  setStatus("loading");
 
60
  const classify = useCallback(() => {
61
  setStatus("processing");
62
  setResults([]); // Clear previous results
63
+ const message: SentimentAnalysisWorkerInput = { text };
64
  worker.current?.postMessage(message);
65
  }, [text]);
66
 
 
152
  {results.map((result, index) => (
153
  <div
154
  key={index}
155
+ className={`p-3 rounded border-2 ${getSentimentColor(result.labels[0])}`}
156
  >
157
  <div className="flex justify-between items-start mb-2">
158
  <span className="font-semibold text-sm">
159
+ {formatLabel(result.labels[0])}
160
  </span>
161
  <span className="text-sm font-mono">
162
+ {(result.scores[0] * 100).toFixed(1)}%
163
  </span>
164
  </div>
165
  <div className="text-sm text-gray-700">
 
176
  );
177
  }
178
 
179
+ export default SentimentAnalysis;
src/components/ZeroShotClassification.tsx CHANGED
@@ -1,6 +1,6 @@
1
  // src/App.tsx
2
  import { useState, useRef, useEffect, useCallback } from "react";
3
- import { Section, WorkerMessage, WorkerInput } from "../types";
4
 
5
  const PLACEHOLDER_REVIEWS: string[] = [
6
  // battery/charging problems
@@ -70,7 +70,7 @@ function ZeroShotClassification() {
70
  setStatus("ready");
71
  } else if (status === "output") {
72
  const { sequence, labels, scores } = e.data.output!;
73
-
74
  // Threshold for classification
75
  const label = scores[0] > 0.5 ? labels[0] : "Other";
76
 
@@ -99,7 +99,7 @@ function ZeroShotClassification() {
99
 
100
  const classify = useCallback(() => {
101
  setStatus("processing");
102
- const message: WorkerInput = {
103
  text,
104
  labels: sections
105
  .slice(0, sections.length - 1)
 
1
  // src/App.tsx
2
  import { useState, useRef, useEffect, useCallback } from "react";
3
+ import { Section, WorkerMessage, ZeroShotWorkerInput } from "../types";
4
 
5
  const PLACEHOLDER_REVIEWS: string[] = [
6
  // battery/charging problems
 
70
  setStatus("ready");
71
  } else if (status === "output") {
72
  const { sequence, labels, scores } = e.data.output!;
73
+
74
  // Threshold for classification
75
  const label = scores[0] > 0.5 ? labels[0] : "Other";
76
 
 
99
 
100
  const classify = useCallback(() => {
101
  setStatus("processing");
102
+ const message: ZeroShotWorkerInput = {
103
  text,
104
  labels: sections
105
  .slice(0, sections.length - 1)
src/types.ts CHANGED
@@ -9,14 +9,21 @@ export interface ClassificationOutput {
9
  scores: number[];
10
  }
11
 
 
 
12
  export interface WorkerMessage {
13
  status: 'initiate' | 'ready' | 'output' | 'complete';
14
  output?: any;
15
  }
16
 
17
- export interface WorkerInput {
18
  text: string;
19
  labels: string[];
20
  }
21
 
 
 
 
 
 
22
  export type AppStatus = 'idle' | 'loading' | 'processing';
 
9
  scores: number[];
10
  }
11
 
12
+
13
+
14
  export interface WorkerMessage {
15
  status: 'initiate' | 'ready' | 'output' | 'complete';
16
  output?: any;
17
  }
18
 
19
+ export interface ZeroShotWorkerInput {
20
  text: string;
21
  labels: string[];
22
  }
23
 
24
+
25
+ export interface SentimentAnalysisWorkerInput {
26
+ text: string;
27
+ }
28
+
29
  export type AppStatus = 'idle' | 'loading' | 'processing';
src/workers/{text-classification.js → sentiment-analysis.js} RENAMED
@@ -36,8 +36,8 @@ self.addEventListener("message", async (event) => {
36
  status: "output",
37
  output: {
38
  sequence: line,
39
- label: output[0].label,
40
- score: output[0].score
41
  }
42
  });
43
  }
 
36
  status: "output",
37
  output: {
38
  sequence: line,
39
+ labels: [output[0].label],
40
+ scores: [output[0].score]
41
  }
42
  });
43
  }