File size: 3,597 Bytes
75137c7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
/**
* 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];
}
|