class_docstr: Implements the *TopicRank* algorithm described by
  [[bougouin-etal-2013-topicrank]](https://derwen.ai/docs/ptr/biblio/#bougouin-etal-2013-topicrank)
  deployed as a `spaCy` pipeline component.
  
  This class does not get called directly; instantiate its factory
  instead.
  
  Algorithm Overview:
  
  1. Preprocessing: Sentence segmentation, word tokenization, POS tagging.
     After this stage, we have preprocessed text.
  2. Candidate extraction: Extract sequences of nouns and adjectives (i.e. noun chunks)
     After this stage, we have a list of keyphrases that may be topics.
  3. Candidate clustering: Hierarchical Agglomerative Clustering algorithm with average
     linking using simple set-based overlap of lemmas. Similarity is achieved at > 25%
     overlap. **Note**: PyTextRank deviates from the original algorithm here, which uses
     stems rather than lemmas.
     After this stage, we have a list of topics.
  4. Candidate ranking: Apply *TextRank* on a complete graph, with topics as nodes
     (i.e. clusters derived in the last step), where edge weights are higher between
     topics that appear closer together within the document.
     After this stage, we have a ranked list of topics.
  5. Candidate selection: Select the first occurring keyphrase from each topic to
     represent that topic.
     After this stage, we have a ranked list of topics, with a keyphrase to represent
     the topic.
      
docstr: Constructor for a factory used to instantiate the PyTextRank pipeline components.
  
      edge_weight:
  default weight for an edge
  
      pos_kept:
  parts of speech tags to be kept; adjust this if strings representing the POS tags change
  
      token_lookback:
  the window for neighboring tokens – similar to a *skip gram*
  
      scrubber:
  optional "scrubber" function to clean up punctuation from a token; if `None` then defaults to `pytextrank.default_scrubber`; when running, PyTextRank will throw a `FutureWarning` warning if the configuration uses a deprecated approach for a scrubber function
  
      stopwords:
  optional dictionary of `lemma: [pos]` items to define the *stop words*, where each item has a key as a lemmatized token and a value as a list of POS tags; may be a file name (string) or a [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html) for a JSON file; otherwise throws a `TypeError` exception
  
      threshold:
  threshold used in *TopicRank* candidate clustering; the original algorithm uses 0.25
  
      method:
  clustering method used in *TopicRank* candidate clustering: see [`scipy.cluster.hierarchy.linkage`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html) for valid methods; the original algorithm uses "average"
          
docstr_tok: ["Constructor","for","a","factory","used","to","instantiate","the","PyTextRank","pipeline","components",".","edge_weight",":","default","weight","for","an","edge","pos_kept",":","parts","of","speech","tags","to","be","kept",";","adjust","this","if","strings","representing","the","POS","tags","change","token_lookback",":","the","window","for","neighboring","tokens","\u2013","similar","to","a","*","skip","gram","*","scrubber",":","optional","``","scrubber","''","function","to","clean","up","punctuation","from","a","token",";","if","`","None","`","then","defaults","to","`","pytextrank.default_scrubber","`",";","when","running",",","PyTextRank","will","throw","a","`","FutureWarning","`","warning","if","the","configuration","uses","a","deprecated","approach","for","a","scrubber","function","stopwords",":","optional","dictionary","of","`","lemma",":","[","pos","]","`","items","to","define","the","*","stop","words","*",",","where","each","item","has","a","key","as","a","lemmatized","token","and","a","value","as","a","list","of","POS","tags",";","may","be","a","file","name","(","string",")","or","a","[","`","pathlib.Path","`","]","(","https",":","\/\/docs.python.org\/3\/library\/pathlib.html",")","for","a","JSON","file",";","otherwise","throws","a","`","TypeError","`","exception","threshold",":","threshold","used","in","*","TopicRank","*","candidate","clustering",";","the","original","algorithm","uses","0.25","method",":","clustering","method","used","in","*","TopicRank","*","candidate","clustering",":","see","[","`","scipy.cluster.hierarchy.linkage","`","]","(","https",":","\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.cluster.hierarchy.linkage.html",")","for","valid","methods",";","the","original","algorithm","uses","``","average","''"]
code: def __init__(
      self,
      doc: Doc,
      edge_weight: float,
      pos_kept: typing.List[str],
      token_lookback: int,
      scrubber: typing.Callable,
      stopwords: typing.Dict[str, typing.List[str]],
      threshold: float,
      method: str,
  ) -> None:
      """
      Constructor for a factory used to instantiate the PyTextRank pipeline components.
  
          edge_weight:
      default weight for an edge
  
          pos_kept:
      parts of speech tags to be kept; adjust this if strings representing the POS tags change
  
          token_lookback:
      the window for neighboring tokens – similar to a *skip gram*
  
          scrubber:
      optional "scrubber" function to clean up punctuation from a token; if `None` then defaults to `pytextrank.default_scrubber`; when running, PyTextRank will throw a `FutureWarning` warning if the configuration uses a deprecated approach for a scrubber function
  
          stopwords:
      optional dictionary of `lemma: [pos]` items to define the *stop words*, where each item has a key as a lemmatized token and a value as a list of POS tags; may be a file name (string) or a [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html) for a JSON file; otherwise throws a `TypeError` exception
  
          threshold:
      threshold used in *TopicRank* candidate clustering; the original algorithm uses 0.25
  
          method:
      clustering method used in *TopicRank* candidate clustering: see [`scipy.cluster.hierarchy.linkage`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html) for valid methods; the original algorithm uses "average"
      """
      super().__init__(
          doc,
          edge_weight,
          pos_kept,
          token_lookback,
          scrubber,
          stopwords,
      )
  
      # TopicRank candidate clustering parameters
      self.threshold: float = threshold
      self.method: str = method
  
imports: from collections import defaultdict
  from functools import lru_cache
  import time
  import typing
  from icecream import ic
  from scipy.cluster.hierarchy import fcluster, linkage
  from scipy.spatial.distance import pdist
  from spacy.tokens import Doc, Span
  import networkx
  from .base import BaseTextRank, BaseTextRankFactory, Phrase, StopWordsLike
label_desc: Use image node_id 1 to create a new TopicRank object from inherited base classes: BaseTextRank with example: obj = TopicRank(doc, edge_weight, pos_kept, token_lookback, scrubber, stopwords, threshold, method)