code: def initSearch(self) -> None:
      N = len(self.index._docweight)
      threshold = int(max(1000, N * 0.05))
  
      stop_words = []
      self._wids_dict = {}
  
      bucket = self.index.family.IF.Bucket
      for wid, docs in self.index._wordinfo.items():
          if len(docs) > threshold:
              stop_words.append(wid)
              continue
  
          if isinstance(docs, dict):
              docs = bucket(docs)
              self.index._wordinfo[wid] = docs
  
          idf = numpy.log1p(N / len(docs))
          term = self.lexicon._words[wid]
  
          self._wids_dict[term] = (wid, idf)
  
      for wid in stop_words:
          word = self.lexicon._words.pop(wid)
          del self.lexicon._wids[word]
          logger.info(f"Removing stop word {word}")
          del self.index._wordinfo[wid]
  
file_path: dedupe/dedupe/canopy_index.py
imports: from __future__ import annotations
  import logging
  import math
  from typing import Iterable
  import numpy
  from BTrees.Length import Length
  from zope.index.text.cosineindex import CosineIndex
  from zope.index.text.lexicon import Lexicon
  from zope.index.text.setops import mass_weightedUnion
  from zope.index.text.textindex import TextIndex
label_desc: Use image node_id 2 for calling the CanopyIndex obj's underlying member method code with example usage: obj.initSearch() without return types