Beispiel #1
0
        /// <summary>
        /// 線形判別分析
        /// </summary>
        /// <param name="Xs">
        /// <para>各郡の Matrix オブジェクト (行がデータ,列が変数に対応する) の配列</para>
        /// <para>
        /// 1 つの群データは 1 つの Matrix で表される.
        /// 本処理により書き換えられることはない (read-only).
        /// </para>
        /// </param>
        public static Lda Lda(Matrix[] Xs)
        {
            int C = Xs.Length;           // 群数

            int[] ns = new int[C];       // 各群のデータ数
            int   p  = Xs[0].ColumnSize; // 次元数

            // 各郡のデータ数を取得
            for (int k = 0; k < C; ++k)
            {
                ns[k] = Xs[k].RowSize;
            }

            Vector tAvg = new Vector(new Size(p));    // 全データにおける各次元の平均値

            tAvg.Zero();

            int tN = 0;                    // 全データ数

            Vector[] avgs = new Vector[C]; // 各群における各次元の平均値
            for (int k = 0; k < C; ++k)
            {
                tN     += Xs[k].RowSize;
                avgs[k] = Xs[k].ColumnAverages;
                tAvg.Apply((int i, double val) => val + Xs[k].Columns[i].Sum);
            }
            tAvg /= tN;

            Matrix B = new Matrix(p, p);

            for (int k = 0; k < C; ++k)
            {
                IVector dv = avgs[k] - tAvg;
                B += (ns[k] * new ColumnVector(dv) * new RowVector(dv));
            }
            B /= (C - 1);

            Matrix W = new Matrix(p, p);

            for (int k = 0; k < C; ++k)
            {
                for (int i = 0; i < ns[k]; ++i)
                {
                    IVector dv = Xs[k].Rows[i] - avgs[k];
                    W += (new ColumnVector(dv) * new RowVector(dv));
                }
            }
            W /= (tN - C);

            Eigen evd = Eigen(Matrix.Inverse(W) * B);

            evd.Sort(KrdLab.Lisys.Eigen.SortOrder.Descending);
            return(new Lda(evd.RealEigenvalues, evd.RealEigenvectors, avgs.ToList()));
        }
Beispiel #2
0
        /// <summary>
        /// 主成分分析
        /// </summary>
        /// <param name="data">
        /// [n, d] の行列(データ数:n,次元数:d,書き換えられることはない)
        /// </param>
        /// <param name="cor">
        /// 相関行列で分析するかどうか (デフォルトは <c>false</c> = 分散・共分散行列)
        /// </param>
        public static Pca Pca(Matrix data, bool cor = false)
        {
            Matrix x = new Matrix(data);
            Matrix s;

            if (cor)
            {
                s = Correlate(x, Target.EachColumn);
            }
            else
            {
                // 各変数の平均値を 0 にする
                Vector colAvgs = x.ColumnAverages;
                x.Columns.ForEach((c, vec) => vec.Apply((i, val) => val - colAvgs[c]));
                // 分散・共分散行列
                s = Matrix.Transpose(x) * x / (x.RowSize - 1);
            }
            // 固有値分解
            Eigen evd = Eigen(s);

            evd.Sort(KrdLab.Lisys.Eigen.SortOrder.Descending);
            // 対称行列の固有値は全て実数
            return(new Pca(evd.RealEigenvalues, evd.RealEigenvectors));
        }