class_docstr: Python impl of TextRank by Milhacea, et al., as a spaCy extension,
  used to extract the top-ranked phrases from a text document
class_docstr_tok: ["Python","impl","of","TextRank","by","Milhacea",",","et","al.",",","as","a","spaCy","extension",",","used","to","extract","the","top-ranked","phrases","from","a","text","document"]
docstr: run extractive summarization, based on vector distance 
  per sentence from the top-ranked phrases,
  when module set as 'paragraph', the func get the average score per paragraph then sort the paragraphs
docstr_tok: ["run","extractive","summarization",",","based","on","vector","distance","per","sentence","from","the","top-ranked","phrases",",","when","module","set","as","'paragraph","'",",","the","func","get","the","average","score","per","paragraph","then","sort","the","paragraphs"]
code: def summary(
      self,
      limit_phrases=10,
      limit_sentences=4,
      preserve_order=False,
      module="sentence",
  ):
      """
      run extractive summarization, based on vector distance
      per sentence from the top-ranked phrases,
      when module set as 'paragraph', the func get the average score per paragraph then sort the paragraphs
      """
      unit_vector = []
  
      # construct a list of sentence boundaries with a phrase set
      # for each (initialized to empty)
  
      sent_bounds = [[s.start, s.end, set([])] for s in self.doc.sents]
  
      # iterate through the top-ranked phrases, added them to the
      # phrase vector for each sentence
  
      phrase_id = 0
  
      for p in self.doc._.phrases:
          unit_vector.append(p.rank)
  
          if self.logger:
              self.logger.debug(
                  "{} {} {}".format(phrase_id, p.text, p.rank)
              )
  
          for chunk in p.chunks:
              for sent_start, sent_end, sent_vector in sent_bounds:
                  if (
                      chunk.start >= sent_start
                      and chunk.start <= sent_end
                  ):
                      sent_vector.add(phrase_id)
  
                      if self.logger:
                          self.logger.debug(
                              " {} {} {} {}".format(
                                  sent_start,
                                  chunk.start,
                                  chunk.end,
                                  sent_end,
                              )
                          )
  
                      break
  
          phrase_id += 1
  
          if phrase_id == limit_phrases:
              break
  
      # construct a unit_vector for the top-ranked phrases, up to
      # the requested limit
  
      sum_ranks = sum(unit_vector)
  
      try:
          unit_vector = [rank / sum_ranks for rank in unit_vector]
      except ZeroDivisionError:
          unit_vector = (0.0,) * len(unit_vector)
  
      # iterate through each sentence, calculating its euclidean
      # distance from the unit vector
  
      sent_rank = {}
      sent_id = 0
  
      for sent_start, sent_end, sent_vector in sent_bounds:
          sum_sq = 0.0
  
          for phrase_id in range(len(unit_vector)):
              if phrase_id not in sent_vector:
                  sum_sq += unit_vector[phrase_id] ** 2.0
  
          sent_rank[sent_id] = sqrt(sum_sq)
          sent_id += 1
  
      if module == "sentence":
          # extract the sentences with the lowest distance
  
          sent_text = {}
          sent_id = 0
  
          for sent in self.doc.sents:
              sent_text[sent_id] = sent
              sent_id += 1
  
          # build a list of sentence indices, sorted according to their
          # corresponding rank
          top_sent_ids = list(range(len(sent_rank)))
          top_sent_ids.sort(key=lambda sent_id: sent_rank[sent_id])
          # truncate to the given limit
          top_sent_ids = top_sent_ids[:limit_sentences]
          # sort in ascending order of index to preserve the order in which the
          # sentences appear in the original text
          if preserve_order:
              top_sent_ids.sort()
          # yield results, up to the limit requested
          for sent_id in top_sent_ids:
              yield sent_text[sent_id]
  
      elif module == "paragraph":
          # input a section include paragraphs separated by "\n\n",
          # get the average score per paragraph then sort the paragraphs
          limit_paragraphs = limit_sentences
          paragraph_text_dict = {}
          paragrapy_rank = {}
          sent_id = 0
          score = 0
          p_text = ""
          for num, sent in enumerate(self.doc.sents):
              p_text += sent.text
              score += sent_rank[num]
  
              # separate every paragraph then reset score
              if sent.text.endswith("\n\n") or (num + 1) == len(
                  sent_rank
              ):
                  paragraph_text_dict[sent_id] = p_text
                  paragrapy_rank[sent_id] = score / len(
                      p_text.split(".")
                  )
                  sent_id += 1
                  p_text = ""
                  score = 0
  
          # build a list of paragraph indices, sorted according to their
          # corresponding rank
  
          # truncate to the given limit
          top_sent_ids = sorted(
              paragrapy_rank.items(), key=lambda x: x[1]
          )[:limit_paragraphs]
          top_sent_ids = [i[0] for i in top_sent_ids]
  
          # sort in ascending order of index to preserve the order in which the
          # paragraphs appear in the original text
          if preserve_order:
              top_sent_ids.sort()
          # yield results, up to the limit requested
          for sent_id in top_sent_ids:
              yield paragraph_text_dict[sent_id]
  
imports: from .base import BaseTextRank
  from .positionrank import PositionRank
  from collections import defaultdict, OrderedDict
  from math import sqrt
  from spacy.tokens import Doc
  import graphviz
  import json
  import logging
  import networkx
  import os
  import os.path
  import re
  import spacy
  import string
  import sys
  import time
  import unicodedata
label_desc: Use image node_id 10 for calling the TextRank obj's underlying member method code with example usage: obj.summary(limit_phrases, limit_sentences, preserve_order, module) without return types