Exemple #1
0
        public KAverageMethod(STATND statNd, int k, IKFirstPointsSelector KFirstPointsSelector)
        {
            m_clasters = new Claster[k];
            m_k        = k;

            m_data = statNd.getJaggedArrayOfData();
            m_N    = m_data.GetLength(0);

            double[][] centers = KFirstPointsSelector.GetFirstKPoints(m_data, k);

            for (int i = 0; i < k; i++)
            {
                m_clasters[i] = new Claster(centers[i]);
            }
        }
        public static RegressionResult FindParamsForNDim(STATND stats, int[] Xindexes, int Yindex, double alpha, Chart diagnosticdiagram)
        {
            #region Подготовка
            //размерность иксов
            int n = Xindexes.Length;

            //собраем все STAT-ы по указанным индексам
            List <STAT> XStats = Xindexes.Select(index => stats.GetStat(index)).ToList();

            //средние по каждому измерению
            double[] AverageArray = XStats.Select(stat => stat.Expectation).ToArray();

            //вектор средних
            Vector AverageVector = new Vector(AverageArray);

            //значения из многомерной выборки, по нужным индексам
            List <Vector> XVectorLst = XStats.Select(stat => new Vector(stat.d)).ToList();

            //отнимаем среднее от каждой колонки
            for (int i = 0; i < n; i++)
            {
                XVectorLst[i] -= AverageVector[i];
            }

            //образуем из значений иксов матрицу
            Matrix XMatrix = Matrix.Create.JoinVectors(XVectorLst);

            //работа с игреком
            STAT yStat = stats.GetStat(Yindex);

            double YExpectation = yStat.Expectation;
            Vector YVector      = new Vector(yStat.d);

            Vector Y0 = YVector - YExpectation;
            #endregion

            //мое обозначение
            Matrix A = XMatrix;//= XMatrix.MultiplyOnVectorRow(AverageVector); // не множить а минусовать

            Matrix ATranspose = A.Transpose();

            //ищем an без а0
            var res = ((ATranspose * A).Inverse() * ATranspose).MultiplyOnVectorColumn(Y0);

            //ищем свободный член а0
            double a0 = YExpectation;

            for (int i = 0; i < n; i++)
            {
                a0 -= res[i] * AverageVector[i];
            }

            //расширенный список результатов с а0
            List <double> extendedResultLst = res.GetCloneOfData().ToList();

            extendedResultLst.Insert(0, a0);

            Vector ExtendedparamsVector = Vector.Create.New(extendedResultLst.ToArray());

            //новый метод
            FillDiagnosticDiagram(diagnosticdiagram, Xindexes.Select(index => stats.GetStat(index)).ToList(), stats.GetStat(Yindex), a0, res.GetCloneOfData());

            return(GetConfidenceIntervalsOnRegressionParametrs(alpha, n, XStats, yStat, YVector, ExtendedparamsVector));
        }
        private static RegressionResult GetConfidenceIntervalsOnRegressionParametrs(double alpha, int n, List <STAT> XStats, STAT yStat, Vector YVector, Vector ExtendedparamsVector)
        {
            //это величина доьавлением/отниманием которой получаются доверительные интервалы на параметры регресии
            double[] confidenceValues = new double[n + 1];

            //берем исходные иксы
            List <Vector> XInputVectors = XStats.Select(stat => new Vector(stat.d)).ToList();

            //добавляю игрекв первую колонку
            XInputVectors.Insert(0, YVector);

            Matrix X = Matrix.Create.JoinVectors(XInputVectors);

            //ищем квантиль
            int    N  = XStats[0].d.Length * n;
            int    Nu = N - n; //по формуле N-n
            double kv = Kvantili.Student(alpha, Nu);

            //коэф детерминации
            XStats.Add(yStat);                                       //добавляем y к иксам, чтобы получить общую матрицу

            STATND STATNDForR        = new STATND(XStats.ToArray()); //заносим полученную матрицу в многомерный анализ
            double MultipleR         = STATNDForR.GetMultipleR(n);
            double DeterminationCoef = MultipleR * MultipleR;

            //ищем остаточную дисперсию и сигму
            double S2    = (double)(N - 1) / (N - n) * yStat.Dispersia * (1 - DeterminationCoef);
            double sigma = Math.Sqrt(S2);

            //значимость параметров
            string[] paramsState = new string[7];
            double   KvForParams = Kvantili.Student(alpha, N - n);

            //ищем сkk
            Matrix C = (X.Transpose() * X).Inverse();

            for (int i = 0; i < n + 1; i++)
            {
                //дл интервальных оценок
                double Ckk = C[i, i];
                confidenceValues[i] = kv * sigma * Math.Sqrt(Ckk);

                //проверка параметров регрессии на значимость
                paramsState[i] = Math.Abs(ExtendedparamsVector[i] / (sigma * Math.Sqrt(Ckk))) <= KvForParams? "не значущий": "Значущий";
            }

            //переносим из массива в вектор
            Vector ConfidenceVector = new Vector(confidenceValues);

            //доверительные границы
            Vector topLimits    = ExtendedparamsVector + ConfidenceVector;
            Vector bottomLimits = ExtendedparamsVector - ConfidenceVector;

            //проверка значимости регрессии
            string state                  = "";
            double f                      = (double)(N - n - 1) / n * DeterminationCoef * DeterminationCoef / (1 - DeterminationCoef * DeterminationCoef);
            int    Nu1                    = n;
            int    Nu2                    = N - n - 1;
            Func <double, double> r       = v => Math.Round(v, 4);
            Action <string>       Add2Log = s => state += s + Environment.NewLine;

            Add2Log("f = " + r(f));
            Add2Log("kv = " + r(kv));
            if (f > kv)
            {
                Add2Log("f > kv");
                Add2Log("Регресійна модель Значуща");
            }
            else
            {
                Add2Log("f <= kv");
                Add2Log("Регресійна модель НЕ Значуща");
            }

            //Интервалы дисперсии
            double nominator  = S2 * (N - n);
            double TopDisp    = nominator / Kvantili.Hi2((2d - alpha) / 2, N - n);
            double BottomDisp = nominator / Kvantili.Hi2(-alpha / 2d, N - n);

            string disprsionIntervals = String.Format("{0}<={1}<={2}", r(BottomDisp), r(S2), r(TopDisp));

            RegressionResult result = new RegressionResult()
            {
                BotoomConfidenceLimits = bottomLimits,
                RegressionParams       = ExtendedparamsVector,
                TopConfidenceLimits    = topLimits,
                R                   = DeterminationCoef,
                state               = state,
                ParamsState         = paramsState,
                DispersionIntervals = disprsionIntervals
            };

            return(result);
        }
        //равенство двух многомерных средних в случае равных ДК
        public static string ComparingTwoNdimAverage(STATND xStat, STATND yStat, double alpha)
        {
            //проверки
            if (!xStat.CheckingLengthOfStats())
            {
                throw new ChekingLengthOfStatsException("xStat");
            }
            if (!yStat.CheckingLengthOfStats())
            {
                throw new ChekingLengthOfStatsException("yStat");
            }

            int nLen1 = xStat.N;
            int nLen2 = yStat.N;

            if (nLen1 != nLen2)
            {
                throw new DIfferentDimentionsLengthException();
            }
            //конец проверок

            //вынос нужных переменных
            int N1 = xStat.GetStat(0).d.Length;  //длинна всех признаков по иксу
            int N2 = yStat.GetStat(0).d.Length;  //длинна всех признаков по y
            int n  = nLen1;                      //количество признаков (должно быть одинаковым для x и y)

            double[][] S0 = ArrayMatrix.GetJaggedArray(n, n);
            double[][] S1 = ArrayMatrix.GetJaggedArray(n, n);

            //лямбды для удобного получения x и y
            Func <int, int, double> x = (NumberOfDim, NumberOfElementInDim) => xStat.GetStat(NumberOfDim).d[NumberOfElementInDim];
            Func <int, int, double> y = (NumberOfDim, NumberOfElementInDim) => yStat.GetStat(NumberOfDim).d[NumberOfElementInDim];

            //лямбды для получения суммы
            Func <int, double> xSum = NumberOfDim => xStat.GetStat(NumberOfDim).d.Sum();
            Func <int, double> ySum = NumberOfDim => yStat.GetStat(NumberOfDim).d.Sum();

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double CommonDenominator = N1 + N2 - 2;

                    double S0Temp = 0;
                    double S1Temp = 0;

                    //по формулам
                    for (int l = 0; l < N1; l++)
                    {
                        S0Temp += x(i, l) * x(j, l);
                    }

                    for (int l = 0; l < N2; l++)
                    {
                        S0Temp += y(i, l) * y(j, l);
                    }

                    S1Temp = S0Temp; //до этого места формулы одинаковые

                    //подсчет частей, которые отличаются
                    S0Temp -= ((xSum(i) + ySum(i)) * (xSum(j) + ySum(j))) / (N1 + N2);

                    S1Temp -= (xSum(i) * xSum(j)) / N1;
                    S1Temp -= (ySum(i) * ySum(j)) / N2;

                    //перенос значений в матрицу
                    S0[i][j] = S0Temp / CommonDenominator;
                    S1[i][j] = S1Temp / CommonDenominator;
                }
            }

            //перенос значений в сложный тип - матрицу(для нахождения определителей)
            Matrix S0Matrix = new Matrix(S0);
            Matrix S1Matrix = new Matrix(S1);

            //подсчет статистики
            double V = N1 + N2 - 2 - n / 2d;

            V *= Math.Log(Math.Abs(S1Matrix.Determinant() / S0Matrix.Determinant()));

            //для удобства
            string resultStr               = "";
            Func <double, double> r        = val => Math.Round(val, 4);
            Action <string>       mess2log = str => resultStr += str + Environment.NewLine;

            //делаем выводы
            double kv = Kvantili.Hi2(alpha, n);

            mess2log("V = " + r(V));
            mess2log("kv = " + r(kv));

            if (V <= kv)
            {
                //гипотезу принято;//средние совпадают
                mess2log("V<kv");
                mess2log("Гіпотезу прийнято!");
                mess2log("Середні співпадають!");
            }
            else
            {
                //гипотезу не принято
                mess2log("V>kv");
                mess2log("Гіпотезу НЕ прийнято!");
                mess2log("Середні НЕ співпадають!");
            }

            return(resultStr);
        }