docstr: Load this dataset into an undirected heterogeneous graph, downloading it if required.
  
  The graph has two types of nodes (``user`` and ``movie``) and one type of edge (``rating``).
  
  The dataset includes some node features on both users and movies: on users, they consist of
  categorical features (``gender`` and ``job``) which are one-hot encoded into binary
  features, and an ``age`` feature that is scaled to have mean = 0 and standard deviation = 1.
  
  Returns:
      A tuple where the first element is a :class:`.StellarGraph` instance containing the graph
      data and features, and the second element is a pandas DataFrame of edges, with columns
      ``user_id``, ``movie_id`` and ``rating`` (a label from 1 to 5).
docstr_tok: ["Load","this","dataset","into","an","undirected","heterogeneous","graph",",","downloading","it","if","required",".","The","graph","has","two","types","of","nodes","(","``","user","``","and","``","movie","``",")","and","one","type","of","edge","(","``","rating","``",")",".","The","dataset","includes","some","node","features","on","both","users","and","movies",":","on","users",",","they","consist","of","categorical","features","(","``","gender","``","and","``","job","``",")","which","are","one-hot","encoded","into","binary","features",",","and","an","``","age","``","feature","that","is","scaled","to","have","mean","=","0","and","standard","deviation","=","1",".","Returns",":","A","tuple","where","the","first","element","is","a",":","class",":","`",".StellarGraph","`","instance","containing","the","graph","data","and","features",",","and","the","second","element","is","a","pandas","DataFrame","of","edges",",","with","columns","``","user_id","``",",","``","movie_id","``","and","``","rating","``","(","a","label","from","1","to","5",")","."]
code: def load(self):
      """
      Load this dataset into an undirected heterogeneous graph, downloading it if required.
  
      The graph has two types of nodes (``user`` and ``movie``) and one type of edge (``rating``).
  
      The dataset includes some node features on both users and movies: on users, they consist of
      categorical features (``gender`` and ``job``) which are one-hot encoded into binary
      features, and an ``age`` feature that is scaled to have mean = 0 and standard deviation = 1.
  
      Returns:
          A tuple where the first element is a :class:`.StellarGraph` instance containing the graph
          data and features, and the second element is a pandas DataFrame of edges, with columns
          ``user_id``, ``movie_id`` and ``rating`` (a label from 1 to 5).
      """
      self.download()
  
      ratings, users, movies, *_ = [
          self._resolve_path(path) for path in self.expected_files
      ]
  
      edges = pd.read_csv(
          ratings,
          sep="\t",
          header=None,
          names=["user_id", "movie_id", "rating", "timestamp"],
          usecols=["user_id", "movie_id", "rating"],
      )
  
      users = pd.read_csv(
          users,
          sep="|",
          header=None,
          names=["user_id", "age", "gender", "job", "zipcode"],
          usecols=["user_id", "age", "gender", "job"],
      )
  
      movie_columns = [
          "movie_id",
          "title",
          "release_date",
          "video_release_date",
          "imdb_url",
          # features from here:
          "unknown",
          "action",
          "adventure",
          "animation",
          "childrens",
          "comedy",
          "crime",
          "documentary",
          "drama",
          "fantasy",
          "film_noir",
          "horror",
          "musical",
          "mystery",
          "romance",
          "sci_fi",
          "thriller",
          "war",
          "western",
      ]
      movies = pd.read_csv(
          movies,
          sep="|",
          header=None,
          names=movie_columns,
          usecols=["movie_id"] + movie_columns[5:],
          encoding="iso-8859-1",
      )
  
      # manage the IDs
      def u(users):
          return "u_" + users.astype(str)
  
      def m(movies):
          return "m_" + movies.astype(str)
  
      users_ids = u(users["user_id"])
  
      movies["movie_id"] = m(movies["movie_id"])
      movies.set_index("movie_id", inplace=True)
  
      edges["user_id"] = u(edges["user_id"])
      edges["movie_id"] = m(edges["movie_id"])
  
      # convert categorical user features to numeric, and normalize age
      feature_encoding = preprocessing.OneHotEncoder(sparse=False)
      onehot = feature_encoding.fit_transform(users[["gender", "job"]])
      scaled_age = preprocessing.scale(users["age"])
      encoded_users = pd.DataFrame(onehot, index=users_ids).assign(
          scaled_age=scaled_age
      )
  
      g = StellarGraph(
          {"user": encoded_users, "movie": movies},
          {"rating": edges[["user_id", "movie_id"]]},
          source_column="user_id",
          target_column="movie_id",
      )
      return g, edges
  
imports: from .dataset_loader import DatasetLoader
  from ..core.graph import StellarGraph, StellarDiGraph
  import itertools
  import logging
  import os
  import pandas
  import numpy
  from sklearn import preprocessing
  from ..core.experimental import experimental
label_desc: Use image node_id 1 for calling the MovieLens obj's underlying member method code with example usage: obj.load() and returns: g,  edges, unknown, unknown