Update app.py
Browse files
app.py
CHANGED
|
@@ -4,57 +4,214 @@ import json
|
|
| 4 |
from datetime import datetime, timedelta
|
| 5 |
import re
|
| 6 |
import xml.etree.ElementTree as ET
|
| 7 |
-
|
| 8 |
-
import
|
| 9 |
-
import
|
|
|
|
| 10 |
|
| 11 |
-
class
|
| 12 |
def __init__(self):
|
| 13 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
self.data_sources = {
|
| 15 |
"reuters_rss": "https://feeds.reuters.com/reuters/worldNews",
|
| 16 |
"bbc_rss": "https://feeds.bbci.co.uk/news/world/rss.xml",
|
| 17 |
-
"un_news": "https://news.un.org/en/rss/rss.xml"
|
| 18 |
-
"crisis_tracker": "https://api.gdeltproject.org/api/v2/summary/summary?d=web&t=summary&ts=full",
|
| 19 |
-
"world_bank_data": "https://api.worldbank.org/v2/country/all/indicator/NY.GDP.MKTP.CD?format=json&date=2024",
|
| 20 |
-
"open_sanctions": "https://data.opensanctions.org/datasets/latest/default/targets.simple.csv",
|
| 21 |
-
"conflict_data": "https://ucdp.uu.se/downloads/ged/ged231-csv.zip"
|
| 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 |
-
- Alleanze coinvolte: {alliances}
|
| 49 |
-
- Tensioni: {tensions}
|
| 50 |
-
- Interessi: {interests}
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
}
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
news_data = []
|
| 59 |
|
| 60 |
try:
|
|
@@ -62,17 +219,16 @@ class RealTimeGeopoliticalAnalyzer:
|
|
| 62 |
response = requests.get(self.data_sources["reuters_rss"], timeout=10)
|
| 63 |
if response.status_code == 200:
|
| 64 |
root = ET.fromstring(response.content)
|
| 65 |
-
for item in root.findall(".//item")[:
|
| 66 |
title = item.find("title")
|
| 67 |
-
pub_date = item.find("pubDate")
|
| 68 |
description = item.find("description")
|
| 69 |
|
| 70 |
if title is not None:
|
| 71 |
news_data.append({
|
| 72 |
"source": "Reuters",
|
| 73 |
"title": title.text,
|
| 74 |
-
"
|
| 75 |
-
"
|
| 76 |
})
|
| 77 |
except:
|
| 78 |
pass
|
|
@@ -82,86 +238,42 @@ class RealTimeGeopoliticalAnalyzer:
|
|
| 82 |
response = requests.get(self.data_sources["bbc_rss"], timeout=10)
|
| 83 |
if response.status_code == 200:
|
| 84 |
root = ET.fromstring(response.content)
|
| 85 |
-
for item in root.findall(".//item")[:
|
| 86 |
title = item.find("title")
|
| 87 |
-
pub_date = item.find("pubDate")
|
| 88 |
description = item.find("description")
|
| 89 |
|
| 90 |
if title is not None:
|
| 91 |
news_data.append({
|
| 92 |
"source": "BBC",
|
| 93 |
"title": title.text,
|
| 94 |
-
"
|
| 95 |
-
"
|
| 96 |
})
|
| 97 |
except:
|
| 98 |
pass
|
| 99 |
|
| 100 |
-
return news_data
|
| 101 |
-
|
| 102 |
-
def fetch_economic_indicators(self):
|
| 103 |
-
"""Recupera indicatori economici real-time"""
|
| 104 |
-
try:
|
| 105 |
-
# World Bank API (pubblico, no key)
|
| 106 |
-
response = requests.get(self.data_sources["world_bank_data"], timeout=15)
|
| 107 |
-
if response.status_code == 200:
|
| 108 |
-
data = response.json()
|
| 109 |
-
if len(data) > 1 and isinstance(data[1], list):
|
| 110 |
-
return data[1][:20] # Top 20 economie
|
| 111 |
-
except:
|
| 112 |
-
pass
|
| 113 |
-
return []
|
| 114 |
|
| 115 |
-
def
|
| 116 |
-
"""
|
| 117 |
-
entities =
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
}
|
| 123 |
|
| 124 |
-
# Pattern per paesi (più sofisticato)
|
| 125 |
-
country_patterns = [
|
| 126 |
-
r'\b(United States|USA|America|US)\b',
|
| 127 |
-
r'\b(China|Chinese|Beijing)\b',
|
| 128 |
-
r'\b(Russia|Russian|Moscow|Kremlin)\b',
|
| 129 |
-
r'\b(Ukraine|Ukrainian|Kyiv|Kiev)\b',
|
| 130 |
-
r'\b(Israel|Israeli|Jerusalem|Tel Aviv)\b',
|
| 131 |
-
r'\b(Iran|Iranian|Tehran)\b',
|
| 132 |
-
r'\b(Germany|German|Berlin)\b',
|
| 133 |
-
r'\b(France|French|Paris)\b',
|
| 134 |
-
r'\b(Italy|Italian|Rome)\b',
|
| 135 |
-
r'\b(Japan|Japanese|Tokyo)\b',
|
| 136 |
-
r'\b(India|Indian|New Delhi)\b',
|
| 137 |
-
r'\b(Turkey|Turkish|Ankara)\b',
|
| 138 |
-
r'\b(Saudi Arabia|Saudi|Riyadh)\b',
|
| 139 |
-
r'\b(North Korea|DPRK|Pyongyang)\b',
|
| 140 |
-
r'\b(South Korea|Seoul)\b',
|
| 141 |
-
r'\b(Taiwan|Taipei)\b',
|
| 142 |
-
r'\b(Pakistan|Islamabad)\b'
|
| 143 |
-
]
|
| 144 |
-
|
| 145 |
-
# Pattern per organizzazioni
|
| 146 |
-
org_patterns = [
|
| 147 |
-
r'\b(NATO|North Atlantic)\b',
|
| 148 |
-
r'\b(European Union|EU)\b',
|
| 149 |
-
r'\b(United Nations|UN)\b',
|
| 150 |
-
r'\b(BRICS)\b',
|
| 151 |
-
r'\b(G7|G20)\b',
|
| 152 |
-
r'\b(ASEAN)\b',
|
| 153 |
-
r'\b(OPEC)\b',
|
| 154 |
-
r'\b(IMF|World Bank)\b'
|
| 155 |
-
]
|
| 156 |
-
|
| 157 |
-
# Keywords geopolitiche
|
| 158 |
-
conflict_keywords = [
|
| 159 |
-
r'\b(war|conflict|tension|crisis|sanctions|embargo|blockade)\b',
|
| 160 |
-
r'\b(military|defense|security|nuclear|missile|drone)\b',
|
| 161 |
-
r'\b(trade war|tariffs|economic pressure|diplomatic crisis)\b',
|
| 162 |
-
r'\b(alliance|partnership|treaty|agreement|summit)\b'
|
| 163 |
-
]
|
| 164 |
-
|
| 165 |
combined_text = ""
|
| 166 |
if isinstance(text_data, list):
|
| 167 |
for item in text_data:
|
|
@@ -172,394 +284,281 @@ class RealTimeGeopoliticalAnalyzer:
|
|
| 172 |
else:
|
| 173 |
combined_text = str(text_data)
|
| 174 |
|
| 175 |
-
# Estrai entità
|
| 176 |
-
for pattern in
|
| 177 |
matches = re.findall(pattern, combined_text, re.IGNORECASE)
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
def ai_generative_analysis(self, query, real_time_data, entities):
|
| 191 |
-
"""AI Generativa per analisi complessa"""
|
| 192 |
-
|
| 193 |
-
# Determina il tipo di analisi necessaria
|
| 194 |
-
query_lower = query.lower()
|
| 195 |
-
analysis_type = "general"
|
| 196 |
-
|
| 197 |
-
if any(word in query_lower for word in ["conflict", "war", "tension", "crisis"]):
|
| 198 |
-
analysis_type = "conflict_analysis"
|
| 199 |
-
elif any(word in query_lower for word in ["economic", "trade", "sanctions", "market"]):
|
| 200 |
-
analysis_type = "economic_impact"
|
| 201 |
-
elif any(word in query_lower for word in ["alliance", "nato", "partnership", "bloc"]):
|
| 202 |
-
analysis_type = "alliance_dynamics"
|
| 203 |
-
|
| 204 |
-
# Template AI per analisi generativa
|
| 205 |
-
ai_analysis = {
|
| 206 |
-
"situation_assessment": self.assess_current_situation(real_time_data, entities),
|
| 207 |
-
"power_dynamics": self.analyze_power_dynamics(entities),
|
| 208 |
-
"trend_analysis": self.identify_trends(real_time_data),
|
| 209 |
-
"risk_assessment": self.calculate_risks(entities, real_time_data),
|
| 210 |
-
"scenario_generation": self.generate_scenarios(query, entities),
|
| 211 |
-
"strategic_implications": self.derive_strategic_implications(entities, real_time_data)
|
| 212 |
-
}
|
| 213 |
-
|
| 214 |
-
return ai_analysis
|
| 215 |
-
|
| 216 |
-
def assess_current_situation(self, data, entities):
|
| 217 |
-
"""Valuta la situazione attuale basata su dati real-time"""
|
| 218 |
-
assessment = []
|
| 219 |
-
|
| 220 |
-
# Intensità delle tensioni basata su keywords
|
| 221 |
-
tension_indicators = ["war", "conflict", "crisis", "sanctions", "military"]
|
| 222 |
-
tension_count = sum(1 for keyword in entities.get("keywords", [])
|
| 223 |
-
if keyword.lower() in tension_indicators)
|
| 224 |
-
|
| 225 |
-
if tension_count >= 3:
|
| 226 |
-
assessment.append("🔴 ALTA TENSIONE - Situazione critica rilevata")
|
| 227 |
-
elif tension_count >= 1:
|
| 228 |
-
assessment.append("🟡 TENSIONE MODERATA - Monitoraggio necessario")
|
| 229 |
-
else:
|
| 230 |
-
assessment.append("🟢 STABILITÀ RELATIVA - Situazione sotto controllo")
|
| 231 |
-
|
| 232 |
-
# Coinvolgimento grandi potenze
|
| 233 |
-
major_powers = ["United States", "USA", "China", "Russia", "European Union", "EU"]
|
| 234 |
-
involved_powers = [p for p in major_powers if p in entities.get("countries", [])]
|
| 235 |
-
|
| 236 |
-
if len(involved_powers) >= 2:
|
| 237 |
-
assessment.append(f"⚡ Coinvolte superpotenze: {', '.join(involved_powers)}")
|
| 238 |
-
|
| 239 |
-
return assessment
|
| 240 |
-
|
| 241 |
-
def analyze_power_dynamics(self, entities):
|
| 242 |
-
"""Analizza le dinamiche di potere"""
|
| 243 |
-
dynamics = []
|
| 244 |
-
|
| 245 |
-
countries = list(entities.get("countries", []))
|
| 246 |
-
orgs = list(entities.get("organizations", []))
|
| 247 |
-
|
| 248 |
-
# Analisi blocchi
|
| 249 |
-
if "NATO" in orgs and any(country in ["Russia", "China"] for country in countries):
|
| 250 |
-
dynamics.append("🔄 CONFRONTO EST-OVEST - Dinamiche da Guerra Fredda")
|
| 251 |
-
|
| 252 |
-
if "China" in countries and "Taiwan" in countries:
|
| 253 |
-
dynamics.append("⚔️ TENSIONE TAIWAN - Flashpoint critico Asia-Pacifico")
|
| 254 |
-
|
| 255 |
-
if "Ukraine" in countries and "Russia" in countries:
|
| 256 |
-
dynamics.append("🚨 CONFLITTO ATTIVO - Europa orientale instabile")
|
| 257 |
-
|
| 258 |
-
return dynamics
|
| 259 |
-
|
| 260 |
-
def identify_trends(self, data):
|
| 261 |
-
"""Identifica trend dai dati real-time"""
|
| 262 |
-
trends = []
|
| 263 |
-
|
| 264 |
-
if not data:
|
| 265 |
-
return ["📊 Dati insufficienti per trend analysis"]
|
| 266 |
-
|
| 267 |
-
# Analisi frequenza keywords nelle notizie
|
| 268 |
-
all_text = ""
|
| 269 |
-
for item in data:
|
| 270 |
-
if isinstance(item, dict):
|
| 271 |
-
all_text += f" {item.get('title', '')} {item.get('description', '')}"
|
| 272 |
-
|
| 273 |
-
trend_keywords = {
|
| 274 |
-
"militarizzazione": ["military", "defense", "weapon", "missile", "nuclear"],
|
| 275 |
-
"sanzioni_economiche": ["sanction", "embargo", "tariff", "economic pressure"],
|
| 276 |
-
"diplomazia": ["summit", "negotiation", "agreement", "treaty", "dialogue"],
|
| 277 |
-
"instabilità": ["crisis", "tension", "conflict", "unstable", "volatile"]
|
| 278 |
-
}
|
| 279 |
-
|
| 280 |
-
for trend, keywords in trend_keywords.items():
|
| 281 |
-
count = sum(all_text.lower().count(keyword) for keyword in keywords)
|
| 282 |
-
if count >= 2:
|
| 283 |
-
trends.append(f"📈 TREND: {trend.upper()} ({count} menzioni)")
|
| 284 |
-
|
| 285 |
-
return trends if trends else ["📊 Pattern stabili - Nessun trend anomalo"]
|
| 286 |
-
|
| 287 |
-
def calculate_risks(self, entities, data):
|
| 288 |
-
"""Calcola livelli di rischio"""
|
| 289 |
-
risks = []
|
| 290 |
-
risk_score = 0
|
| 291 |
-
|
| 292 |
-
# Fattori di rischio
|
| 293 |
-
high_risk_combinations = [
|
| 294 |
-
(["Russia", "Ukraine"], "Escalation conflitto"),
|
| 295 |
-
(["China", "Taiwan"], "Crisi Taiwan Strait"),
|
| 296 |
-
(["Iran", "Israel"], "Conflitto Medio Oriente"),
|
| 297 |
-
(["North Korea", "South Korea"], "Tensione coreana")
|
| 298 |
-
]
|
| 299 |
-
|
| 300 |
-
countries = list(entities.get("countries", []))
|
| 301 |
-
|
| 302 |
-
for combo, risk_desc in high_risk_combinations:
|
| 303 |
-
if all(country in countries for country in combo):
|
| 304 |
-
risks.append(f"🚨 ALTO RISCHIO: {risk_desc}")
|
| 305 |
-
risk_score += 3
|
| 306 |
-
|
| 307 |
-
# Rischio sanzioni
|
| 308 |
-
if "sanctions" in entities.get("keywords", []):
|
| 309 |
-
risks.append("💰 RISCHIO ECONOMICO: Impatti sanzionatori")
|
| 310 |
-
risk_score += 2
|
| 311 |
-
|
| 312 |
-
# Rischio militare
|
| 313 |
-
if any(keyword in entities.get("keywords", []) for keyword in ["military", "nuclear", "missile"]):
|
| 314 |
-
risks.append("⚔️ RISCHIO MILITARE: Escalation possibile")
|
| 315 |
-
risk_score += 2
|
| 316 |
-
|
| 317 |
-
# Calcola livello generale
|
| 318 |
-
if risk_score >= 5:
|
| 319 |
-
risks.insert(0, "🔴 LIVELLO RISCHIO: CRITICO")
|
| 320 |
-
elif risk_score >= 3:
|
| 321 |
-
risks.insert(0, "🟡 LIVELLO RISCHIO: ELEVATO")
|
| 322 |
-
else:
|
| 323 |
-
risks.insert(0, "🟢 LIVELLO RISCHIO: MODERATO")
|
| 324 |
-
|
| 325 |
-
return risks
|
| 326 |
-
|
| 327 |
-
def generate_scenarios(self, query, entities):
|
| 328 |
-
"""Genera scenari futuri basati su AI"""
|
| 329 |
-
scenarios = []
|
| 330 |
-
|
| 331 |
-
countries = list(entities.get("countries", []))
|
| 332 |
-
keywords = list(entities.get("keywords", []))
|
| 333 |
-
|
| 334 |
-
# Scenari basati su pattern
|
| 335 |
-
if "Russia" in countries and "Ukraine" in countries:
|
| 336 |
-
scenarios.extend([
|
| 337 |
-
"📊 SCENARIO A: Escalation → Coinvolgimento NATO diretto",
|
| 338 |
-
"📊 SCENARIO B: Stallo → Guerra di logoramento prolungata",
|
| 339 |
-
"📊 SCENARIO C: Negoziato → Cessate il fuoco territoriale"
|
| 340 |
-
])
|
| 341 |
-
|
| 342 |
-
elif "China" in countries and "Taiwan" in countries:
|
| 343 |
-
scenarios.extend([
|
| 344 |
-
"📊 SCENARIO A: Blockade → Crisi economica globale",
|
| 345 |
-
"📊 SCENARIO B: Status quo → Tensione controllata",
|
| 346 |
-
"📊 SCENARIO C: Riunificazione → Shock geopolitico"
|
| 347 |
-
])
|
| 348 |
-
|
| 349 |
-
else:
|
| 350 |
-
# Scenari generici
|
| 351 |
-
scenarios.extend([
|
| 352 |
-
"📊 SCENARIO A: Stabilizzazione → Ritorno alla normalità",
|
| 353 |
-
"📊 SCENARIO B: Escalation → Aumento delle tensioni",
|
| 354 |
-
"📊 SCENARIO C: Frammentazione → Nuovi equilibri regionali"
|
| 355 |
-
])
|
| 356 |
-
|
| 357 |
-
return scenarios
|
| 358 |
-
|
| 359 |
-
def derive_strategic_implications(self, entities, data):
|
| 360 |
-
"""Deriva implicazioni strategiche"""
|
| 361 |
-
implications = []
|
| 362 |
-
|
| 363 |
-
countries = list(entities.get("countries", []))
|
| 364 |
-
orgs = list(entities.get("organizations", []))
|
| 365 |
-
|
| 366 |
-
# Implicazioni per alleanze
|
| 367 |
-
if "NATO" in orgs:
|
| 368 |
-
implications.append("🛡️ NATO: Rafforzamento deterrenza e coesione alleanza")
|
| 369 |
-
|
| 370 |
-
if "EU" in orgs or "European Union" in orgs:
|
| 371 |
-
implications.append("🇪🇺 UE: Necessità autonomia strategica e difesa comune")
|
| 372 |
-
|
| 373 |
-
# Implicazioni economiche
|
| 374 |
-
if any(country in ["China", "USA", "Germany"] for country in countries):
|
| 375 |
-
implications.append("💼 COMMERCIO: Riconfigurazione catene globali del valore")
|
| 376 |
-
|
| 377 |
-
# Implicazioni tecnologiche
|
| 378 |
-
if "China" in countries and "USA" in countries:
|
| 379 |
-
implications.append("🔬 TECH: Accelerazione decoupling tecnologico")
|
| 380 |
-
|
| 381 |
-
# Implicazioni energetiche
|
| 382 |
-
if "Russia" in countries:
|
| 383 |
-
implications.append("⚡ ENERGIA: Diversificazione fonti e fornitori")
|
| 384 |
-
|
| 385 |
-
return implications
|
| 386 |
|
| 387 |
-
def
|
| 388 |
-
"""
|
| 389 |
|
| 390 |
try:
|
| 391 |
-
# 1.
|
| 392 |
-
|
| 393 |
-
|
|
|
|
|
|
|
|
|
|
| 394 |
|
| 395 |
-
#
|
| 396 |
-
|
| 397 |
-
entities = self.extract_geopolitical_entities(combined_data)
|
| 398 |
|
| 399 |
-
#
|
| 400 |
-
|
| 401 |
|
| 402 |
-
#
|
| 403 |
-
report = self.
|
| 404 |
|
| 405 |
return report
|
| 406 |
|
| 407 |
except Exception as e:
|
| 408 |
-
return f"❌ Errore nell'analisi
|
| 409 |
|
| 410 |
-
def
|
| 411 |
-
"""Genera report
|
| 412 |
|
| 413 |
report_parts = []
|
| 414 |
|
| 415 |
-
# Header
|
| 416 |
-
report_parts.append("
|
| 417 |
-
report_parts.append("
|
| 418 |
-
report_parts.append(f"
|
| 419 |
-
report_parts.append("
|
| 420 |
report_parts.append("")
|
| 421 |
|
| 422 |
-
# Query Analysis
|
| 423 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 424 |
report_parts.append("")
|
| 425 |
|
| 426 |
-
#
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
if entities['countries']:
|
| 436 |
-
report_parts.append(f" 🏛️ Countries: {', '.join(list(entities['countries'])[:8])}")
|
| 437 |
-
if entities['organizations']:
|
| 438 |
-
report_parts.append(f" 🏢 Organizations: {', '.join(list(entities['organizations'])[:6])}")
|
| 439 |
-
if entities['keywords']:
|
| 440 |
-
report_parts.append(f" 🔑 Keywords: {', '.join(list(entities['keywords'])[:8])}")
|
| 441 |
report_parts.append("")
|
| 442 |
|
| 443 |
-
#
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
|
|
|
|
|
|
|
|
|
| 447 |
report_parts.append("")
|
| 448 |
|
| 449 |
-
#
|
| 450 |
-
if
|
| 451 |
-
report_parts.append("
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
report_parts.append("")
|
| 461 |
|
| 462 |
-
#
|
| 463 |
-
report_parts.append("
|
| 464 |
-
for
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
report_parts.append("")
|
| 467 |
|
| 468 |
-
#
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
report_parts.append("")
|
| 473 |
|
| 474 |
-
#
|
| 475 |
-
report_parts.append("
|
| 476 |
-
|
| 477 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 478 |
report_parts.append("")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
|
| 480 |
-
#
|
| 481 |
-
report_parts.append("📊 DATA PIPELINE:")
|
| 482 |
-
report_parts.append(" • Real-time RSS feeds (Reuters, BBC, UN)")
|
| 483 |
-
report_parts.append(" • World Bank economic indicators")
|
| 484 |
-
report_parts.append(" • NLP entity extraction")
|
| 485 |
-
report_parts.append(" • AI generative analysis")
|
| 486 |
-
report_parts.append(" • Pattern recognition algorithms")
|
| 487 |
report_parts.append("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 488 |
|
| 489 |
-
report_parts.append(f"
|
|
|
|
| 490 |
|
| 491 |
return "\n".join(report_parts)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 492 |
|
| 493 |
-
# Inizializza
|
| 494 |
-
|
| 495 |
|
| 496 |
-
def
|
| 497 |
-
"""
|
| 498 |
if not user_query.strip():
|
| 499 |
-
return "❌ Inserisci una query per l'analisi geopolitica
|
| 500 |
|
| 501 |
-
#
|
| 502 |
-
|
| 503 |
|
| 504 |
-
|
|
|
|
| 505 |
|
| 506 |
-
# Esempi con focus
|
| 507 |
examples = [
|
| 508 |
-
"Analizza la
|
| 509 |
-
"
|
| 510 |
-
"
|
| 511 |
-
"
|
| 512 |
-
"
|
| 513 |
-
"
|
| 514 |
]
|
| 515 |
|
| 516 |
-
# Interface
|
| 517 |
demo = gr.Interface(
|
| 518 |
-
fn=
|
| 519 |
inputs=[
|
| 520 |
gr.Textbox(
|
| 521 |
-
label="Geopolitical Query",
|
| 522 |
-
placeholder="Es: Analizza
|
| 523 |
lines=3
|
| 524 |
)
|
| 525 |
],
|
| 526 |
outputs=[
|
| 527 |
gr.Textbox(
|
| 528 |
-
label="
|
| 529 |
-
lines=
|
| 530 |
-
max_lines=
|
| 531 |
)
|
| 532 |
],
|
| 533 |
-
title="
|
| 534 |
description="""
|
| 535 |
-
**🚀
|
| 536 |
|
| 537 |
-
|
| 538 |
-
•
|
| 539 |
-
•
|
| 540 |
-
•
|
| 541 |
-
•
|
|
|
|
| 542 |
|
| 543 |
-
💡 **Capabilities:**
|
| 544 |
-
•
|
| 545 |
-
•
|
| 546 |
-
•
|
| 547 |
-
•
|
| 548 |
|
| 549 |
-
|
| 550 |
""",
|
| 551 |
examples=examples,
|
| 552 |
-
theme=gr.themes.
|
| 553 |
css="""
|
| 554 |
.gradio-container {
|
| 555 |
-
max-width:
|
| 556 |
margin: auto;
|
|
|
|
| 557 |
}
|
| 558 |
.description {
|
| 559 |
-
background: linear-gradient(
|
| 560 |
color: white;
|
| 561 |
-
padding:
|
| 562 |
-
border-radius:
|
| 563 |
}
|
| 564 |
"""
|
| 565 |
)
|
|
|
|
| 4 |
from datetime import datetime, timedelta
|
| 5 |
import re
|
| 6 |
import xml.etree.ElementTree as ET
|
| 7 |
+
import numpy as np
|
| 8 |
+
import hashlib
|
| 9 |
+
from collections import defaultdict
|
| 10 |
+
import math
|
| 11 |
|
| 12 |
+
class VectorizedGeopoliticalAI:
|
| 13 |
def __init__(self):
|
| 14 |
+
# Spazi vettoriali multidimensionali per analisi geopolitica
|
| 15 |
+
self.vector_dimensions = 512
|
| 16 |
+
self.semantic_space = self.initialize_semantic_space()
|
| 17 |
+
|
| 18 |
+
# Matrici di trasformazione per concetti geopolitici
|
| 19 |
+
self.transformation_matrices = {
|
| 20 |
+
'power_dynamics': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1,
|
| 21 |
+
'economic_influence': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1,
|
| 22 |
+
'military_capability': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1,
|
| 23 |
+
'diplomatic_relations': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1,
|
| 24 |
+
'resource_control': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1,
|
| 25 |
+
'information_warfare': np.random.randn(self.vector_dimensions, self.vector_dimensions) * 0.1
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
# Knowledge Graph Embeddings
|
| 29 |
+
self.entity_embeddings = {}
|
| 30 |
+
self.relation_embeddings = {}
|
| 31 |
+
self.temporal_embeddings = {}
|
| 32 |
+
|
| 33 |
+
# Fonti real-time
|
| 34 |
self.data_sources = {
|
| 35 |
"reuters_rss": "https://feeds.reuters.com/reuters/worldNews",
|
| 36 |
"bbc_rss": "https://feeds.bbci.co.uk/news/world/rss.xml",
|
| 37 |
+
"un_news": "https://news.un.org/en/rss/rss.xml"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
+
self.initialize_embeddings()
|
| 41 |
+
|
| 42 |
+
def initialize_semantic_space(self):
|
| 43 |
+
"""Inizializza spazio semantico multidimensionale"""
|
| 44 |
+
# Crea base ortonormale per lo spazio semantico geopolitico
|
| 45 |
+
semantic_basis = {}
|
| 46 |
+
|
| 47 |
+
# Dimensioni fondamentali della geopolitica
|
| 48 |
+
fundamental_concepts = [
|
| 49 |
+
'sovereignty', 'power', 'alliance', 'conflict', 'trade', 'territory',
|
| 50 |
+
'resource', 'influence', 'security', 'diplomacy', 'ideology', 'culture',
|
| 51 |
+
'economy', 'military', 'information', 'technology', 'energy', 'population'
|
| 52 |
+
]
|
| 53 |
+
|
| 54 |
+
for i, concept in enumerate(fundamental_concepts):
|
| 55 |
+
vector = np.zeros(self.vector_dimensions)
|
| 56 |
+
# Distribuzione gaussiana per embedding iniziale
|
| 57 |
+
vector[:len(fundamental_concepts)] = np.random.normal(0, 0.1, len(fundamental_concepts))
|
| 58 |
+
vector[i] = 1.0 # Componente principale
|
| 59 |
+
semantic_basis[concept] = vector / np.linalg.norm(vector)
|
| 60 |
|
| 61 |
+
return semantic_basis
|
| 62 |
+
|
| 63 |
+
def initialize_embeddings(self):
|
| 64 |
+
"""Inizializza embeddings per entità geopolitiche"""
|
| 65 |
+
|
| 66 |
+
# Entità geopolitiche con caratteristiche vettoriali
|
| 67 |
+
entities = {
|
| 68 |
+
'USA': {'power': 0.95, 'economy': 0.92, 'military': 0.98, 'influence': 0.90},
|
| 69 |
+
'China': {'power': 0.88, 'economy': 0.89, 'military': 0.85, 'influence': 0.82},
|
| 70 |
+
'Russia': {'power': 0.75, 'economy': 0.45, 'military': 0.88, 'influence': 0.70},
|
| 71 |
+
'Germany': {'power': 0.65, 'economy': 0.85, 'military': 0.55, 'influence': 0.72},
|
| 72 |
+
'Ukraine': {'power': 0.25, 'economy': 0.20, 'military': 0.45, 'influence': 0.35},
|
| 73 |
+
'Iran': {'power': 0.40, 'economy': 0.30, 'military': 0.60, 'influence': 0.45},
|
| 74 |
+
'Israel': {'power': 0.55, 'economy': 0.70, 'military': 0.80, 'influence': 0.60},
|
| 75 |
+
'Taiwan': {'power': 0.45, 'economy': 0.75, 'military': 0.50, 'influence': 0.40},
|
| 76 |
+
'North Korea': {'power': 0.20, 'economy': 0.10, 'military': 0.70, 'influence': 0.25},
|
| 77 |
+
'NATO': {'power': 0.95, 'economy': 0.88, 'military': 0.95, 'influence': 0.90},
|
| 78 |
+
'EU': {'power': 0.80, 'economy': 0.90, 'military': 0.60, 'influence': 0.85}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
for entity, characteristics in entities.items():
|
| 82 |
+
# Crea vettore multidimensionale per l'entità
|
| 83 |
+
vector = np.zeros(self.vector_dimensions)
|
| 84 |
|
| 85 |
+
# Mappa caratteristiche su dimensioni vettoriali
|
| 86 |
+
for i, (char, value) in enumerate(characteristics.items()):
|
| 87 |
+
if char in self.semantic_space:
|
| 88 |
+
vector += value * self.semantic_space[char]
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
# Aggiungi rumore gaussiano per robustezza
|
| 91 |
+
vector += np.random.normal(0, 0.05, self.vector_dimensions)
|
| 92 |
+
|
| 93 |
+
# Normalizza
|
| 94 |
+
self.entity_embeddings[entity] = vector / (np.linalg.norm(vector) + 1e-8)
|
| 95 |
+
|
| 96 |
+
def text_to_vector(self, text):
|
| 97 |
+
"""Converte testo in rappresentazione vettoriale"""
|
| 98 |
+
# Tokenizzazione e pesatura TF-IDF semplificata
|
| 99 |
+
words = re.findall(r'\b\w+\b', text.lower())
|
| 100 |
+
|
| 101 |
+
# Crea vettore composito
|
| 102 |
+
composite_vector = np.zeros(self.vector_dimensions)
|
| 103 |
+
word_count = 0
|
| 104 |
+
|
| 105 |
+
# Mappa semantica delle parole chiave
|
| 106 |
+
semantic_mapping = {
|
| 107 |
+
'war': 'conflict', 'peace': 'diplomacy', 'trade': 'economy',
|
| 108 |
+
'military': 'military', 'sanctions': 'economy', 'alliance': 'alliance',
|
| 109 |
+
'nuclear': 'military', 'energy': 'resource', 'oil': 'resource',
|
| 110 |
+
'crisis': 'conflict', 'negotiation': 'diplomacy', 'summit': 'diplomacy'
|
| 111 |
}
|
| 112 |
|
| 113 |
+
for word in words:
|
| 114 |
+
if word in semantic_mapping and semantic_mapping[word] in self.semantic_space:
|
| 115 |
+
concept = semantic_mapping[word]
|
| 116 |
+
composite_vector += self.semantic_space[concept]
|
| 117 |
+
word_count += 1
|
| 118 |
+
elif word in self.semantic_space:
|
| 119 |
+
composite_vector += self.semantic_space[word]
|
| 120 |
+
word_count += 1
|
| 121 |
+
|
| 122 |
+
# Normalizzazione con peso logaritmico
|
| 123 |
+
if word_count > 0:
|
| 124 |
+
composite_vector /= math.log(word_count + 1)
|
| 125 |
+
|
| 126 |
+
return composite_vector / (np.linalg.norm(composite_vector) + 1e-8)
|
| 127 |
+
|
| 128 |
+
def compute_entity_relations(self, entities):
|
| 129 |
+
"""Calcola relazioni tra entità nello spazio vettoriale"""
|
| 130 |
+
relations = {}
|
| 131 |
+
|
| 132 |
+
for i, entity1 in enumerate(entities):
|
| 133 |
+
if entity1 not in self.entity_embeddings:
|
| 134 |
+
continue
|
| 135 |
+
|
| 136 |
+
for j, entity2 in enumerate(entities[i+1:], i+1):
|
| 137 |
+
if entity2 not in self.entity_embeddings:
|
| 138 |
+
continue
|
| 139 |
+
|
| 140 |
+
vec1 = self.entity_embeddings[entity1]
|
| 141 |
+
vec2 = self.entity_embeddings[entity2]
|
| 142 |
+
|
| 143 |
+
# Similarità coseno
|
| 144 |
+
cosine_sim = np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
|
| 145 |
+
|
| 146 |
+
# Distanza euclidea normalizzata
|
| 147 |
+
euclidean_dist = np.linalg.norm(vec1 - vec2) / math.sqrt(self.vector_dimensions)
|
| 148 |
+
|
| 149 |
+
# Proiezione su spazio delle alleanze
|
| 150 |
+
alliance_projection = np.dot(vec1 + vec2, self.semantic_space['alliance'])
|
| 151 |
+
|
| 152 |
+
# Proiezione su spazio dei conflitti
|
| 153 |
+
conflict_projection = np.dot(vec1 - vec2, self.semantic_space['conflict'])
|
| 154 |
+
|
| 155 |
+
relations[(entity1, entity2)] = {
|
| 156 |
+
'similarity': cosine_sim,
|
| 157 |
+
'distance': euclidean_dist,
|
| 158 |
+
'alliance_potential': alliance_projection,
|
| 159 |
+
'conflict_potential': abs(conflict_projection),
|
| 160 |
+
'power_differential': np.linalg.norm(vec1) - np.linalg.norm(vec2)
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
return relations
|
| 164 |
+
|
| 165 |
+
def apply_transformation_matrices(self, input_vector, context_type):
|
| 166 |
+
"""Applica matrici di trasformazione per analisi contestuale"""
|
| 167 |
+
if context_type not in self.transformation_matrices:
|
| 168 |
+
return input_vector
|
| 169 |
+
|
| 170 |
+
transformation_matrix = self.transformation_matrices[context_type]
|
| 171 |
+
transformed_vector = np.dot(transformation_matrix, input_vector)
|
| 172 |
+
|
| 173 |
+
# Applicazione funzione di attivazione (tanh per mantenere bounded)
|
| 174 |
+
activated_vector = np.tanh(transformed_vector)
|
| 175 |
+
|
| 176 |
+
return activated_vector
|
| 177 |
+
|
| 178 |
+
def vector_space_analysis(self, query_vector, entities, real_time_data):
|
| 179 |
+
"""Analisi nello spazio vettoriale multidimensionale"""
|
| 180 |
+
analysis = {}
|
| 181 |
+
|
| 182 |
+
# 1. Analisi di proiezione su sottospazi semantici
|
| 183 |
+
semantic_projections = {}
|
| 184 |
+
for concept, basis_vector in self.semantic_space.items():
|
| 185 |
+
projection = np.dot(query_vector, basis_vector)
|
| 186 |
+
semantic_projections[concept] = projection
|
| 187 |
+
|
| 188 |
+
# 2. Calcolo delle distanze nel manifold geopolitico
|
| 189 |
+
entity_distances = {}
|
| 190 |
+
for entity in entities:
|
| 191 |
+
if entity in self.entity_embeddings:
|
| 192 |
+
distance = np.linalg.norm(query_vector - self.entity_embeddings[entity])
|
| 193 |
+
entity_distances[entity] = distance
|
| 194 |
+
|
| 195 |
+
# 3. Analisi delle trasformazioni contestuali
|
| 196 |
+
contextual_transforms = {}
|
| 197 |
+
for context in self.transformation_matrices.keys():
|
| 198 |
+
transformed = self.apply_transformation_matrices(query_vector, context)
|
| 199 |
+
# Calcola l'entropia della trasformazione
|
| 200 |
+
entropy = -np.sum(transformed * np.log(np.abs(transformed) + 1e-8))
|
| 201 |
+
contextual_transforms[context] = {
|
| 202 |
+
'vector': transformed,
|
| 203 |
+
'entropy': entropy,
|
| 204 |
+
'norm': np.linalg.norm(transformed)
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
analysis['semantic_projections'] = semantic_projections
|
| 208 |
+
analysis['entity_distances'] = entity_distances
|
| 209 |
+
analysis['contextual_transforms'] = contextual_transforms
|
| 210 |
+
|
| 211 |
+
return analysis
|
| 212 |
+
|
| 213 |
+
def fetch_real_time_data(self):
|
| 214 |
+
"""Recupera dati real-time per alimentare i vettori"""
|
| 215 |
news_data = []
|
| 216 |
|
| 217 |
try:
|
|
|
|
| 219 |
response = requests.get(self.data_sources["reuters_rss"], timeout=10)
|
| 220 |
if response.status_code == 200:
|
| 221 |
root = ET.fromstring(response.content)
|
| 222 |
+
for item in root.findall(".//item")[:8]:
|
| 223 |
title = item.find("title")
|
|
|
|
| 224 |
description = item.find("description")
|
| 225 |
|
| 226 |
if title is not None:
|
| 227 |
news_data.append({
|
| 228 |
"source": "Reuters",
|
| 229 |
"title": title.text,
|
| 230 |
+
"description": description.text if description is not None else "",
|
| 231 |
+
"vector": self.text_to_vector(title.text + " " + (description.text or ""))
|
| 232 |
})
|
| 233 |
except:
|
| 234 |
pass
|
|
|
|
| 238 |
response = requests.get(self.data_sources["bbc_rss"], timeout=10)
|
| 239 |
if response.status_code == 200:
|
| 240 |
root = ET.fromstring(response.content)
|
| 241 |
+
for item in root.findall(".//item")[:8]:
|
| 242 |
title = item.find("title")
|
|
|
|
| 243 |
description = item.find("description")
|
| 244 |
|
| 245 |
if title is not None:
|
| 246 |
news_data.append({
|
| 247 |
"source": "BBC",
|
| 248 |
"title": title.text,
|
| 249 |
+
"description": description.text if description is not None else "",
|
| 250 |
+
"vector": self.text_to_vector(title.text + " " + (description.text or ""))
|
| 251 |
})
|
| 252 |
except:
|
| 253 |
pass
|
| 254 |
|
| 255 |
+
return news_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
|
| 257 |
+
def extract_entities_advanced(self, text_data):
|
| 258 |
+
"""Estrazione avanzata di entità con confidence scores"""
|
| 259 |
+
entities = []
|
| 260 |
+
entity_vectors = {}
|
| 261 |
+
|
| 262 |
+
# Pattern più sofisticati per entità geopolitiche
|
| 263 |
+
entity_patterns = {
|
| 264 |
+
'USA|United States|America|Washington': 'USA',
|
| 265 |
+
'China|Chinese|Beijing|PRC': 'China',
|
| 266 |
+
'Russia|Russian|Moscow|Kremlin': 'Russia',
|
| 267 |
+
'Ukraine|Ukrainian|Kyiv|Kiev': 'Ukraine',
|
| 268 |
+
'Iran|Iranian|Tehran': 'Iran',
|
| 269 |
+
'Israel|Israeli|Jerusalem': 'Israel',
|
| 270 |
+
'Taiwan|Taipei': 'Taiwan',
|
| 271 |
+
'North Korea|DPRK|Pyongyang': 'North Korea',
|
| 272 |
+
'NATO|North Atlantic': 'NATO',
|
| 273 |
+
'European Union|EU': 'EU',
|
| 274 |
+
'Germany|German|Berlin': 'Germany'
|
| 275 |
}
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
combined_text = ""
|
| 278 |
if isinstance(text_data, list):
|
| 279 |
for item in text_data:
|
|
|
|
| 284 |
else:
|
| 285 |
combined_text = str(text_data)
|
| 286 |
|
| 287 |
+
# Estrai entità con confidence
|
| 288 |
+
for pattern, entity in entity_patterns.items():
|
| 289 |
matches = re.findall(pattern, combined_text, re.IGNORECASE)
|
| 290 |
+
if matches:
|
| 291 |
+
confidence = len(matches) / len(combined_text.split()) * 100
|
| 292 |
+
entities.append({
|
| 293 |
+
'name': entity,
|
| 294 |
+
'confidence': min(confidence, 1.0),
|
| 295 |
+
'mentions': len(matches)
|
| 296 |
+
})
|
| 297 |
+
|
| 298 |
+
if entity in self.entity_embeddings:
|
| 299 |
+
entity_vectors[entity] = self.entity_embeddings[entity]
|
| 300 |
+
|
| 301 |
+
return entities, entity_vectors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
|
| 303 |
+
def generate_mathematical_analysis(self, query, real_time_data):
|
| 304 |
+
"""Genera analisi matematica avanzata dai vettori"""
|
| 305 |
|
| 306 |
try:
|
| 307 |
+
# 1. Converte query in vettore multidimensionale
|
| 308 |
+
query_vector = self.text_to_vector(query)
|
| 309 |
+
|
| 310 |
+
# 2. Estrai entità e loro vettori
|
| 311 |
+
entities, entity_vectors = self.extract_entities_advanced([{"title": query}] + real_time_data)
|
| 312 |
+
entity_names = [e['name'] for e in entities]
|
| 313 |
|
| 314 |
+
# 3. Calcola relazioni nello spazio vettoriale
|
| 315 |
+
relations = self.compute_entity_relations(entity_names)
|
|
|
|
| 316 |
|
| 317 |
+
# 4. Analisi vettoriale completa
|
| 318 |
+
vector_analysis = self.vector_space_analysis(query_vector, entity_names, real_time_data)
|
| 319 |
|
| 320 |
+
# 5. Genera report matematico
|
| 321 |
+
report = self.generate_vector_report(query, query_vector, entities, relations, vector_analysis, real_time_data)
|
| 322 |
|
| 323 |
return report
|
| 324 |
|
| 325 |
except Exception as e:
|
| 326 |
+
return f"❌ Errore nell'analisi vettoriale: {str(e)}"
|
| 327 |
|
| 328 |
+
def generate_vector_report(self, query, query_vector, entities, relations, vector_analysis, real_time_data):
|
| 329 |
+
"""Genera report basato su analisi vettoriale matematica"""
|
| 330 |
|
| 331 |
report_parts = []
|
| 332 |
|
| 333 |
+
# Header matematico
|
| 334 |
+
report_parts.append("🧮 VECTORIZED GEOPOLITICAL ANALYSIS")
|
| 335 |
+
report_parts.append("═" * 60)
|
| 336 |
+
report_parts.append(f"📐 Vector Space: R^{self.vector_dimensions} | Semantic Manifold Analysis")
|
| 337 |
+
report_parts.append(f"🕐 Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')}")
|
| 338 |
report_parts.append("")
|
| 339 |
|
| 340 |
+
# Query Vector Analysis
|
| 341 |
+
query_norm = np.linalg.norm(query_vector)
|
| 342 |
+
query_entropy = -np.sum(query_vector * np.log(np.abs(query_vector) + 1e-8))
|
| 343 |
+
report_parts.append(f"🎯 QUERY VECTORIZATION:")
|
| 344 |
+
report_parts.append(f" ∥q∥₂ = {query_norm:.4f} | H(q) = {query_entropy:.4f}")
|
| 345 |
+
report_parts.append(f" Dimensional complexity: {np.count_nonzero(np.abs(query_vector) > 0.1)}/{self.vector_dimensions}")
|
| 346 |
report_parts.append("")
|
| 347 |
|
| 348 |
+
# Semantic Projections
|
| 349 |
+
top_projections = sorted(vector_analysis['semantic_projections'].items(),
|
| 350 |
+
key=lambda x: abs(x[1]), reverse=True)[:6]
|
| 351 |
+
|
| 352 |
+
report_parts.append("📊 SEMANTIC SPACE PROJECTIONS:")
|
| 353 |
+
for concept, projection in top_projections:
|
| 354 |
+
intensity = "█" * int(abs(projection) * 20 + 1)
|
| 355 |
+
sign = "+" if projection > 0 else "-"
|
| 356 |
+
report_parts.append(f" {concept:.<15} {sign}{abs(projection):.3f} {intensity}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
report_parts.append("")
|
| 358 |
|
| 359 |
+
# Entity Analysis with Confidence
|
| 360 |
+
if entities:
|
| 361 |
+
report_parts.append("🎭 ENTITY DETECTION (CONFIDENCE-WEIGHTED):")
|
| 362 |
+
sorted_entities = sorted(entities, key=lambda x: x['confidence'], reverse=True)
|
| 363 |
+
for entity in sorted_entities[:8]:
|
| 364 |
+
confidence_bar = "▓" * int(entity['confidence'] * 20)
|
| 365 |
+
report_parts.append(f" {entity['name']:.<12} π={entity['confidence']:.3f} n={entity['mentions']} {confidence_bar}")
|
| 366 |
report_parts.append("")
|
| 367 |
|
| 368 |
+
# Vector Relations Analysis
|
| 369 |
+
if relations:
|
| 370 |
+
report_parts.append("🔗 INTER-ENTITY VECTOR RELATIONS:")
|
| 371 |
+
sorted_relations = sorted(relations.items(), key=lambda x: x[1]['similarity'], reverse=True)
|
| 372 |
+
for (e1, e2), rel_data in sorted_relations[:5]:
|
| 373 |
+
sim = rel_data['similarity']
|
| 374 |
+
conflict_pot = rel_data['conflict_potential']
|
| 375 |
+
alliance_pot = rel_data['alliance_potential']
|
| 376 |
+
|
| 377 |
+
# Classificazione relazione basata su metriche vettoriali
|
| 378 |
+
if alliance_pot > 0.3 and sim > 0.5:
|
| 379 |
+
relation_type = "🤝 ALLIANCE"
|
| 380 |
+
elif conflict_pot > 0.4 and sim < 0.2:
|
| 381 |
+
relation_type = "⚔️ ADVERSARIAL"
|
| 382 |
+
elif abs(rel_data['power_differential']) > 0.3:
|
| 383 |
+
relation_type = "⚖️ ASYMMETRIC"
|
| 384 |
+
else:
|
| 385 |
+
relation_type = "🔄 NEUTRAL"
|
| 386 |
+
|
| 387 |
+
report_parts.append(f" {e1} ↔ {e2}")
|
| 388 |
+
report_parts.append(f" {relation_type} | cos(θ)={sim:.3f} | ∆P={rel_data['power_differential']:.3f}")
|
| 389 |
report_parts.append("")
|
| 390 |
|
| 391 |
+
# Contextual Transformations
|
| 392 |
+
report_parts.append("🔄 CONTEXTUAL MANIFOLD TRANSFORMATIONS:")
|
| 393 |
+
for context, transform_data in vector_analysis['contextual_transforms'].items():
|
| 394 |
+
entropy = transform_data['entropy']
|
| 395 |
+
norm = transform_data['norm']
|
| 396 |
+
|
| 397 |
+
# Calcola divergenza dal vettore originale
|
| 398 |
+
divergence = np.linalg.norm(query_vector - transform_data['vector'])
|
| 399 |
+
|
| 400 |
+
report_parts.append(f" {context.replace('_', ' ').title()}:")
|
| 401 |
+
report_parts.append(f" H(T(q)) = {entropy:.3f} | ∥T(q)∥ = {norm:.3f} | D_KL = {divergence:.3f}")
|
| 402 |
report_parts.append("")
|
| 403 |
|
| 404 |
+
# Real-Time Vector Correlation
|
| 405 |
+
if real_time_data:
|
| 406 |
+
report_parts.append("📡 REAL-TIME VECTOR CORRELATION:")
|
| 407 |
+
correlations = []
|
| 408 |
+
|
| 409 |
+
for news in real_time_data[:5]:
|
| 410 |
+
if 'vector' in news:
|
| 411 |
+
correlation = np.dot(query_vector, news['vector'])
|
| 412 |
+
correlations.append((news['title'][:50] + "...", correlation))
|
| 413 |
+
|
| 414 |
+
sorted_correlations = sorted(correlations, key=lambda x: abs(x[1]), reverse=True)
|
| 415 |
+
for title, corr in sorted_correlations[:3]:
|
| 416 |
+
corr_intensity = "●" * int(abs(corr) * 15 + 1)
|
| 417 |
+
report_parts.append(f" ρ={corr:.3f} {corr_intensity}")
|
| 418 |
+
report_parts.append(f" {title}")
|
| 419 |
report_parts.append("")
|
| 420 |
|
| 421 |
+
# Mathematical Predictions
|
| 422 |
+
report_parts.append("🔮 MATHEMATICAL TRAJECTORY ANALYSIS:")
|
| 423 |
+
|
| 424 |
+
# Calcola gradiente nel semantic space
|
| 425 |
+
gradient_vector = np.zeros(self.vector_dimensions)
|
| 426 |
+
for concept, projection in vector_analysis['semantic_projections'].items():
|
| 427 |
+
if abs(projection) > 0.2: # Soglia significatività
|
| 428 |
+
gradient_vector += projection * self.semantic_space[concept]
|
| 429 |
+
|
| 430 |
+
gradient_norm = np.linalg.norm(gradient_vector)
|
| 431 |
+
|
| 432 |
+
if gradient_norm > 0.5:
|
| 433 |
+
report_parts.append(" 📈 HIGH-GRADIENT TRAJECTORY: Sistema in evoluzione rapida")
|
| 434 |
+
report_parts.append(f" ∇f = {gradient_norm:.3f} | Instabilità prevista")
|
| 435 |
+
elif gradient_norm > 0.2:
|
| 436 |
+
report_parts.append(" 📊 MODERATE-GRADIENT: Evoluzione controllata")
|
| 437 |
+
report_parts.append(f" ∇f = {gradient_norm:.3f} | Stabilità relativa")
|
| 438 |
+
else:
|
| 439 |
+
report_parts.append(" 📉 LOW-GRADIENT: Sistema in equilibrio")
|
| 440 |
+
report_parts.append(f" ∇f = {gradient_norm:.3f} | Convergenza locale")
|
| 441 |
+
|
| 442 |
+
# Risk Assessment basato su metriche vettoriali
|
| 443 |
+
risk_metrics = self.calculate_vector_risk_metrics(vector_analysis, relations)
|
| 444 |
report_parts.append("")
|
| 445 |
+
report_parts.append("⚠️ VECTOR-BASED RISK ASSESSMENT:")
|
| 446 |
+
report_parts.append(f" Risk Magnitude: ∥R∥ = {risk_metrics['magnitude']:.3f}")
|
| 447 |
+
report_parts.append(f" Entropy Level: H(R) = {risk_metrics['entropy']:.3f}")
|
| 448 |
+
report_parts.append(f" Stability Index: σ = {risk_metrics['stability']:.3f}")
|
| 449 |
|
| 450 |
+
# Footer metodologico
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
report_parts.append("")
|
| 452 |
+
report_parts.append("📚 MATHEMATICAL FRAMEWORK:")
|
| 453 |
+
report_parts.append(" • High-dimensional semantic embedding (512D)")
|
| 454 |
+
report_parts.append(" • Manifold learning on geopolitical concepts")
|
| 455 |
+
report_parts.append(" • Real-time vector correlation analysis")
|
| 456 |
+
report_parts.append(" • Multi-contextual transformation matrices")
|
| 457 |
+
report_parts.append(" • Information-theoretic risk quantification")
|
| 458 |
|
| 459 |
+
report_parts.append(f"")
|
| 460 |
+
report_parts.append(f"🔄 Next vector update: {(datetime.now() + timedelta(minutes=30)).strftime('%H:%M UTC')}")
|
| 461 |
|
| 462 |
return "\n".join(report_parts)
|
| 463 |
+
|
| 464 |
+
def calculate_vector_risk_metrics(self, vector_analysis, relations):
|
| 465 |
+
"""Calcola metriche di rischio basate su analisi vettoriale"""
|
| 466 |
+
|
| 467 |
+
# Risk magnitude basato su proiezioni semantiche
|
| 468 |
+
conflict_indicators = ['conflict', 'military', 'power']
|
| 469 |
+
risk_magnitude = sum(abs(vector_analysis['semantic_projections'].get(indicator, 0))
|
| 470 |
+
for indicator in conflict_indicators)
|
| 471 |
+
|
| 472 |
+
# Entropy del sistema basata su trasformazioni contestuali
|
| 473 |
+
entropies = [transform['entropy'] for transform in vector_analysis['contextual_transforms'].values()]
|
| 474 |
+
system_entropy = np.mean(entropies) if entropies else 0
|
| 475 |
+
|
| 476 |
+
# Stability index basato su varianza delle relazioni
|
| 477 |
+
if relations:
|
| 478 |
+
similarities = [rel['similarity'] for rel in relations.values()]
|
| 479 |
+
stability = 1.0 - np.var(similarities) if similarities else 1.0
|
| 480 |
+
else:
|
| 481 |
+
stability = 0.5
|
| 482 |
+
|
| 483 |
+
return {
|
| 484 |
+
'magnitude': min(risk_magnitude, 1.0),
|
| 485 |
+
'entropy': system_entropy,
|
| 486 |
+
'stability': stability
|
| 487 |
+
}
|
| 488 |
|
| 489 |
+
# Inizializza il sistema AI vettoriale
|
| 490 |
+
ai_system = VectorizedGeopoliticalAI()
|
| 491 |
|
| 492 |
+
def analyze_vectorized(user_query):
|
| 493 |
+
"""Funzione principale con analisi vettoriale matematica"""
|
| 494 |
if not user_query.strip():
|
| 495 |
+
return "❌ Inserisci una query per l'analisi vettoriale geopolitica."
|
| 496 |
|
| 497 |
+
# Recupera dati real-time e processa
|
| 498 |
+
real_time_data = ai_system.fetch_real_time_data()
|
| 499 |
|
| 500 |
+
# Analisi matematica completa
|
| 501 |
+
return ai_system.generate_mathematical_analysis(user_query, real_time_data)
|
| 502 |
|
| 503 |
+
# Esempi con focus su complessità matematica
|
| 504 |
examples = [
|
| 505 |
+
"Analizza la dinamica vettoriale del conflitto Russia-Ucraina",
|
| 506 |
+
"Proiezione multidimensionale delle tensioni USA-Cina",
|
| 507 |
+
"Manifold geopolitico della crisi energetica europea",
|
| 508 |
+
"Trasformazioni contestuali delle alleanze NATO",
|
| 509 |
+
"Correlazioni vettoriali nell'instabilità mediorientale",
|
| 510 |
+
"Analisi del gradiente nelle relazioni Indo-Pacifiche"
|
| 511 |
]
|
| 512 |
|
| 513 |
+
# Interface con focus matematico
|
| 514 |
demo = gr.Interface(
|
| 515 |
+
fn=analyze_vectorized,
|
| 516 |
inputs=[
|
| 517 |
gr.Textbox(
|
| 518 |
+
label="Geopolitical Vector Query",
|
| 519 |
+
placeholder="Es: Analizza lo spazio vettoriale delle tensioni Taiwan-Cina nel manifold indo-pacifico...",
|
| 520 |
lines=3
|
| 521 |
)
|
| 522 |
],
|
| 523 |
outputs=[
|
| 524 |
gr.Textbox(
|
| 525 |
+
label="Mathematical Geopolitical Analysis",
|
| 526 |
+
lines=35,
|
| 527 |
+
max_lines=45
|
| 528 |
)
|
| 529 |
],
|
| 530 |
+
title="🧮 Vectorized Geopolitical Intelligence AI",
|
| 531 |
description="""
|
| 532 |
+
**🚀 Analisi Geopolitica tramite Spazi Vettoriali Multidimensionali**
|
| 533 |
|
| 534 |
+
🔬 **Framework Matematico:**
|
| 535 |
+
• 📐 **Embedding Semantico**: 512-dimensional vector space
|
| 536 |
+
• 🌐 **Manifold Learning**: Proiezioni su sottospazi geopolitici
|
| 537 |
+
• 🔄 **Matrici di Trasformazione**: Analisi contestuali multiple
|
| 538 |
+
• 📊 **Correlazione Vettoriale**: Input real-time transformati
|
| 539 |
+
• ⚡ **Information Theory**: Risk assessment entropico
|
| 540 |
|
| 541 |
+
💡 **Advanced Capabilities:**
|
| 542 |
+
• Conversione linguaggio naturale → vettori multidimensionali
|
| 543 |
+
• Relazioni inter-entità calcolate in spazio astratto
|
| 544 |
+
• Gradient analysis per previsioni di traiettoria
|
| 545 |
+
• Metriche quantitative per assessment geopolitico
|
| 546 |
|
| 547 |
+
🎯 **Output**: Analisi matematica rigorosa invece di template generici
|
| 548 |
""",
|
| 549 |
examples=examples,
|
| 550 |
+
theme=gr.themes.Monochrome(),
|
| 551 |
css="""
|
| 552 |
.gradio-container {
|
| 553 |
+
max-width: 1100px;
|
| 554 |
margin: auto;
|
| 555 |
+
font-family: 'Courier New', monospace;
|
| 556 |
}
|
| 557 |
.description {
|
| 558 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 559 |
color: white;
|
| 560 |
+
padding: 25px;
|
| 561 |
+
border-radius: 15px;
|
| 562 |
}
|
| 563 |
"""
|
| 564 |
)
|