בניית מסכות סמיכות לקבוצות מאקרו במנגנון קשב לנכסים
סיכום
כלי זה בונה מטריצת סמיכות בוליאנית בין נכסים, על סמך תוויות קבוצת נכסים וקישורים אופציונליים בין קבוצות. נכסים המשויכים לאותה קבוצת מאקרו מקושרים זה לזה, וכל קשת שסופקה בין קבוצות מקשרת את כל חברי שתי הקבוצות בשני הכיוונים. קישורים עצמיים אופציונליים מאפשרים לכל נכס להפנות קשב לעצמו. נכסים ללא מיפוי משויכים לקבוצה לא ידועה, ולכן הם מקושרים לנכסים אחרים ללא מיפוי.
פונקציה שנייה ממירה את מטריצת הסמיכות למסכת קשב, באמצעות סימון זוגות שאינם סמוכים כבלתי מורשים. הקוד בודק שהמטריצה הקלטית ריבועית לפני ההמרה. כך אפשר לקודד הנחת קיבוץ מאקרו במודל קשב, אך הכלי אינו אומד קבוצות או קשרים מנתוני שוק, והתועלת שלו תלויה באיכות ובעדכניות של המיפוי שסופק ושל הקשתות בין הקבוצות. המסמך מציג פרטי מימוש ולא תוצאות אמפיריות או הערכת מסחר.
רעיונות מרכזיים
- נכסים באותה קבוצה מקבלים קשרים הדדיים במטריצת הסמיכות.
- קישורים בין קבוצות מחברים באופן סימטרי כל נכס בקבוצה אחת לכל נכס בקבוצה האחרת.
- אפשר לכלול או להשמיט קשרים עצמיים באמצעות פרמטר.
- נכסים ללא מיפוי חולקים קבוצה לא ידועה, ולכן הם מקושרים זה לזה.
- מסכת הקשב מסמנת כל זוג נכסים שאינו סמוך כבלתי מורשה.
תגיות
הטקסט המלא
# graph.py
```py
"""Macroeconomic graph prior utilities.
Builds an asset-level adjacency matrix from macro group labels and
cross-group edges for adjacency-masked attention in DeePM.
"""
from __future__ import annotations
from collections.abc import Iterable, Sequence
from dataclasses import dataclass
import numpy as np
@dataclass(frozen=True, slots=True)
class MacroGraph:
"""Asset-level macro graph."""
assets: list[str]
groups: list[str]
adjacency: np.ndarray # Boolean (N, N)
def build_macro_adjacency(
*,
assets: Sequence[str],
asset_to_group: dict[str, str],
cross_group_edges: Iterable[tuple[str, str]] = (),
include_self_loops: bool = True,
) -> MacroGraph:
"""Build a boolean adjacency matrix from group labels and group edges.
Parameters
----------
assets: Asset identifiers matching the price panel columns.
asset_to_group: Mapping from asset -> macro group label.
cross_group_edges: Undirected (group_a, group_b) edges.
include_self_loops: If True, sets A[i,i] = True.
"""
assets_list = [str(a) for a in assets]
groups = [str(asset_to_group.get(a, "UNKNOWN")) for a in assets_list]
n = len(assets_list)
adj = np.zeros((n, n), dtype=bool)
if include_self_loops:
np.fill_diagonal(adj, True)
group_to_indices: dict[str, list[int]] = {}
for i, g in enumerate(groups):
group_to_indices.setdefault(g, []).append(i)
for indices in group_to_indices.values():
idx = np.array(indices, dtype=int)
adj[np.ix_(idx, idx)] = True
for g1, g2 in cross_group_edges:
idx1 = group_to_indices.get(g1, [])
idx2 = group_to_indices.get(g2, [])
if not idx1 or not idx2:
continue
a = np.array(idx1, dtype=int)
b = np.array(idx2, dtype=int)
adj[np.ix_(a, b)] = True
adj[np.ix_(b, a)] = True
return MacroGraph(assets=assets_list, groups=groups, adjacency=adj)
def adjacency_to_attn_mask(adjacency: np.ndarray) -> np.ndarray:
"""Convert boolean adjacency to attention mask (True = disallowed)."""
if adjacency.ndim != 2 or adjacency.shape[0] != adjacency.shape[1]:
raise ValueError("adjacency must be square (N,N)")
return ~adjacency
```מוצג במלואו בציון המקור ובהתאם לרישיון שלו. רישיון: MIT
הסיכום נכתב בידי סוכן המחקר של Stratmill על סמך המקור; הוא אינו העתק של המקור.