Just like traditional applications development, machine learning involves writing code. One aspect where the two differ is the workflow. While software development follows a fairly linear process (design, develop, and deploy a feature), machine learning is a different beast. You work on a single feature, which is never 100% complete. You constantly run experiments, and re-design your model in depth at a rapid pace. Traditional tests are entirely useless. Validating whether you are on the right track takes minutes, if not hours.
In this talk, we will take the example of a Machine Learning competition we recently participated in, the Kaggle Home Depot competition, to illustrate what "doing Machine Learning" looks like. We will explain the challenges we faced, and how we tackled them, setting up a harness to easily create and run experiments, while keeping our sanity. We will also draw comparisons with traditional software development, and highlight how some ideas translate from one context to the other, adapted to different constraints.
2. About me
• Mathias @brandewinder
• F# & Machine Learning
• Based in San Francisco
• I do have a tiny accent
3. Why this talk?
• Machine learning competition as a team
• Team work requires process
• Code, but “subtly different”
• Statically typed functional with F#
8. Team & Results
• Jamie Dixon
(@jamie_Dixon), Taylor
Wood (@squeekeeper), &
alii
• Final ranking: 122nd/2125
(top 6%)
9. The question
“6 inch damper”
“Battic Door Energy Conservation
Products Premium 6 in. Back Draft
Damper”
Is this any good?
Search Product
10. The data
"Simpson Strong-Tie 12-Gauge Angle","l bracket",2.5
"BEHR Premium Textured DeckOver 1-gal. #SC-141 Tugboat Wood and
Concrete Coating","deck over",3
"Delta Vero 1-Handle Shower Only Faucet Trim Kit in Chrome (Valve Not
Included)","rain shower head",2.33
"Toro Personal Pace Recycler 22 in. Variable Speed Self-Propelled Gas
Lawn Mower with Briggs & Stratton Engine","honda mower",2
"Hampton Bay Caramel Simple Weave Bamboo Rollup Shade - 96 in. W x 72
in. L","hampton bay chestnut pull up shade",2.67
"InSinkErator SinkTop Switch Single Outlet for InSinkErator
Disposers","disposer",2.67
"Sunjoy Calais 8 ft. x 5 ft. x 8 ft. Steel Tile Fabric Grill
Gazebo","grill gazebo",3
...
11. The problem
• Given a Search, and the Product that was recommended,
• Predict how Relevant the recommendation is,
• Rated from terrible (1.0) to awesome (3.0).
12. The competition
• 70,000 training examples
• 20,000 search + product to predict
• Smallest RMSE* wins
• About 3 months
*RMSE ~ average distance between correct and predicted values
14. An obvious solution
// domain model
type Observation = {
Search: string
Product: string
}
// prediction function
let predict (obs:Observation) = 2.0
16. Code, but…
• Domain is trivial
• No obvious tests to write
• Correctness is (mostly) unimportant
What are we trying to do here?
17. We will change the function predict,
over and over and over again,
trying to be creative, and
come up with a predict function that
fits the data better.
18. Observation
• Single feature
• Never complete, no binary test
• Many experiments
• Possibly in parallel
• No “correct” model - any model could work. If it performs
better, it is better.
32. Validating
• Leave some of the data out
• Learn on part of the data
• Evaluate performance on the rest
33. Recap
• Traditional software: incrementally build solutions by
completing discrete features,
• Machine Learning: create experiments, hoping to improve
a predictor
• Traditional process likely inadequate
39. To avoid waste,
build flexibility where
there is volatility,
and automate repeatable steps.
40. Strategy
• Use types to represent what we are doing
• Automate everything that doesn’t change: data loading,
algorithm learning, evaluation
• Make what changes often (and is valuable) easy to
change: creation of features
41. Core model
type Observation = {
Search: string
Product: string }
type Relevance : float
type Predictor = Observation -> Relevance
type Feature = Observation -> float
type Example = Relevance * Observation
type Model = Feature []
type Learning = Model -> Example [] -> Predictor
42. “Catalog of Features”
let ``search length`` : Feature =
fun obs -> obs.Search.Length |> float
let ``product title length`` : Feature =
fun obs -> obs.Product.Length |> float
let ``matching words`` : Feature =
fun obs ->
let w1 = obs.Search.Split ' ' |> set
let w2 = obs.Product.Split ' ' |> set
Set.intersect w1 w2 |> Set.count |> float
43. Experiments
// shared/common data loading code
let model = [|
``search length``
``product title length``
``matching words``
|]
let predictor = RandomForest.regression model training
Let quality = evaluate predictor validation
46. Food for thought
• Use types for modelling
• Model the process, not the entity
• Cross-validation replaces tests
47. Domain modelling?
// Object oriented style
type Observation = {
Search: string
Product: string }
with member this.SearchLength =
this.Search.Length
// Properties as functions
type Observation = {
Search: string
Product: string }
let searchLength (obs:Observation) =
obs.Search.Length
// "object" as a bag of functions
let model = [
fun obs -> searchLength obs
]
49. Recap
• F# Types to model Domain with common “language”
across scripts
• Separate code elements by role, to enable focusing on
high value activity, the creation of features
51. Reproducible research
• Anyone must be able to re-compute everything, from
scratch
• Model is meaningless without the data
• Don’t tamper with the source data
• Script everything
52. Analogy: Source Control + Automated Build
If I check out code from source control,
it should work.
53. One simple main idea:
does the Search query look like the Product?
54. Dataset normalization
• “ductless air conditioners”, “GREE Ultra
Efficient 18,000 BTU (1.5Ton) Ductless
(Duct Free) Mini Split Air Conditioner with
Inverter, Heat, Remote 208-230V”
• “6 inch damper”,”Battic Door Energy
Conservation Products Premium 6 in. Back
Draft Damper”,
• “10000 btu windowair conditioner”, “GE
10,000 BTU 115-Volt Electronic Window Air
Conditioner with Remote”
62. General
• Don’t be religious about process
• Why do you follow a process?
• Identify where you waste energy
• Build flexibility around volatility
• Automate the repeatable parts
63. Statically typed functional
• Super clean scripts / data pipelines
• Types help define clear domain models
• Types prevent dumb mistakes
64. Open questions
• Better way to version features?
• Experiment is not an entity?
• Is pre-processing a feature?
• Something missing in overall versioning
• Better understanding of data/code dependencies (reuse
computation, …)
65. Shameless plug
I have a book out, “Machine
Learning projects for .NET
developers”, Apress
66. Thank you
@brandewinder /
brandewinder.com
• Come chat if you are interested in
the topic!
• Check out fsharp.org…