Можно ли отлаживать F # или, как LINQ в C#, это фактически невозможно?
Я работаю над проектами машинного обучения для. NET разработчиков и я впервые использую F #.
Я попытался отредактировать пример упражнения. Версию C# было легко запустить, но моя попытка с версией F # просто зависла.
Что я могу сделать, чтобы отследить проблему?
open System.IO
type Observation = { Label:string; Pixels: int[] }
type Distance = int[] * int[] -> int
type Classifier = int[] -> string
let toObservation (csvData:string) =
let columns = csvData.Split(',')
let label = columns.[0]
let pixels = columns.[1..] |> Array.map int
{ Label = label; Pixels = pixels }
let reader path =
let data = File.ReadAllLines path
data.[1..]
|> Array.map toObservation
let trainingPath = __SOURCE_DIRECTORY__ + @"../../Data/trainingsample.csv"
let training = reader trainingPath
let manhattanDistance (pixels1,pixels2) =
Array.zip pixels1 pixels2
|> Array.map (fun (x,y) -> abs (x-y))
|> Array.sum
let euclideanDistance (pixels1,pixels2) =
Array.zip pixels1 pixels2
|> Array.map (fun (x,y) -> pown (x-y) 2)
|> Array.sum
let dotCountDistance(pixels1, pixels2) =
let t1 = pixels1 |> Array.map (fun(z) -> if z > 128 then 1 else 0) |> Array.sum
let t2 = pixels2 |> Array.map (fun(z) -> if z > 128 then 1 else 0) |> Array.sum
abs(t1 - t2)
let train (trainingset:Observation[]) (dist:Distance) =
let classify (pixels:int[]) =
trainingset
|> Array.minBy (fun x -> dist (x.Pixels, pixels))
|> fun x -> x.Label
classify
//
// This is my new function
//
let train2 (trainingset:Observation[]) (dist:Distance) =
let classify (pixels:int[]) =
trainingset
|> Array.map (fun(z) -> dist(z.Pixels, pixels), z.Label)
|> Array.groupBy(fun (a, y) -> y)
|> Array.map(fun (lbl, ds) -> lbl, (ds |> Array.map(fun (p, q) -> p) |> Array.sum ) * 100 / (ds |> Array.length))
|> Array.sortByDescending( fun (lbl, s) -> s)
|> fun z -> z.[0]
|> fun (lbl, s) -> lbl
classify
//
//
//
let validationPath = __SOURCE_DIRECTORY__ + @"../../Data/validationsample.csv"
let validation = reader validationPath
let evaluate validationSet classifier =
validationSet
|> Array.averageBy (fun x -> if classifier x.Pixels = x.Label then 1. else 0.)
|> printfn "Correct: %.3f"
let manhattanModel = train training manhattanDistance
let euclideanModel = train training euclideanDistance
let dotCountModel = train training dotCountDistance
let manhattanModel2 = train2 training manhattanDistance
let euclideanModel2 = train2 training euclideanDistance
let dotCountModel2 = train2 training dotCountDistance
printfn "Manhattan"
evaluate validation manhattanModel // <------------------- This just hangs.
printfn "Euclidean"
evaluate validation euclideanModel
printfn "Dot Count"
evaluate validation dotCountModel
// Illustration: full distance function
let d (X,Y) =
Array.zip X Y
|> Array.map (fun (x,y) -> pown (x-y) 2)
|> Array.sum
|> sqrt
Вот, y C# версия, которая работает
return data.Select(z => new { z.Label, D = distance.Between(z.Pixels, pixels) })
.GroupBy(z => z.Label)
.Select(z => new { Label = z.Key, MeanDistance = z.Average(y => y.D) })
.OrderBy(z => z.MeanDistance).First()
.Label;