【问题标题】:F# Program is Not Running to CompletionF# 程序未运行完成
【发布时间】:2013-11-02 04:56:46
【问题描述】:

我正在尝试将我从http://www.clear-lines.com/blog/post/Nearest-Neighbor-Classification-Part-2.aspx 复制的 F# 脚本作为 fs 程序而不是脚本执行。我已经下载了我正在使用的所有库,并在其他环境中对其进行了测试,它们都可以正常工作。它可以正确编译并将 csv 文件排序到一个数组中,但它不会在之后执行:

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

【问题讨论】:

    标签: algorithm f# k-means


    【解决方案1】:

    let elections 块中的代码被执行的原因是它被定义为一个值而不是一个函数(它不接受任何参数,也没有单位 ())。这意味着它在声明时执行

    脚本中唯一出现在此之后的代码声明了一个函数(称为evaluate;它看起来很相似,但它接受参数,因此除非有人调用它并提供所需的参数,否则不会执行),但你这样做了没有任何调用它的代码。

    我认为最简单的更改是:

    1. 从函数 evaluate 的末尾删除 kprop 参数(这些似乎没有使用)
    2. 在脚本的最后,使用您存储在elections 中的值调用evaluate 方法,如下所示:

      let dataset, labels = elections

      evaluate dataset labels

    稍微重构一下代码可能是有意义的,因为在elections 的声明期间执行代码似乎有点令人困惑,但是一旦你让代码工作,它可能更容易重组并了解正在发生的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 2016-07-22
      • 1970-01-01
      相关资源
      最近更新 更多