NETWORK Procedure

Example 2.18 A Node Similarity Recipe Recommendation Engine

When recommending products to consumers, retailers often build models that are based on known relationships between consumers and products, such as purchase history or online reviews. These models are known as recommendation engines. This example builds a model that recommends recipes that are most similar and most dissimilar from each other, based on the similarity of their ingredient lists. The data set consists of six sauce recipes, each consisting of some subset of ingredients. The inclusion of ingredients in recipes is organized into a bipartite network G, shown in Figure 245.

Figure 245: Recipe-Ingredient Network G

Recipe-Ingredient Network


The links of G are constructed from raw data that are specified in adjacency list format in the DATA step:

data mylib.LinkSetRecipesIn;
   infile datalines dsd flowover;
   length Recipe $20. Ingredient1-Ingredient13 $20.;
   input Recipe $ Ingredient1-Ingredient13 $;
   array ingredient Ingredient1 -- Ingredient13;
   from = Recipe;
   do over ingredient;
      if missing(ingredient) then leave;
      to = Ingredient;
      output;
   end;
   keep from to;
   datalines;
Spag Sauce,      Tomato,Garlic,Salt,Onion,TomatoPaste,OliveOil
                 Oregano,Parsley, , , , ,
Spag Meat Sauce, Tomato,Garlic,Salt,Onion,TomatoPaste,OliveOil
                 Celery,GreenPepper,BayLeaf,GroundBeef,Carrot
                 PorkSausage,RedPepper
Eggplant Relish, Garlic,Salt,Onion,TomatoPaste,OliveOil,Eggplant
                 GreenOlives,Capers,Sugar, , , ,
Creole Sauce,    Tomato,Salt,Onion,TomatoPaste,OliveOil,Celery
                 Broth,GreenPepper,BlackPepper,Paprika,Thyme
                 WorcestershireSauce,
Salsa,           Tomato,Garlic,Salt,Onion,Cilantro,Tomatillo
                 JalapenoPepper,Lime, , , , ,
Enchilada Sauce, Tomato,Broth,Cumin,Flour,BrownSugar,ChiliPowder
                 CayennePepper,Oil, , , , ,
;

In this example, the cosine node similarity scores between pairs of recipes are of interest.

The following DATA step defines the subset of nodes that represent the six recipes:

data mylib.NodesSubsetRecipesIn;
   infile datalines dsd;
   length node $20.;
   source = 1;
   sink = 1;
   input node;
   datalines;
Spag Sauce
Spag Meat Sauce
Eggplant Relish
Creole Sauce
Salsa
Enchilada Sauce
;

The following statements produce the output data table mylib.NodeSim, which contains the cosine similarity scores between the nodes in the input subset; higher similarity scores indicate greater overlap of the recipes’ ingredient lists.

proc network
   links            = mylib.LinkSetRecipesIn
   nodesSubset      = mylib.NodesSubsetRecipesIn;
   nodeSimilarity
      jaccard       = false
      cosine        = true
      outSimilarity = mylib.SimilarityRecipesOut;
run;

The output data table mylib.SimilarityRecipesOut contains the cosine similarity score of each recipe node pair, as shown in Output 2.18.1.

Output 2.18.1: Recipe Cosine Similarity Output

sourcesinkcosine
Creole SauceCreole Sauce1.00000
Creole SauceSpag Meat Sauce0.56045
Creole SauceSpag Sauce0.51031
Creole SauceEggplant Relish0.38490
Creole SauceSalsa0.30619
Creole SauceEnchilada Sauce0.20412
Eggplant RelishEggplant Relish1.00000
Eggplant RelishSpag Sauce0.58926
Eggplant RelishSpag Meat Sauce0.46225
Eggplant RelishCreole Sauce0.38490
Eggplant RelishSalsa0.35355
Eggplant RelishEnchilada Sauce0.00000
Enchilada SauceEnchilada Sauce1.00000
Enchilada SauceCreole Sauce0.20412
Enchilada SauceSpag Sauce0.12500
Enchilada SauceSalsa0.12500
Enchilada SauceSpag Meat Sauce0.09806
Enchilada SauceEggplant Relish0.00000
SalsaSalsa1.00000
SalsaSpag Sauce0.50000
SalsaSpag Meat Sauce0.39223
SalsaEggplant Relish0.35355
SalsaCreole Sauce0.30619
SalsaEnchilada Sauce0.12500
Spag Meat SauceSpag Meat Sauce1.00000
Spag Meat SauceSpag Sauce0.58835
Spag Meat SauceCreole Sauce0.56045
Spag Meat SauceEggplant Relish0.46225
Spag Meat SauceSalsa0.39223
Spag Meat SauceEnchilada Sauce0.09806
Spag SauceSpag Sauce1.00000
Spag SauceEggplant Relish0.58926
Spag SauceSpag Meat Sauce0.58835
Spag SauceCreole Sauce0.51031
Spag SauceSalsa0.50000
Spag SauceEnchilada Sauce0.12500


The following statements produce a heat map visualization of the similarity between pairs of recipes:

proc sort data=mylib.SimilarityRecipesOut out=SimilarityRecipesSorted;
   by sink source;
run;
proc sgplot data=SimilarityRecipesSorted noautolegend;
   title "Cosine Similarity of Recipes";
   heatmap y=source x=sink / weight=cosine
      colormodel=(white green) outline x2axis;
   text y=source x=sink text=cosine / textAttrs=(size=10pt);
   xaxis display=none;
   x2axis display=(nolabel);
   yaxis display=(nolabel) reverse;
run;

Output 2.18.2: Cosine Node Similarity between Recipe Pairs

Cosine Node Similarity between Recipe Pairs


From the heat map shown in Output 2.18.2, you can conclude that the recipes most similar to the Creole sauce recipe by ingredient cosine similarity are the spaghetti meat sauce and spaghetti sauce recipes. Conversely, the enchilada sauce and eggplant relish recipes have zero cosine similarity because they have no ingredients in common.

Last updated: August 07, 2026