anchor.diff:  #r "../packages/Accord.Math/lib/net40/Accord.Math.dll"
   #r "../packages/Accord.Statistics/lib/net40/Accord.Statistics.dll"
   #r "../packages/FSharp.Collections.ParallelSeq/lib/net40/FSharp.Collections.ParallelSeq.dll"
  +#r "../packages/StemmersNet/lib/net20/StemmersNet.dll"
   
   open System
   open System.IO
  
positive.code:     |> Map.ofSeq
  let inline productDescription uid = productDescMap |> Map.find uid
  
  (* wordMatch needs to have a fuzzy match
     The sample R script uses a regex like this:
     pattern <- paste("(^| )",words[i],"($| )",sep="") *)
  let wordMatch (words:string) (title:string) (desc:string) =
      let isMatch input word = // TODO should stem words, e.g. "angles" -> "angle"
          Regex.IsMatch(input, sprintf @"\b%s\b" (Regex.Escape word), RegexOptions.IgnoreCase)
      let words' = words.Split([|' '|], StringSplitOptions.RemoveEmptyEntries)
      let uniqueWords = words' |> Array.distinct
      let numberInTitle = uniqueWords |> Array.filter (isMatch title) |> Array.length
      let numberInDescription = uniqueWords |> Array.filter (isMatch desc) |> Array.length
      numberInTitle, numberInDescription, uniqueWords.Length 
  
negative.code: open FSharp.Data
  open FSharp.Collections.ParallelSeq
  open Accord.Statistics.Models.Regression.Linear
  open Iveonik.Stemmers
  
  [<Literal>]
  let trainDataPath = "../data/train.csv"
  