/// <summary> /// Calcualtes loglikelihood of Gaussian Mixture Distribution /// </summary> /// <param name="observations">Observation seuqnce</param> /// <param name="mixingCoefficients">Mixing coeficients</param> /// <param name="covariances">Array of covariance matrixes</param> /// <param name="mean">Array of mean vectors</param> /// <returns>Loglikelihood</returns> public static double Calculate(double[][] observations, double[] mixingCoefficients, double[][,] covariances, double[][] means) { var N = observations.Length; var K = mixingCoefficients.Length; var D = means[0].Length; var result = 0.0d; var constant = (1 / Math.Pow(Math.Sqrt(2 * Math.PI), D)); for (int n = 0; n < N; n++) { var x = observations[n]; var mixtureResult = 0.0; for (int k = 0; k < K; k++) { var covarianceMatrix = new Matrix(covariances[k]); var covarianceMatrixInverse = covarianceMatrix.Inverse(); var distance = Mahalanobis.Calculate(x, means[k], covarianceMatrixInverse); var prefix = constant * (1 / Math.Sqrt(covarianceMatrix.Determinant)); mixtureResult += mixingCoefficients[k] * prefix *Math.Exp(-0.5 *distance); } result += Math.Log(mixtureResult); } return(result); }
/// <summary> /// 1. Calculate Mahalanobis Distance for exponent factor /// 2. Check if the matrix is semetric /// 3. Check if the matrix is positive and semidifine /// 4. Calculate Inverse matrix /// 5. Check if matrix is Positive definite /// </summary> /// <param name="x">Observation vector</param> /// <returns>Probability</returns> public override double ProbabilityDensityFunction(params double[] x) { var k = x.Length; var sigmaInverse = _matrix.Inverse(); var distance = Mahalanobis.Calculate(x, Mean, sigmaInverse); var constant = (1 / Math.Pow(SqrtPi, k)) * (1 / Math.Sqrt(_matrix.Determinant)); var p = constant * Math.Exp(-0.5 * distance); // This means that the probability is to low (underflow) if (p.EqualsToZero() || double.IsNaN(p)) { p = MINIMUM_PROBABILITY; } // if (p > 1 || p < 0) // { // Debug.Write(Environment.NewLine + "Covariance matrix " + Environment.NewLine); // Debug.Write(_matrix.ToString()); // Debug.Write(Environment.NewLine + "Mean Vector " + Environment.NewLine); // Debug.Write((new Vector(Mean)).ToString()); // Debug.Write(Environment.NewLine + "Observation Vector " + Environment.NewLine); // Debug.Write((new Vector(x)).ToString()); // Debug.Write(Environment.NewLine); // //throw new ApplicationException(string.Format("Probability function value {0} must be in range [0..1]", p)); // } return(p > 1 ? 1 : p); }
public void doc_mahalanobis() { #region doc_mahalanobis_3 // Let's say we would like to compute the Mahalanobis // distance between the two vectors x and y below: double[] x = { 2, 5, 1 }; double[] y = { 4, 2, 2 }; // Using the covariance double[,] covariance = { { 4, 3, 0 }, { 3, 5, 2 }, { 0, 2, 6 } }; // There are multiple ways to create a Mahalanobis // distance. The easiest method by far is by using: var mahalanobis = Mahalanobis.FromCovarianceMatrix(covariance); // Then, you can compute the distance using: double distance = mahalanobis.Distance(x, y); // However, if you need more control over how the covariance matrix // should be inverted, or if you have the precision matrix instead of // the covariance, you can use any of the alternative methods: var fromCholesky = new Mahalanobis(new CholeskyDecomposition(covariance)); var fromSVD = new Mahalanobis(new SingularValueDecomposition(covariance)); var fromPrecision1 = new Mahalanobis(covariance.Inverse()); var fromPrecision2 = Mahalanobis.FromPrecisionMatrix(covariance.Inverse()); // They all should produce equivalent results: double a = fromCholesky.Distance(x, y); double b = fromSVD.Distance(x, y); double c = fromPrecision1.Distance(x, y); double d = fromPrecision2.Distance(x, y); #endregion double expected = Distance.Mahalanobis(x, y, new CholeskyDecomposition(covariance)); Assert.AreEqual(3.5185224171518357, expected, 1e-10); Assert.AreEqual(expected, distance, 1e-10); Assert.AreEqual(distance, a, 1e-10); Assert.AreEqual(distance, b, 1e-10); Assert.AreEqual(distance, c, 1e-10); Assert.AreEqual(distance, d, 1e-10); }
public static double MahalanobisMetrics(int row, int rowToCount) { var columns = GetColumnsWithoutLast(); if (InverseCovarianceMatrix == null) { var matrix = new double[Dt.Rows.Count, columns.Count]; for (int rowC = 0; rowC < Dt.Rows.Count; rowC++) { for (int colC = 0; colC < columns.Count; colC++) { matrix[rowC, colC] = Convert.ToDouble(Dt.Rows[rowC][colC]); } } var covarianceMatrix = matrix.Covariance(); try { InverseCovarianceMatrix = covarianceMatrix.Inverse(); } catch { InverseCovarianceMatrix = covarianceMatrix.PseudoInverse(); } } double[] xValues = new double[columns.Count]; double[] yValues = new double[columns.Count]; for (int a = 0; a < columns.Count; a++) { double x = Convert.ToDouble(Dt.Rows[row][a]); double y = Convert.ToDouble(Dt.Rows[rowToCount][a]); xValues[a] = x; yValues[a] = y; } return(Mahalanobis.FromPrecisionMatrix(InverseCovarianceMatrix).Distance(xValues, yValues)); }
/// <summary> /// Caclulates Loglikelihood of Multivariate Gaussian Distribution /// </summary> /// <param name="observations">Observarion Sequence</param> /// <param name="covariance">Covariance Matrixe</param> /// <param name="mean">Mean Vector</param> /// <returns>Loglikelihood</returns> public static double Calculate(double[][] observations, double[,] covariance, double[] mean) { var N = observations.Length; var D = covariance.GetLength(0); var constant = N * D * 0.5 * Math.Log(2 * Math.PI); var covarianceMatrix = new Matrix(covariance); var covarianceMatrixInverse = covarianceMatrix.Inverse(); var lnCovariance = N * 0.5 * Math.Log(covarianceMatrix.Determinant); var sumObservations = 0.0; for (int n = 0; n < N; n++) { var x = observations[n]; var distance = Mahalanobis.Calculate(x, mean, covarianceMatrixInverse); sumObservations += distance; } return(-constant - lnCovariance - 0.5 * sumObservations); }
public void Calculate_MeanVectorAndCovarianceMatrixAndVector_MahalanobisDistance() { var m = new double[] { 500, 500 }; var x = new double[] { 410, 400 }; var sigma = new double[2, 2]; sigma[0, 0] = 6291.55737; sigma[0, 1] = 3754.32851; sigma[1, 0] = 3754.32851; sigma[1, 1] = 6280.77066; var matrix = new Matrix(sigma); var sigmaInverse = matrix.Inverse(); sigmaInverse[0, 0] = Math.Round(sigmaInverse[0, 0], 5); sigmaInverse[0, 1] = Math.Round(sigmaInverse[0, 1], 5); sigmaInverse[1, 0] = Math.Round(sigmaInverse[1, 0], 5); sigmaInverse[1, 1] = Math.Round(sigmaInverse[1, 1], 5); var d = Mahalanobis.Calculate(x, m, sigmaInverse); Assert.AreEqual(1.825, Math.Round(d, 3)); }
private double[,] mahalanobisMethod() { var mainWindow = (MainWindow)Application.Current.MainWindow; var format = new NumberFormatInfo(); format.NegativeSign = "-"; int i = 0; double[,] distances = new double[mainWindow.gridData.Rows.Count, mainWindow.gridData.Rows.Count]; double[,] table = new double[mainWindow.gridData.Rows.Count, mainWindow.gridData.Columns.Count - 1]; //double[,] table = new double[5,3]; //table[0, 0] = 64; //table[0, 1] = 580; //table[0, 2] = 29; //table[1, 0] = 66; //table[1, 1] = 570; //table[1, 2] = 33; //table[2, 0] = 68; //table[2, 1] = 590; //table[2, 2] = 37; //table[3, 0] = 69; //table[3, 1] = 660; //table[3, 2] = 46; //table[4, 0] = 73; //table[4, 1] = 600; //table[4, 2] = 55; foreach (DataRow row in mainWindow.gridData.Rows) { for (int j = 0; j < mainWindow.gridData.Columns.Count - 1; j++) { var value = mainWindow.gridData.Rows[i][j].ToString(); if (value.StartsWith(",") || value.StartsWith(".")) { value = "0" + value; } table[i, j] = Convert.ToDouble(value, format); } i++; } double[] d = new double[mainWindow.gridData.Columns.Count - 1]; double[,] diff = new double[1, mainWindow.gridData.Columns.Count - 1]; double[,] diffT = null; double[,] covarMatrix = table.Covariance(); double[,] inverseCovarMatrix = null; double[,] tmp = null; double[,] squaredDist = null; try { inverseCovarMatrix = covarMatrix.Inverse(); } catch (Exception exp) { inverseCovarMatrix = covarMatrix.PseudoInverse(); } var mahalanobis = Mahalanobis.FromPrecisionMatrix(inverseCovarMatrix); List <double> X = new List <double>(); List <double> Y = new List <double>(); for (int k = 0; k < mainWindow.gridData.Rows.Count; k++) { for (int n = 0; n < mainWindow.gridData.Rows.Count; n++) { if (k == n) { distances[k, n] = 0; } else { X.Clear(); Y.Clear(); for (int j = 0; j < mainWindow.gridData.Columns.Count - 1; j++) { var valueK = mainWindow.gridData.Rows[k][j].ToString(); if (valueK.StartsWith(",") || valueK.StartsWith(".")) { valueK = "0" + valueK; } var valueN = mainWindow.gridData.Rows[n][j].ToString(); if (valueN.StartsWith(",") || valueN.StartsWith(".")) { valueN = "0" + valueN; } //d[j] = Convert.ToDouble(valueK, format) - Convert.ToDouble(valueN, format); // diff[0, j] = d[j]; X.Add(Convert.ToDouble(valueK, format)); Y.Add(Convert.ToDouble(valueN, format)); } //diffT = Transpose(diff); // covarMatrix = table.Covariance(); //try //{ // inverseCovarMatrix = covarMatrix.Inverse(); //} //catch(Exception exp) //{ // inverseCovarMatrix = covarMatrix.PseudoInverse(); //} //var mahalanobis = Mahalanobis.FromPrecisionMatrix(inverseCovarMatrix); double result = mahalanobis.Distance(X.ToArray(), Y.ToArray()); //tmp = MultiplyMatrix(diff, inverseCovarMatrix); //squaredDist = MultiplyMatrix(tmp, diffT); //double result = Math.Sqrt(squaredDist[0, 0]); if (Double.IsNaN(result)) { distances[k, n] = 0; } else { distances[k, n] = result; } } } } return(distances); }
public KAverageWindow() { InitializeComponent(); mainWindow = (MainWindow)Application.Current.MainWindow; metrics = new List <string>() { "metryka euklidesowa", "metryka Manhattan", "metryka Czebyszewa", "metryka Mahalanobisa" }; metricsComboBox.ItemsSource = metrics; distinctClasses = (from row in mainWindow.gridData.AsEnumerable() select row.Field <string>(mainWindow.gridData.Columns[mainWindow.gridData.Columns.Count - 1].ColumnName)).Distinct().ToList(); copiedTable = mainWindow.gridData.Copy(); copiedTable.Columns.RemoveAt(copiedTable.Columns.Count - 1); for (int z = 0; z < copiedTable.Rows.Count; z++) { var newRow = tableWithNewColumns.NewRow(); tableWithNewColumns.Rows.Add(newRow); } //var mainWindow = (MainWindow)Application.Current.MainWindow; var format = new NumberFormatInfo(); format.NegativeSign = "-"; int i = 0; double[,] table = new double[mainWindow.gridData.Rows.Count, mainWindow.gridData.Columns.Count - 1]; foreach (DataRow row in mainWindow.gridData.Rows) { for (int j = 0; j < mainWindow.gridData.Columns.Count - 1; j++) { var value = mainWindow.gridData.Rows[i][j].ToString(); if (value.StartsWith(",") || value.StartsWith(".")) { value = "0" + value; } table[i, j] = Convert.ToDouble(value, format); } i++; } double[] d = new double[mainWindow.gridData.Columns.Count - 1]; double[,] diff = new double[1, mainWindow.gridData.Columns.Count - 1]; double[,] covarMatrix = table.Covariance(); double[,] inverseCovarMatrix = null; try { inverseCovarMatrix = covarMatrix.Inverse(); } catch (Exception exp) { inverseCovarMatrix = covarMatrix.PseudoInverse(); } mahalanobis = Mahalanobis.FromPrecisionMatrix(inverseCovarMatrix); }