Variable propagation


(Eric Cyliu) #1

Can someone help explain variable propagation in details ? I am not sure how it works.
Here is an example from docs. I do not understand

  1. how “math(paths / (num_films/paths))” can be fraction ?
  2. why is “math(num_films/paths)” always the same as “num_films” ?
  3. Why is “math(num_films)” not always the same, i.e., should be the same as total_nums?
curl localhost:8080/query -XPOST -d '{
	movie_fraction(func:eq(name@en, "Peter Jackson")){
   uid
    paths as math(1)
    total_films : num_films as count(director.film)
    director : name@en

    director.film {
      starring {
        performance.actor {
          path: math(paths)
          xx: math(num_films/paths)
          *fraction : math(paths / (num_films/paths))*
          actor : name@en
        }
      }
    }
  }
}' | python -m json.tool | less

Results:

{
  "data": {
    "movie_fraction": [
      {
        "total_films": 0,
        "director": "Peter Jackson"
      },
      {
        "total_films": 0,
        "director": "Peter Jackson"
      },
      {
        "actor": "Tim McLachlan",
        "director": "Peter Jackson",
        "fraction": 0.052632,
        "path": 1,
        "total_films": 19,
        "xx": 19
      },
      {
        "actor": "Thomas Rimmer",
        "director": "Peter Jackson",
        "fraction": 0.052632,
        "path": 1,
        "total_films": 19,
        "xx": 19
      },
      {
        "actor": "Jeffrey Thomas",
        "director": "Peter Jackson",
        "fraction": 0.105263,
        "path": 2,
        "total_films": 19,
        "xx": 19
      },
      {
        "actor": "Cate Blanchett",
        "director": "Peter Jackson",
        "fraction": 0.315789,
        "path": 6,
        "total_films": 19,
        "xx": 19
      },
...
...
...

(Pawan Rawal) #2

The blogpost on recommendation engines does a good job of explaining variable propagation. It is best understood by drawing a graph and calculating the value of a variable at different levels

The blogpost mentions:

In short, the value that a node receives is equal to the sum of values of all its parent nodes.

You could try with a smaller query on https://play.dgraph.io and try to correlate the graph response with the JSON.

{
  movie_fraction(func:eq(name@en, "Peter Jackson")){
    uid
    paths as math(1)
    total_films : num_films as count(director.film)
    name@en

    director.film (first: 5) {
      starring(first: 5) {
        performance.actor {
          path: math(paths)
          xx: math(num_films/paths)
          fraction : math(paths / (num_films/paths))
          name@en
        }
      }
    }
  }
}

which produces the following Graph

and has the following JSON response

{
  "data": {
    "movie_fraction": [
      {
        "uid": "0x8b77c",
        "val(paths)": 1,
        "total_films": 0,
        "name@en": "Peter Jackson"
      },
      {
        "uid": "0x1cdf22",
        "val(paths)": 1,
        "total_films": 0,
        "name@en": "Peter Jackson"
      },
      {
        "uid": "0x764275",
        "val(paths)": 1,
        "total_films": 19,
        "name@en": "Peter Jackson",
        "director.film": [
          {
            "starring": [
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Tim McLachlan"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Thomas Rimmer"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Jeffrey Thomas"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 2,
                    "xx": 19,
                    "fraction": 0.105263,
                    "name@en": "Cate Blanchett"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "William Kircher"
                  }
                ]
              }
            ]
          },
          {
            "starring": [
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Craig Hall"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Lee Hartley"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Lee Donahue"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Julie Holmes"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Jim Knobeloch"
                  }
                ]
              }
            ]
          },
          {
            "starring": [
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Anthony Ray Parker"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Elizabeth Hawthorne"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 2,
                    "xx": 19,
                    "fraction": 0.105263,
                    "name@en": "Stuart Devenie"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "William Pomeroy"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Angela Bloomfield"
                  }
                ]
              }
            ]
          },
          {
            "starring": [
              {
                "performance.actor": [
                  {
                    "path": 2,
                    "xx": 19,
                    "fraction": 0.105263,
                    "name@en": "Stuart Devenie"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Mark Hadlow"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Donna Akersten"
                  }
                ]
              }
            ]
          },
          {
            "starring": [
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Hugo Weaving"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "James Nesbitt"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Christopher Lee"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 1,
                    "xx": 19,
                    "fraction": 0.052632,
                    "name@en": "Ken Stott"
                  }
                ]
              },
              {
                "performance.actor": [
                  {
                    "path": 2,
                    "xx": 19,
                    "fraction": 0.105263,
                    "name@en": "Cate Blanchett"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "uid": "0x7dc6b0",
        "val(paths)": 1,
        "total_films": 0,
        "name@en": "Peter Jackson"
      }
    ]
  }
}

As you can see from the JSON response, only Cate Blanchett and Stuart Devenie have value of path as 2 which is also observable from the graph since they have two incoming edges. Remember, the value of a variable at a node is the sum of values of the variable for its parent nodes.

Now to answer your questions.

This is because both num_films and paths are defined at the same level, so the ratio of their values would remain the same at every level.

I think you meant same as total_films. A variable has different value at different depths i.e. what we call variable propagation. So the value at a level would depend on the sum of the value of a variable at the parent nodes.

We convert an integer variable to float before passing it to the division(/) operator and as value of paths is less than value of num_films/paths you end up with a fraction. I’d definitely recommend reading the section on Variable propogation in the blogpost.


(system) #3

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.