简体   繁体   中英

F# library or .Net Numerics equivalent to Python Numpy function

I have the following python Numpy function; it is able to take X, an array with an arbitrary number of columns and rows, and output a Y value predicted by a least squares function.

What is the Math.Net equivalent for such a function?

Here is the Python code:

    newdataX = np.ones([dataX.shape[0],dataX.shape[1]+1])
    newdataX[:,0:dataX.shape[1]]=dataX

    # build and save the model
    self.model_coefs, residuals, rank, s = np.linalg.lstsq(newdataX, dataY)

I think you are looking for the functions on this page: http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearRegression/MultipleRegression.htm

You have a few options to solve :

  • Normal Equations : MultipleRegression.NormalEquations(x, y)

  • QR Decomposition : MultipleRegression.QR(x, y)

  • SVD : MultipleRegression.SVD(x, y)

Normal equations are faster but less numerically stable while SVD is the most numerically stable but the slowest.

You can call numpy from .NET using pythonnet (C# CODE BELOW IS COPIED FROM GITHUB):

The only "funky" part right now with pythonnet is passing numpy arrays. It is possible to convert them to Python lists at the interface, though this reduces performance for some situations.

https://github.com/pythonnet/pythonnet/tree/develop

static void Main(string[] args)
{
  using (Py.GIL()) {
    dynamic np = Py.Import("numpy");
    dynamic sin = np.sin;
    Console.WriteLine(np.cos(np.pi*2));
    Console.WriteLine(sin(5));
    double c = np.cos(5) + sin(5);
    Console.WriteLine(c);
    dynamic a = np.array(new List<float> { 1, 2, 3 });
    dynamic b = np.array(new List<float> { 6, 5, 4 }, Py.kw("dtype", np.int32));
    Console.WriteLine(a.dtype);
    Console.WriteLine(b.dtype);
    Console.WriteLine(a * b);
    Console.ReadKey();
  }
}

outputs:

1.0  
-0.958924274663
-0.6752620892
float64
int32
[  6.  10.  12.]

Here is example using F# posted on github:

https://github.com/pythonnet/pythonnet/issues/112

open Python.Runtime
open FSharp.Interop.Dynamic
open System.Collections.Generic

[<EntryPoint>]
let main argv = 
    //set up for garbage collection?
    use gil = Py.GIL()

    //-----
    //NUMPY
    //import numpy
    let np = Py.Import("numpy")

    //call a numpy function dynamically
    let sinResult = np?sin(5)

    //make a python list the hard way
    let list = new Python.Runtime.PyList()
    list.Append( new PyFloat(4.0) )
    list.Append( new PyFloat(5.0) )

    //run the python list through np.array dynamically
    let a = np?array( list )
    let sumA = np?sum(a) 

    //again, but use a keyword to change the type
    let b = np?array( list, Py.kw("dtype", np?int32 ) )
    let sumAB = np?add(a,b)

    let SeqToPyFloat ( aSeq : float seq ) =
        let list = new Python.Runtime.PyList()
        aSeq |> Seq.iter( fun x -> list.Append( new PyFloat(x)))
        list

    //Worth making some convenience functions (see below for why)
    let a2 = np?array( [|1.0;2.0;3.0|] |> SeqToPyFloat )

    //--------------------
    //Problematic cases: these run but don't give good results
    //make a np.array from a generic list
    let list2 = [|1;2;3|] |> ResizeArray
    let c = np?array( list2 )
    printfn "%A" c //gives type not value in debugger

    //make a np.array from an array
    let d = np?array( [|1;2;3|] )
    printfn "%A" d //gives type not value in debugger

    //use a np.array in a function
    let sumD = np?sum(d)  //gives type not value in debugger
    //let sumCD = np?add(d,d) // this will crash

    //can't use primitive f# operators on the np.arrays without throwing an exception; seems 
    //to work in c# https://github.com/tonyroberts/pythonnet //develop branch
    //let e = d + 1

    //-----
    //NLTK
    //import nltk
    let nltk = Py.Import("nltk")
    let sentence = "I am happy"
    let tokens = nltk?word_tokenize(sentence)
    let tags = nltk?pos_tag(tokens)

    let taggedWords = nltk?corpus?brown?tagged_words()
    let taggedWordsNews = nltk?corpus?brown?tagged_words(Py.kw("categories", "news") )
    printfn "%A" taggedWordsNews

    let tlp = nltk?sem?logic?LogicParser(Py.kw("type_check",true))
    let parsed = tlp?parse("walk(angus)")
    printfn "%A" parsed?argument

    0 // return an integer exit code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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