NLP-IBM-Debater / src /app /utils /analysis.utils.ts
Yassine Mhirsi
Add analysis charts and utilities
75137c7
raw
history blame
3.6 kB
/**
* Utility functions for analyzing analysis results and calculating statistics
*/
import type { AnalysisResult } from '../types/analysis.types.ts';
/**
* Statistics about stance distribution
*/
export type StanceStats = {
total: number;
pro: number;
con: number;
proPercentage: number;
conPercentage: number;
};
/**
* Topic frequency data
*/
export type TopicFrequency = {
topic: string;
count: number;
proCount: number;
conCount: number;
};
/**
* Time-based statistics
*/
export type TimeStats = {
date: string;
count: number;
};
/**
* Calculate stance distribution statistics
*/
export function calculateStanceStats(results: AnalysisResult[]): StanceStats {
const total = results.length;
const pro = results.filter((r) => r.predicted_stance === 'PRO').length;
const con = results.filter((r) => r.predicted_stance === 'CON').length;
return {
total,
pro,
con,
proPercentage: total > 0 ? (pro / total) * 100 : 0,
conPercentage: total > 0 ? (con / total) * 100 : 0,
};
}
/**
* Calculate topic frequency statistics
*/
export function calculateTopicFrequency(
results: AnalysisResult[],
limit: number = 10
): TopicFrequency[] {
const topicMap = new Map<string, { count: number; proCount: number; conCount: number }>();
results.forEach((result) => {
const topic = result.topic.trim();
if (!topic) return;
const existing = topicMap.get(topic) || { count: 0, proCount: 0, conCount: 0 };
existing.count += 1;
if (result.predicted_stance === 'PRO') {
existing.proCount += 1;
} else {
existing.conCount += 1;
}
topicMap.set(topic, existing);
});
return Array.from(topicMap.entries())
.map(([topic, stats]) => ({
topic,
count: stats.count,
proCount: stats.proCount,
conCount: stats.conCount,
}))
.sort((a, b) => b.count - a.count)
.slice(0, limit);
}
/**
* Calculate time-based statistics (grouped by date)
*/
export function calculateTimeStats(results: AnalysisResult[]): TimeStats[] {
const dateMap = new Map<string, number>();
results.forEach((result) => {
const date = new Date(result.created_at).toISOString().split('T')[0];
dateMap.set(date, (dateMap.get(date) || 0) + 1);
});
return Array.from(dateMap.entries())
.map(([date, count]) => ({ date, count }))
.sort((a, b) => a.date.localeCompare(b.date));
}
/**
* Get unique topics count
*/
export function getUniqueTopicsCount(results: AnalysisResult[]): number {
const uniqueTopics = new Set(results.map((r) => r.topic.trim()).filter((t) => t));
return uniqueTopics.size;
}
/**
* Get average argument length (in characters)
*/
export function getAverageArgumentLength(results: AnalysisResult[]): number {
if (results.length === 0) return 0;
const totalLength = results.reduce((sum, r) => sum + r.argument.length, 0);
return Math.round(totalLength / results.length);
}
/**
* Get most recent analysis date
*/
export function getMostRecentAnalysisDate(results: AnalysisResult[]): string | null {
if (results.length === 0) return null;
const dates = results.map((r) => new Date(r.created_at).getTime());
const mostRecent = new Date(Math.max(...dates));
return mostRecent.toISOString().split('T')[0];
}
/**
* Get oldest analysis date
*/
export function getOldestAnalysisDate(results: AnalysisResult[]): string | null {
if (results.length === 0) return null;
const dates = results.map((r) => new Date(r.created_at).getTime());
const oldest = new Date(Math.min(...dates));
return oldest.toISOString().split('T')[0];
}