code: def _compute_word_scores(
      doc: Doc,
      graph: nx.Graph,
      cooc_mat: dict[tuple[str, str], int],
      normalize: Optional[str | Callable[[Token], str]],
  ) -> dict[str, float]:
      word_strs: list[str] = list(graph.nodes())
      # "level of hierarchy" component
      max_truss_levels = _compute_node_truss_levels(graph)
      max_truss_level = max(max_truss_levels.values())
      # check for edge case when all word scores would be zero / undefined
      if not max_truss_level:
          return {}
  
      # "semantic strength of a word" component
      sem_strengths = {
          w: sum(
              cooc_mat[tuple(sorted([w, nbr]))] * max_truss_levels[nbr]
              for nbr in graph.neighbors(w)
          )
          for w in word_strs
      }
      # "semantic connectivity" component
      sem_connectivities = {
          w: len(
              set(max_truss_levels[nbr] for nbr in graph.neighbors(w))
          )
          / max_truss_level
          for w in word_strs
      }
      # "positional weight" component
      word_pos = collections.defaultdict(float)
      for word, word_str in zip(
          doc, ext_utils.terms_to_strings(doc, normalize)
      ):
          word_pos[word_str] += 1 / (word.i + 1)
      return {
          w: word_pos[w]
          * max_truss_levels[w]
          * sem_strengths[w]
          * sem_connectivities[w]
          for w in word_strs
      }
  
file_path: textacy/src/textacy/extract/keyterms/scake.py
imports: from __future__ import annotations
  import collections
  import itertools
  from operator import itemgetter
  from typing import Callable, Collection, Counter, Iterable, Optional
  import networkx
  from cytoolz import itertoolz
  from spacy.tokens import Doc, Token
  from ...None import utils
  from ..None import utils
label_desc: Use image node_id 2 for calling a global function with example usage: _compute_word_scores(doc, graph, cooc_mat, normalize) and returns: unknown, dict