code: def create(
      item_data,
      item_id,
      observation_data=None,
      user_id=None,
      target=None,
      weights="auto",
      similarity_metrics="auto",
      item_data_transform="auto",
      max_item_neighborhood_size=64,
      verbose=True,
  ):
      """Create a content-based recommender model in which the similarity
      between the items recommended is determined by the content of
      those items rather than learned from user interaction data.
  
      The similarity score between two items is calculated by first
      computing the similarity between the item data for each column,
      then taking a weighted average of the per-column similarities to
      get the final similarity.  The recommendations are generated
      according to the average similarity of a candidate item to all the
      items in a user's set of rated items.
  
      Parameters
      ----------
  
      item_data : SFrame
          An SFrame giving the content of the items to use to learn the
          structure of similar items.  The SFrame must have one column
          that matches the name of the `item_id`; this gives a unique
          identifier that can then be used to make recommendations.  The rest
          of the columns are then used in the distance calculations
          below.
  
      item_id : string
          The name of the column in item_data (and `observation_data`,
          if given) that represents the item ID.
  
      observation_data : None (optional)
          An SFrame giving user and item interaction data.  This
          information is stored in the model, and the recommender will
          recommend the items with the most similar content to the
          items that were present and/or highly rated for that user.
  
      user_id : None (optional)
          If observation_data is given, then this specifies the column
          name corresponding to the user identifier.
  
      target : None (optional)
          If observation_data is given, then this specifies the column
          name corresponding to the target or rating.
  
      weights : dict or 'auto' (optional)
          If given, then weights must be a dictionary of column names
          present in item_data to weights between the column names.  If
          'auto' is given, the all columns are weighted equally.
  
      max_item_neighborhood_size : int, 64
          For each item, we hold this many similar items to use when
          aggregating models for predictions.  Decreasing this value
          decreases the memory required by the model and decreases the
          time required to generate recommendations, but it may also
          decrease recommendation accuracy.
  
      verbose : True or False (optional)
          If set to False, then less information is printed.
  
      Examples
      --------
  
        >>> item_data = tc.SFrame({"my_item_id" : range(4),
                                   "data_1" : [ [1, 0], [1, 0], [0, 1], [0.5, 0.5] ],
                                   "data_2" : [ [0, 1], [1, 0], [0, 1], [0.5, 0.5] ] })
  
        >>> m = tc.recommender.item_content_recommender.create(item_data, "my_item_id")
        >>> m.recommend_from_interactions([0])
  
        Columns:
                my_item_id      int
                score   float
                rank    int
  
        Rows: 3
  
        Data:
        +------------+----------------+------+
        | my_item_id |     score      | rank |
        +------------+----------------+------+
        |     3      | 0.707106769085 |  1   |
        |     1      |      0.5       |  2   |
        |     2      |      0.5       |  3   |
        +------------+----------------+------+
        [3 rows x 3 columns]
  
        >>> m.recommend_from_interactions([0, 1])
  
        Columns:
                my_item_id      int
                score   float
                rank    int
  
        Rows: 2
  
        Data:
        +------------+----------------+------+
        | my_item_id |     score      | rank |
        +------------+----------------+------+
        |     3      | 0.707106769085 |  1   |
        |     2      |      0.25      |  2   |
        +------------+----------------+------+
        [2 rows x 3 columns]
  
      """
      from turicreate._cython.cy_server import QuietProgress
  
      # item_data is correct type
      if (
          not isinstance(item_data, _SFrame)
          or item_data.num_rows() == 0
      ):
          raise TypeError(
              "`item_data` argument must be a non-empty SFrame giving item data to use for similarities."
          )
  
      # Error checking on column names
      item_columns = set(item_data.column_names())
  
      if item_id not in item_columns:
          raise ValueError(
              "Item column given as 'item_id = %s', but this is not found in `item_data` SFrame."
              % item_id
          )
  
      # Now, get the set ready to test for other argument issues.
      item_columns.remove(item_id)
  
      if weights != "auto":
          if type(weights) is not dict:
              raise TypeError(
                  "`weights` parameter must be 'auto' or a dictionary of column "
                  "names in `item_data` to weight values."
              )
  
          bad_columns = [
              col_name
              for col_name in item_columns
              if col_name not in item_columns
          ]
          if bad_columns:
              raise ValueError(
                  "Columns %s given in weights, but these are not found in item_data."
                  % ", ".join(bad_columns)
              )
  
          # Now, set any columns not given in the weights column to be
          # weight 0.
          for col_name in item_columns:
              weights.setdefault(col_name, 0)
  
      ################################################################################
      # Now, check the feature transformer stuff.
  
      # Pass it through a feature transformer.
      if item_data_transform == "auto":
          item_data_transform = (
              _turicreate.toolkits._feature_engineering.AutoVectorizer(
                  excluded_features=[item_id]
              )
          )
  
      if not isinstance(
          item_data_transform,
          _turicreate.toolkits._feature_engineering.TransformerBase,
      ):
          raise TypeError(
              "item_data_transform must be 'auto' or a valid feature_engineering transformer instance."
          )
  
      # Transform the input data.
      item_data = item_data_transform.fit_transform(item_data)
  
      # Translate any string columns to actually work in nearest
      # neighbors by making it a categorical list.  Also translate lists
      # into dicts, and normalize numeric columns.
      gaussian_kernel_metrics = set()
  
      for c in item_columns:
          if item_data[c].dtype is str:
              item_data[c] = item_data[c].apply(lambda s: {s: 1})
          elif item_data[c].dtype in [float, int]:
              item_data[c] = (item_data[c] - item_data[c].mean()) / max(
                  item_data[c].std(), 1e-8
              )
              gaussian_kernel_metrics.add(c)
  
      if verbose:
          print("Applying transform:")
          print(item_data_transform)
  
      opts = {}
      model_proxy = _turicreate.extensions.item_content_recommender()
      model_proxy.init_options(opts)
  
      # The user_id is implicit if none is given.
      if user_id is None:
          user_id = "__implicit_user__"
  
      normalization_factor = 1
  
      # Set the observation data.
      if observation_data is None:
          # In this case, it's important to make this a string type.  If
          # the user column is not given, it may be given at recommend
          # time, in which case it is cast to a string type and cast
          # back if necessary.
          empty_user = _turicreate.SArray([], dtype=str)
          empty_item = _turicreate.SArray(
              [], dtype=item_data[item_id].dtype
          )
          observation_data = _turicreate.SFrame(
              {user_id: empty_user, item_id: empty_item}
          )
  
      # Now, work out stuff for the observation_data component
      normalization_factor = 1
  
      # 1 for the item_id column.
      if item_data.num_columns() >= 3:
          if weights == "auto":
              # TODO: automatically tune this.
              weights = {
                  col_name: 1
                  for col_name in item_data.column_names()
                  if col_name != item_id
              }
  
          # Use the abs value here in case users pass in weights with negative values.
          normalization_factor = sum(abs(v) for v in weights.values())
          if normalization_factor == 0:
              raise ValueError("Weights cannot all be set to 0.")
  
          distance = [
              (
                  [col_name],
                  (
                      "gaussian_kernel"
                      if col_name in gaussian_kernel_metrics
                      else "cosine"
                  ),
                  weight,
              )
              for col_name, weight in weights.items()
          ]
  
      else:
          distance = "cosine"
  
      # Now, build the nearest neighbors model:
      nn = _turicreate.nearest_neighbors.create(
          item_data, label=item_id, distance=distance, verbose=verbose
      )
      graph = nn.query(
          item_data,
          label=item_id,
          k=max_item_neighborhood_size,
          verbose=verbose,
      )
      graph = graph.rename(
          {
              "query_label": item_id,
              "reference_label": "similar",
              "distance": "score",
          },
          inplace=True,
      )
  
      def process_weights(x):
          return max(-1, min(1, 1 - x / normalization_factor))
  
      graph["score"] = graph["score"].apply(process_weights)
  
      opts = {
          "user_id": user_id,
          "item_id": item_id,
          "target": target,
          "similarity_type": "cosine",
          "max_item_neighborhood_size": max_item_neighborhood_size,
      }
  
      user_data = _turicreate.SFrame()
      extra_data = {"nearest_items": graph}
      with QuietProgress(verbose):
          model_proxy.train(
              observation_data, user_data, item_data, opts, extra_data
          )
  
      return ItemContentRecommender(model_proxy)
  
file_path: turicreate/src/python/turicreate/toolkits/recommender/item_content_recommender.py
imports: from __future__ import print_function
  from __future__ import division
  from __future__ import absolute_import
  import turicreate
  from turicreate import SFrame
  from turicreate.toolkits.recommender.util import _Recommender
label_desc: Use image node_id 1 for calling a global function with example usage: create(item_data, item_id, observation_data, user_id, target, weights, similarity_metrics, item_data_transform, max_item_neighborhood_size, verbose) and returns: ItemContentRecommender, max