code: def calculate_similar_artists(output_filename, model_name="als"):
      """generates a list of similar artists in lastfm by utilizing the 'similar_items'
      api of the models"""
      artists, _, plays = get_lastfm()
  
      # create a model from the input data
      model = get_model(model_name)
  
      # if we're training an ALS based model, weight input for last.fm
      # by bm25
      if model_name.endswith("als"):
          # lets weight these models by bm25weight.
          logging.debug("weighting matrix by bm25_weight")
          plays = bm25_weight(plays, K1=100, B=0.8)
  
          # also disable building approximate recommend index
          model.approximate_recommend = False
  
      # this is actually disturbingly expensive:
      plays = plays.tocsr()
      user_plays = plays.T.tocsr()
  
      logging.debug("training model %s", model_name)
      start = time.time()
      model.fit(user_plays)
      logging.debug(
          "trained model '%s' in %0.2fs",
          model_name,
          time.time() - start,
      )
  
      # write out similar artists by popularity
      start = time.time()
      logging.debug("calculating top artists")
  
      user_count = np.ediff1d(plays.indptr)
      to_generate = sorted(
          np.arange(len(artists)), key=lambda x: -user_count[x]
      )
  
      # write out as a TSV of artistid, otherartistid, score
      logging.debug("writing similar items")
      with tqdm.tqdm(total=len(to_generate)) as progress:
          with codecs.open(output_filename, "w", "utf8") as o:
              batch_size = 1000
              for startidx in range(0, len(to_generate), batch_size):
                  batch = to_generate[startidx : startidx + batch_size]
                  ids, scores = model.similar_items(batch, 11)
                  for i, artistid in enumerate(batch):
                      artist = artists[artistid]
                      for other, score in zip(ids[i], scores[i]):
                          o.write(
                              f"{artist}\t{artists[other]}\t{score}\n"
                          )
                  progress.update(len(batch))
  
      logging.debug(
          "generated similar artists in %0.2fs", time.time() - start
      )
  
file_path: implicit/examples/lastfm.py
imports: import argparse
  import codecs
  import logging
  import time
  import numpy
  import tqdm
  from implicit.als import AlternatingLeastSquares
  from implicit.approximate_als import AnnoyAlternatingLeastSquares, FaissAlternatingLeastSquares, NMSLibAlternatingLeastSquares
  from implicit.bpr import BayesianPersonalizedRanking
  from implicit.datasets.lastfm import get_lastfm
  from implicit.lmf import LogisticMatrixFactorization
  from implicit.nearest_neighbours import BM25Recommender, CosineRecommender, TFIDFRecommender, bm25_weight
label_desc: Use image node_id 2 for calling a global function with example usage: calculate_similar_artists(output_filename, model_name) without return types