/// <summary> /// Мягкая косинусная метрика использует матрицу произведений значений confidence Терма a с собой, Терма b с собой, Терма a с Термом b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private static float SoftCosine(DAL.Term a, DAL.Term b) { float s = 0; float da = 0, db = 0; for (int i = 0; i < a.Count; i++) { for (int j = 0; j < b.Count; j++) { s += a.Childs[i].confidence * b.Childs[j].confidence; } } for (int i = 0; i < a.Count; i++) { for (int j = 0; j < a.Count; j++) { da += a.Childs[i].confidence * a.Childs[j].confidence; } } for (int i = 0; i < b.Count; i++) { for (int j = 0; j < b.Count; j++) { db += b.Childs[i].confidence * b.Childs[j].confidence; } } return((float)(s / (Math.Sqrt(da) * Math.Sqrt(db)))); }
private static float SoftOverlapping(DAL.Term a, DAL.Term b) { float count = a.Childs.Sum(c => b.Childs.Max(bc => Confidence.Compare(c, bc))); float denominator = a.Count * a.Count + b.Count * b.Count; return((float)Math.Sqrt(count * count / denominator)); }
/// <summary> /// Основной метод, вызывающий вычисления метрики, соответствющей рангу Термов a и b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static float Compare(DAL.Term a, DAL.Term b) { if (a.rank != b.rank) { throw new ArgumentException("Попытка сравнить термы разных рангов"); } return(Confidence.MetricsStack[a.rank](a, b)); }
/// <summary> /// Левое косинусная метрика - в отличие от косинусного, в знаменателе не произведение модулей Термов, а модуль терма a /// Данная метрика учитывает только модуль (длину) Терма a. Аналогично можно сделать правую косинусную метрику, вызовом CosineLeft(b,a). /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private static float CosineLeft(DAL.Term a, DAL.Term b) { int n = a.Count < b.Count ? a.Count : b.Count; float s = 0; for (int i = 0; i < n; i++) { s += (a.Childs[i].id == b.Childs[i].id) ? a.Childs[i].confidence : 0; } return(s / a.Count); }
/// <summary> /// Косинусная метрика между Термами: сумма совпадающих подслов, делёная на произведение модулей Термов /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private static float Cosine(DAL.Term a, DAL.Term b) { int n = a.Count < b.Count ? a.Count : b.Count; float s = 0; for (int i = 0; i < n; i++) { s += (a.Childs[i].id == b.Childs[i].id) ? a.Childs[i].confidence : 0; } float denominator = (float)(Math.Sqrt(a.Count) * Math.Sqrt(b.Count)); return(s / denominator); }
/// <summary> /// Метрика схожести зависящая от количества совпадающих эелементов вне зависимости от их порядка. /// Итоговое значение делится на длину слова b (отсюда в названии Right), т.о. метрика тем больше, /// чем короче слово b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private static float SoftOverlappingRight(DAL.Term a, DAL.Term b) { float count = a.Childs.Sum(c => b.Childs.Max(bc => Confidence.Compare(c, bc))); return(count / b.Count); }
/// <summary> /// Возвращает отношение количества дочерних слов, вошедших в b и количетсва дочерних слов b. Учитываются точные вхождения /// </summary> /// <param name="a">терм</param> /// <param name="b">терм</param> /// <returns>оценка схожести из интервала [0,1], где 0 - не похожи, 1 - максимально похожи</returns> private static float Overlapping(DAL.Term a, DAL.Term b) { int count = a.Childs.Sum(c => b.Contains(c) ? 1 : 0); return(count / a.Count); }
/// <summary> /// Метрика бинарного совпадения Термов по идентификаторам /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private static float Equality(DAL.Term a, DAL.Term b) { return(a.id == b.id ? 1 : 0); }