2013-11-02 1 views
1

Я пытаюсь выполнить скрипт F #, который я скопировал из http://www.clear-lines.com/blog/post/Nearest-Neighbor-Classification-Part-2.aspx как fs-программу, а не скрипт. Я загрузил все библиотеки, которые я использую, и проверил их в других контекстах, и все они работают. Он компилирует правильно и сортирует файл CSV в массив, но он не выполняет после:Программа F # не работает до завершения

let labels = fileAsLines |> Array.map (fun line -> line.[4]) 
dataset, labels 

Спасибо заранее за любую помощь, я читал и используя этот форум часто и оценить все указания.

// Learn more about F# at http://fsharp.net 
// Code from http://www.clear-lines.com/blog/post/Nearest-Neighbor-Classification-part-2.aspx 

open MicrosoftResearch.Infer.Fun.FSharp.Syntax 
open MicrosoftResearch.Infer.Fun.FSharp.Inference 
open MicrosoftResearch.Infer.Fun.Lib 
open MicrosoftResearch.Infer.Maths 
open System.IO 
open System 
open System.Drawing 
open MSDN.FSharp.Charting 

let distance v1 v2 = 
    Array.zip v1 v2 
    |> Array.fold (fun sum e -> sum + pown (fst e - snd e) 2) 0.0|> sqrt 

let classify subject dataset labels k = 
    dataset 
    |> Array.map (fun row -> distance row subject) 
    |> Array.zip labels 
    |> Array.sortBy snd 
    |> Array.toSeq 
    |> Seq.take k 
    |> Seq.groupBy fst 
    |> Seq.maxBy (fun g -> Seq.length (snd g)) 
let column (dataset: float [][]) i = 
     dataset |> Array.map (fun row -> row.[i]) 

let columns (dataset: float [][]) = 
    let cols = dataset.[0] |> Array.length 
    [| for i in 0 .. (cols - 1) -> column dataset i |] 

let minMax dataset = 
    dataset 
    |> columns 
    |> Array.map (fun col -> Array.min(col), Array.max(col)) 

let minMaxNormalizer dataset = 
    let bounds = minMax dataset 
    fun (vector: float[]) -> 
     Array.mapi (fun i v -> 
      (vector.[i] - fst v)/(snd v - fst v)) bounds 

let normalize data (normalizer: float[] -> float[]) = 
    data |> Array.map normalizer 

let classifier dataset labels k = 
    let normalizer = minMaxNormalizer dataset 
    let normalized = normalize dataset normalizer 
    fun subject -> classify (normalizer(subject)) normalized labels k 

let elections = 
    let file = @"C:\Users\Jessica\Dataset\Election2008.txt" 
    let fileAsLines = 
     File.ReadAllLines(file) 
      |> Array.map (fun line -> line.Split(',')) 
    let dataset = 
     fileAsLines 
     |> Array.map (fun line -> 
      [| Convert.ToDouble(line.[1]); 
       Convert.ToDouble(line.[2]); 
       Convert.ToDouble(line.[3]) |]) 
    let labels = fileAsLines |> Array.map (fun line -> line.[4]) 
    dataset, labels 

let evaluate dataset (labels: string []) k prop = 
    let size = dataset |> Array.length 
    let sample = floor ((float)size * prop) |> (int) 
    let testSubjects, testLabels = dataset.[0 .. sample-1], labels.[0..sample-1] 
    let trainData = dataset.[sample .. size-1], labels.[sample .. size-1] 
    let c = classifier (fst trainData) (snd trainData) k 
    let results = 
     testSubjects 
     |> Array.mapi (fun i e -> fst (c e), testLabels.[i]) 
    results 
    |> Array.iter (fun e -> printfn "%s %s" (fst e) (snd e)) 
    let correct = 
     results 
     |> Array.filter (fun e -> fst e = snd e) 
     |> Array.length 
    printfn "%i out of %i called correctly" correct sample 

ответ

2

Причина код внутри let elections блока выполняется в том, что она определяется как значение, а не функция (она не принимает никаких аргументов, ни блок ()). Это означает, что он выполнен , как указано.

Единственный код, который появляется после этого в вашем скрипте, объявляет функцию (она называется evaluate; она выглядит аналогичной, но она принимает аргументы и, следовательно, не выполняется, если только что-то не вызывает ее и не предоставляет необходимые аргументы), но вы не иметь любой код, который его вызывает.

Я считаю, что легкие изменения, чтобы сделать это делать то, что я думаю, что вы пытаетесь сделать это:

  1. Удалите k и prop аргументы с конца функции evaluate (это, кажется, не можно использовать)
  2. в самом конце сценария, вызовите метод evaluate со значениями, хранящимися в elections, как это:

    let dataset, labels = elections

    evaluate dataset labels

Это, вероятно, имеет смысл перестроить код немного, потому что кажется, немного сбивает с толку, что у вас есть код выполняется во время объявления elections, но как только вы получили код может быть проще реструктурировать и понять, что происходит.