NETWORK Procedure
Example 2.22 Using Projection to Recommend Recipe Ingredient Pairings
The task of recipe recommendation that is demonstrated in A Node Similarity Recipe Recommendation Engine can also be achieved by using projection. This example solves a similar recommendation problem that considers ingredient pairings instead of recipe pairings. By using the PROJECTION statement, you can find pairs of ingredients that occur together in one or more recipes. Consider again the data table mylib.LinkSetRecipesIn, which is used in Example 2.18. The inclusion of ingredients in recipes is organized into a bipartite network G, which is shown in Figure 245.
In this example, the numbers of common neighbors (recipe nodes) between ingredient node pairs are of interest. The PROJECTION statement requires a nodes data table with a column that indicates which nodes are recipes and which nodes are ingredients. You can use the following statements to generate the nodes data table mylib.NodeSetRecipesIn (which has a single variable called node):
proc network
links = mylib.LinkSetRecipesIn
outNodes = mylib.NodeSetRecipesIn;
run;
Then, you can use the following DATA step to define a partition variable:
data mylib.NodeSetRecipesIn;
set mylib.NodeSetRecipesIn;
if node in (
'Spag Sauce'
'Spag Meat Sauce'
'Eggplant Relish'
'Creole Sauce'
'Salsa'
'Enchilada Sauce'
) then partition = 0;
else partition = 1;
run;
The partition variable has a value of 0 for recipe nodes and a value of 1 for ingredient nodes. Therefore, PROC NETWORK computes the network projection onto ingredient nodes through recipe nodes. The following statements produce the output data table mylib.ProjectionLinkSetOut, which contains links between ingredient pairs that appear in at least one common recipe. In addition, the output data table mylib.ProjectionListOut contains the lists of recipes that are common to each pair of ingredients.
proc network
nodes = mylib.NodeSetRecipesIn
links = mylib.LinkSetRecipesIn;
projection
partition = partition
commonNeighbors = true
outProjectionLinks = mylib.ProjectionLinkSetOut
outNeighborsList = mylib.ProjectionListOut;
run;
The output is displayed in Output 2.22.1; it contains the ingredient pairings that occur in three or more recipes. For example, garlic and olive oil have three common neighbors, which means they occur together in three recipes.
Output 2.22.1: Top Ingredient Pairings
| from | to | commonNeighbors |
|---|---|---|
| Onion | Salt | 5 |
| Garlic | Onion | 4 |
| Garlic | Salt | 4 |
| OliveOil | Onion | 4 |
| OliveOil | Salt | 4 |
| OliveOil | TomatoPaste | 4 |
| Onion | Tomato | 4 |
| Onion | TomatoPaste | 4 |
| Salt | Tomato | 4 |
| Salt | TomatoPaste | 4 |
| Garlic | OliveOil | 3 |
| Garlic | Tomato | 3 |
| Garlic | TomatoPaste | 3 |
| OliveOil | Tomato | 3 |
| Tomato | TomatoPaste | 3 |
You can also use the following statements to display the particular recipes that contain both garlic and olive oil:
proc print data=mylib.ProjectionListOut
(where=(from = 'Garlic' and to = 'OliveOil'))
noobs;
run;
The output is shown in Output 2.22.2; it indicates that eggplant relish, spaghetti sauce, and spaghetti meat sauce are the three recipes that contain both garlic and olive oil.
Output 2.22.2: Top Ingredient Pairings
| from | to | neighbor_id | neighbor |
|---|---|---|---|
| Garlic | OliveOil | 1 | Eggplant Relish |
| Garlic | OliveOil | 2 | Spag Meat Sauce |
| Garlic | OliveOil | 3 | Spag Sauce |