C#でMath.NET Numericsを使用する(統計計算編2)

前回の続き。

前回のコードを見て多くの方が「何これ超手続きイケテナイ」あるいは「対リスト操作なのになんでメソッドチェーンできないんですかっ!」と思われていることでしょう。

そんな皆さんに朗報です。宣言的な書き方、拡張メソッドでの使用が用意されています。

まず、宣言的な書き方ですが、実際には前回のStatisiticsクラスと等価ではないものの、ほぼ同様の機能を持ったDescriptiveStatisticsクラスが用意されています。しかしそのまんまなクラス名です。

以下はコード例。

//宣言的に記述する
Console.WriteLine("宣言的な記述をするためにDescriptiveStatisticsクラスを使用する。");
            
var stat = new DescriptiveStatistics(data); //重い!
//標準偏差
Console.WriteLine("Standard Deviation = {0}", stat.StandardDeviation);
//平均
Console.WriteLine("Mean = {0}", stat.Mean);
//メジアン
Console.WriteLine("Median = {0}", stat.Median);
//分散
Console.WriteLine("Variance = {0}", stat.Variance);
//歪度
Console.WriteLine("Skewness = {0}", stat.Skewness);
//尖度
Console.WriteLine("Kurtosis = {0}", stat.Kurtosis);

という風に宣言的に記述できます。ただ、Statisticには無い関数がこちらには存在したり、こちらには無い関数がStatisticクラスには存在したりするので、ドキュメントで違いを確認しておきましょう。

皆さんがメソッドチェーンを愛してやまないのは知っています。

それなので、Statisticクラスには前回紹介した関数と同じ内容の拡張メソッドが用意されています。

//拡張メソッドを使用する
Console.WriteLine("\r\nStatisticsクラスのメソッドを拡張メソッドとして使用する。");
//標準偏差
Console.WriteLine("Standard Deviation = {0}", data.StandardDeviation());
//母標準偏差
Console.WriteLine("Population Standard Deviation = {0}", data.PopulationStandardDeviation());
//標本分散
Console.WriteLine("Variance = {0}", data.Variance());
//メジアン(中央値)
Console.WriteLine("Median = {0}", data.Median());
//順序統計量
//Console.WriteLine("Order Statisitc(i-Order = 123) = {0}", data.OrderStatistic(123));
//OrderStatisticは拡張メソッドに対応していない。

上にあるようにOrderStatisticのように拡張メソッドが用意されていない場合もありますので、注意が必要です。

ということで、ちょっと注意点はあるものの、Math.NET Numericsではだいぶモダンなコードの書き方出来るようになっています。

全体コードは以下の通りです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathNet.Numerics.Statistics;

namespace MathNetStatisticsSample2
{
    class Program
    {
        static void Main(string[] args) {
            var rnd = new System.Random();
            double[] data = new double[10000000];

            int i;
            for (i = 0; i < 10000000; i++) {
                data[i] = rnd.NextDouble();
            }

            //宣言的に記述する
            Console.WriteLine("宣言的な記述をするためにDescriptiveStatisticsクラスを使用する。");
            
            var stat = new DescriptiveStatistics(data); //重い!
            //標準偏差
            Console.WriteLine("Standard Deviation = {0}", stat.StandardDeviation);
            //平均
            Console.WriteLine("Mean = {0}", stat.Mean);
            //メジアン
            Console.WriteLine("Median = {0}", stat.Median);
            //分散
            Console.WriteLine("Variance = {0}", stat.Variance);
            //歪度
            Console.WriteLine("Skewness = {0}", stat.Skewness);
            //尖度
            Console.WriteLine("Kurtosis = {0}", stat.Kurtosis);

            //以上のようにDescriptiveStatisticsクラスはStatisticsとは1:1ではないので注意が必要

            //拡張メソッドを使用する
            Console.WriteLine("\r\nStatisticsクラスのメソッドを拡張メソッドとして使用する。");
            //標準偏差
            Console.WriteLine("Standard Deviation = {0}", data.StandardDeviation());
            //母標準偏差
            Console.WriteLine("Population Standard Deviation = {0}", data.PopulationStandardDeviation());
            //標本分散
            Console.WriteLine("Variance = {0}", data.Variance());
            //メジアン(中央値)
            Console.WriteLine("Median = {0}", data.Median());
            //順序統計量
            //Console.WriteLine("Order Statisitc(i-Order = 123) = {0}", data.OrderStatistic(123));
            //OrderStatisticは拡張メソッドに対応していない。

            Console.Write("何か入力してください...");
            Console.Read();
        }
    }
}

※通常本サイトで公開されるソースコードライセンスはApache License v2.0ですが、上コードについてはMITライセンスとします。

上のサンプルコードはGitHubにて公開しています。
https://github.com/ishisaka/MathNetSample

コメントを残す