women’s style recommendation with artificial intelligence (part #1)

Introduction

We know several basic style “rules” (ha!) based on body shape:

  • Skirts:
    • “Apple” Body Shape:
      • IF body shape is apple AND skirt has front zipper THEN don’t wear
      • IF body shape is apple AND skirt has side zipper THEN wear
      • IF body shape is apple AND skirt has no zipper THEN wear
    • “Rectangular” Body Shape:
      • IF body shape is rectangle AND skirt has front zipper THEN wear
      • IF body shape is rectangle AND skirt has front zipper THEN wear
      • IF body shape is rectangle AND skirt has front zipper THEN wear
      • IF body shape is rectangle AND skirt is A-line THEN wear
  • Pants:
    • “Apple” Body Shape:
      • IF body shape is apple AND jeans have flare THEN wear
      • IF body shape is apple AND jeans have pleats THEN don’t wear
      • IF body shape is apple AND jeans have stretch THEN wear
      • IF body shape is apple AND trousers have flare THEN wear
      • IF body shape is apple AND trousers have pleats THEN don’t wear
      • IF body shape is apple AND trousers have stretch THEN wear
    • “Rectangle” Body Shape:
      • IF body shape is rectangle AND jeans have flare THEN wear
      • IF body shape is rectangle AND jeans have pleats THEN wear
      • IF body shape is rectangle AND jeans have stretch THEN wear
      • IF body shape is rectangle AND trousers have flare THEN wear
      • IF body shape is rectangle AND trousers have pleats THEN wear
      • IF body shape is rectangle AND trousers have stretch THEN wear

We want to create an artificially intelligent system to probabilistically decide, given a query such as “I have an ‘apple’ body shape and am thinking of wearing a skirt with a zipper in front. Should I?”. To accomplish this we use these rules to train a Bayesian network, and then use the network to make inferences upon queries such as the one given above.

Training the Network

From these we derive the 13 nodes of our Bayesian network:

Node
apple
jeans.with.flare
jeans.with.pleats
jeans.with.stretch
rectangle
skirt.with.a.line
skirt.with.front.zipper
skirt.with.no.zipper
skirt.with.side.zipper
trousers.with.flare
trousers.with.pleats
trousers.with.stretch
wear

We use the rules and the nodes to produce an automatically generated graph. Put to help it along, we will apply some expert knowledge and specify some

We seed the model structure identification algorithm with some basic expert knowledge by manually specifying the following 12 causal relationships:

From To
rectangle wear
apple wear
skirt.with.front.zipper wear
skirt.with.side.zipper wear
skirt.with.no.zipper wear
skirt.with.a.line wear
jeans.with.flare wear
jeans.with.stretch wear
jeans.with.pleats wear
trousers.with.flare wear
trousers.with.stretch wear
trousers.with.pleats wear

(We will see later that the automated graph structure learning procedure adds one more edge).

We save these relationships in “output/style_edges.csv” for later import using R.

We then encode the rules in dictionaries/hashes for items co-joint in a rule. For example, we express the skirt-related rules pertaining to apple-shaped bodies in JSON as:

    {
        "wear": "Yes",
        "apple": "1",
        "skirt.with.no.zipper": "1"
    },
    {
        "wear": "Yes",
        "apple": "1",
        "skirt.with.side.zipper": "1",
    },
    {
        "wear": "No",
        "apple": "1",
        "skirt.with.front.zipper": "1",
    }

For each entry, we zero out all other nodes (expect for “wear”, which is set to “No”), and express all 19 rules as a data frame, where the index order corresponds to the node order displayed above:

0,0,0,0,1,0,0,1,0,0,0,0,Yes
0,0,0,0,1,0,1,0,0,0,0,0,Yes
0,0,0,0,1,0,0,0,1,0,0,0,Yes
0,0,0,0,1,1,0,0,0,0,0,0,Yes
0,1,0,0,1,0,0,0,0,0,0,0,Yes
0,0,0,1,1,0,0,0,0,0,0,0,Yes
0,0,1,0,1,0,0,0,0,0,0,0,Yes
0,0,0,0,1,0,0,0,0,1,0,0,Yes
0,0,0,0,1,0,0,0,0,0,0,1,Yes
0,0,0,0,1,0,0,0,0,0,1,0,Yes
1,0,0,0,0,0,0,1,0,0,0,0,Yes
1,0,0,0,0,0,0,0,1,0,0,0,Yes
1,0,0,0,0,0,1,0,0,0,0,0,No
1,1,0,0,0,0,0,0,0,0,0,0,Yes
1,0,0,1,0,0,0,0,0,0,0,0,Yes
1,0,1,0,0,0,0,0,0,0,0,0,No
1,0,0,0,0,0,0,0,0,1,0,0,Yes
1,0,0,0,0,0,0,0,0,0,0,1,Yes
1,0,0,0,0,0,0,0,0,0,1,0,No

We save this data frame as “output/style_rules.csv” for later import by R.

In R, we load the necessary libraries and the CSV files. We also ensure everything is a factor in the rules data frame:

We look at the expert-specified edges, noting the existence of 12 relationships. After running the hill climbing algorithm to derive the network structure from the prior-specified edges and the rules, we notice that now 13 edges are present:

Here is the added edge:

From To
apple rectangle

We derive the model’s parameters from the training data, and then compile it for use in inference.

Results

Suppose we have an “apple” body shape, and want to choose a skirt using this model. We try the following skirt types against the apple body shape to infer whether or not to wear a particular skirt:

The first result in the image above resoundingly rejects wearing a skirt having a front zipper when one carries and apple-shaped body. By contrast, the second result approves of skirts having side zippers for apple-shaped folks. Both results concord with the IF-THEN-ELSE rules initially specified. The third result proves interesting—we did not provide a rule for apple-shaped bodies and A-line skirts, so the model provides no conclusion.

We observe similar results for trousers: The first two outcomes match the rules, but the third provides no decision because we provided no information about whether flare and stretch may be used together in a pair of trousers for apple-shaped bodies, or for any body shape for that matter!

Issues to Resolve

As indicated in the last paragraph, in practice a pair of trousers may have both flare and the ability to stretch. Each of these traits alone proves great for apple-shaped individuals. So together I manually infer that the two together are at least okay and may be even preferable. However, the model does not derive such a conclusion. In other words, we need to add rules saying these two traits may coexist.

Also, this effort took a lot of manual “expert” specification of the initial “seed” graph structure. Ideally one would learn the final structure purely from rules. My thinking is that the rule data frame is rather sparse, making it hard to learn the structure in an automated fashion. On the other hand, I may not have chosen the best learning algorithm.

Stay tuned…

– Emily

Update 16 April 2018

I’m onto the next iteration of the model design. A visual of results so far:

Post Author: badassdatascience

Leave a Reply

Your email address will not be published.