简体   繁体   English

OCaml 中的逻辑回归

[英]Logistic Regression in OCaml

I was trying to use Logistic regression in OCaml.我试图在 OCaml 中使用逻辑回归。 I need to use it as a blackbox for another problem I'm solving.我需要将它用作我正在解决的另一个问题的黑盒。 I found the following site:我找到了以下网站:

http://math.umons.ac.be/anum/en/software/OCaml/Logistic_Regression/ http://math.umons.ac.be/anum/en/software/OCaml/Logistic_Regression/

I pasted the following code (with a few modifications - I defined my own iris_features and iris_label) from this site into a file named logistic_regression.ml:我将此站点中的以下代码(进行了一些修改 - 我定义了自己的 iris_features 和 iris_label)粘贴到名为logistic_regression.ml 的文件中:

open Scanf
open Format
open Bigarray
open Lacaml.D

let log_reg ?(lambda=0.1) x y =
  (* [f_df] returns the value of the function to maximize and store
     its gradient in [g]. *)
  let f_df w g =
    let s = ref 0. in
    ignore(copy ~y:g w); (* g ← w *)
    scal (-. lambda) g;  (* g = -λ w *)
    for i = 0 to Array.length x - 1 do
      let yi = float y.(i) in
      let e = exp(-. yi *. dot w x.(i)) in
      s := !s +. log1p e;
      axpy g ~alpha:(yi *. e /. (1. +. e)) ~x:x.(i);
    done;
    -. !s -. 0.5 *. lambda *. dot w w
  in
  let w = Vec.make0 (Vec.dim x.(0)) in
  ignore(Lbfgs.F.max f_df w);
  w


let iris_features = [1 ; 2 ; 3] ;;
let iris_labels = 2 ;;

let proba w x y = 1. /. (1. +. exp(-. float y *. dot w x))
let () =
  let sol = log_reg iris_features iris_labels in
  printf "w = %a\n" Lacaml.Io.pp_fvec sol;
  let nwrongs = ref 0 in
  for i = 0 to Array.length iris_features - 1 do
    let p = proba sol iris_features.(i) iris_labels.(i) in
    printf "Label = %i prob = %g => %s\n" iris_labels.(i) p
      (if p > 0.5 then "correct" else (incr nwrongs; "wrong"))
  done;
  printf "Number of wrong labels: %i\n" !nwrongs

I have the following questions:我有以下问题:

  1. On trying to compile the code, I get the error message: " Error: Unbound module Lacaml ".在尝试编译代码时,我收到错误消息:“ Error: Unbound module Lacaml ”。 I've installed Lacaml;我已经安装了 Lacaml; done opam init several times, tried to provide a flag -package = Lacaml;做了几次 opam init,试图提供一个标志 -package = Lacaml; I don't know how to solve this?我不知道如何解决这个问题?
  2. As you can see I've defined my own version of iris_features and iris_labels - are the types correct ie in the function log_reg is the type of x int list and that of y as int?如您所见,我已经定义了自己的 iris_features 和 iris_labels 版本-类型是否正确,即 function log_reg 中的类型是 x int 列表,而 y 的类型是 int?

Both iris_features and iris_labels are arrays and array literals in OCaml are delimited with the [| iris_featuresiris_labels都是 arrays 并且 OCaml 中的数组文字用[|分隔。 , |] style parentheses, eg, , |]样式括号,例如,


let iris_features = [|(* I don't know what to put here*)|]
let iris_labels = [|2|]

The iris_features array has type vec array , ie, an array of vectors, not an array of integers, and didn't I dig too deep to know what to put there, but the syntax is the following, iris_features数组的类型为vec array ,即一个向量数组,而不是一个整数数组,我是不是挖得太深不知道该放什么,但语法如下,

let iris_features =[|
  Vec.of_list [1.; 2.; 3.;];
  Vec.of_list [4.; 5.; 6.;];
|]

The Lacaml interface has changed a bit since the code was written and axpy no longer accepts labeled ~x arguments (both x and y vectors are positional now) so you need to remove ~x and fix the order (I presume that x.(i) is x in the a*x + y expression and g corresponds to y , eg,自从编写代码以来,Lacaml 接口发生了一些变化,并且axpy不再接受标记为~x arguments (x 和 y 向量现在都是位置的)所以你需要删除~x并修复顺序(我假设x.(i)a*x + y x中的 x 并且g对应于y ,例如,

 axpy ~alpha:(yi *. e /. (1. +. e)) x.(i) g;

This code also depends on lbfgs , so you need to install it as well,这段代码也依赖于lbfgs ,所以你也需要安装它,

opam depext --install lbfgs

I would suggest you using dune as your default built system but for fast prototyping, you can use ocamlbuild .我建议您使用dune作为您的默认构建系统,但对于快速原型设计,您可以使用ocamlbuild Put your code into an empty folder in a file named regress.ml (you can pick other name, just update the build instructions correspondingly), now you can build it to a native executable, as将您的代码放入名为regress.ml的文件中的空文件夹中(您可以选择其他名称,只需相应地更新构建指令),现在您可以将其构建为本机可执行文件,如

ocamlbuild -pkg lacaml -pkg lbfgs regress.native

run it as运行它

./regress.native

If you're playing in the OCaml toplevel (aka interpreter, ie, running your code in the ocaml interpreter), you can load lacaml and lbfgs using the following two directives:如果你在 OCaml 顶层(又名解释器,即在ocaml解释器中运行你的代码),你可以使用以下两个指令加载lacamllbfgs

#use "topfind";;
#require "lacaml.top";;
#require "lbfgs";;

(The # is not a prompt but a part of the directive syntax, so don't forget to type it as well). #不是提示符,而是指令语法的一部分,所以不要忘记键入它)。

Now you can copy-paste your code into the interpreter and play with it.现在您可以将代码复制粘贴到解释器中并使用它。

Bonus Track - building with dune奖励轨道 - 用沙丘建造

  1. create an empty folder and a put regress.ml there.创建一个空文件夹并在那里放置regress.ml
  2. remove open Bigarray and open Scanf as dune is very strict on warnings and turns them into errors (and it will warn you on those lines as they are, in fact, unused)删除open Bigarrayopen Scanf Scanf 因为 dune 对警告非常严格并将它们变成错误(它会在这些行上警告你,因为它们实际上是未使用的)
  3. create the dune project创建沙丘项目
dune init exe regress --libs lacaml,lbfgs
  1. build and run构建并运行
dune exec ./regress.exe

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM