سؤال

وكيف يمكنني العثور على التشابه بين جيب التمام ناقلات؟

ولست بحاجة لايجاد التشابه لقياس القرابة بين سطرين من النص.

وعلى سبيل المثال، لا بد لي جملتين مثل:

<اقتباس فقرة>   

ونظام لواجهة المستخدم

     

والمستخدم الجهاز واجهة

... وناقلات كل منهما بعد TF-الجيش الإسرائيلي، تليها التطبيع باستخدام LSI، على سبيل المثال [1,0.5] و[0.5,1].

وكيف يمكنني قياس smiliarity بين هذه النواقل؟

هل كانت مفيدة؟

المحلول

public class CosineSimilarity extends AbstractSimilarity {

  @Override
  protected double computeSimilarity(Matrix sourceDoc, Matrix targetDoc) {
    double dotProduct = sourceDoc.arrayTimes(targetDoc).norm1();
    double eucledianDist = sourceDoc.normF() * targetDoc.normF();
    return dotProduct / eucledianDist;
  }
}

وفعلت بعض الاشياء فريق العمل الجيش الإسرائيلي مؤخرا لبلدي وحدة استرجاع المعلومات في الجامعة. لقد استخدمت هذه الطريقة جيب التمام التشابه الذي يستخدم جاما: جافا مصفوفة حزمة

لرمز المصدر الكامل نرى IR الرياضيات مع جاوة: تدابير التشابه ، موردا جيدا حقا أن يغطي بعض القياسات التشابه مختلفة جيدة.

نصائح أخرى

إذا كنت ترغب في تجنب الاعتماد على طرف ثالث المكتبات لهذه المهمة بسيطة، وهنا هو تطبيق جافا عادي:

public static double cosineSimilarity(double[] vectorA, double[] vectorB) {
    double dotProduct = 0.0;
    double normA = 0.0;
    double normB = 0.0;
    for (int i = 0; i < vectorA.length; i++) {
        dotProduct += vectorA[i] * vectorB[i];
        normA += Math.pow(vectorA[i], 2);
        normB += Math.pow(vectorB[i], 2);
    }   
    return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}

لاحظ أن وظيفة يفترض أن ناقلات لهما نفس الطول. قد ترغب في التحقق explictly ذلك للسلامة.

وإلقاء نظرة على العنوان التالي: http://en.wikipedia.org/wiki/Cosine_similarity .

إذا كان لديك ناقلات ألف وباء.

ويتم تعريف تشابه على النحو التالي:

cosine(theta) = A . B / ||A|| ||B||

For a vector A = (a1, a2), ||A|| is defined as sqrt(a1^2 + a2^2)

For vector A = (a1, a2) and B = (b1, b2), A . B is defined as a1 b1 + a2 b2;

So for vector A = (a1, a2) and B = (b1, b2), the cosine similarity is given as:

  (a1 b1 + a2 b2) / sqrt(a1^2 + a2^2) sqrt(b1^2 + b2^2)

مثال:

A = (1, 0.5), B = (0.5, 1)

cosine(theta) = (0.5 + 0.5) / sqrt(5/4) sqrt(5/4) = 4/5

لكود المصفوفة في جافا انصح باستخدام كولت المكتبة. إذا كان لديك هذا، رمز يشبه (لم تختبر أو حتى المترجمة):

DoubleMatrix1D a = new DenseDoubleMatrix1D(new double[]{1,0.5}});
DoubleMatrix1D b = new DenseDoubleMatrix1D(new double[]{0.5,1}});
double cosineDistance = a.zDotProduct(b)/Math.sqrt(a.zDotProduct(a)*b.zDotProduct(b))

ويمكن أيضا تغيير رمز أعلاه إلى استخدام إحدى الطرق Blas.dnrm2() أو Algebra.DEFAULT.norm2() لحساب القاعدة. بالضبط نفس النتيجة، وهي أكثر قابلية للقراءة تعتمد على الذوق.

وعندما كنت أعمل مع التعدين النص منذ بعض الوقت، وكنت تستخدم SimMetrics المكتبة التي توفر مجموعة واسعة من مقاييس مختلفة في جاوة. إذا حدث أن كنت بحاجة الى مزيد، ثم هناك دائما R وكرا للنظر في.

ولكن الترميز عليه من الوصف في ويكيبيديا هي مهمة تافهة إلى حد ما، ويمكن أن يكون ممارسة لطيفة.

لتمثيل متفرق من ناقلات باستخدام Map(dimension -> magnitude) هنا هو نسخة سكالا (يمكنك أن تفعل أشياء مماثلة في جاوة 8)

def cosineSim(vec1:Map[Int,Int],
              vec2:Map[Int,Int]): Double ={
  val dotProduct:Double = vec1.keySet.intersect(vec2.keySet).toList
    .map(dim => vec1(dim) * vec2(dim)).sum
  val norm1:Double = vec1.values.map(mag => mag * mag).sum
  val norm2:Double = vec2.values.map(mag => mag * mag).sum
  return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2))
}
def cosineSimilarity(vectorA: Vector[Double], vectorB: Vector[Double]):Double={
    var dotProduct = 0.0
    var normA = 0.0
    var normB = 0.0
    var i = 0

    for(i <- vectorA.indices){
        dotProduct += vectorA(i) * vectorB(i)
        normA += Math.pow(vectorA(i), 2)
        normB += Math.pow(vectorB(i), 2)
    }

    dotProduct / (Math.sqrt(normA) * Math.sqrt(normB))
}

def main(args: Array[String]): Unit = {
    val vectorA = Array(1.0,2.0,3.0).toVector
    val vectorB = Array(4.0,5.0,6.0).toVector
    println(cosineSimilarity(vectorA, vectorA))
    println(cosineSimilarity(vectorA, vectorB))
}

ونسخة سكالا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top