سؤال

أحاول استخدام TF-IDF لفرز المستندات إلى فئات. لقد قمت بحساب TF_IDF لبعض المستندات ، لكن الآن عندما أحاول حساب تشابه جيب التمام بين اثنين من هذه المستندات ، أحصل على تتبع قائل:

#len(u)==201, len(v)==246

cosine_distance(u, v)
ValueError: objects are not aligned

#this works though:
cosine_distance(u[:200], v[:200])
>> 0.52230249969265641

هل تقطيع المتجه بحيث len (u) == len (v) النهج الصحيح؟ أعتقد أن تشابه جيب التمام سيعمل مع متجهات بأطوال مختلفة.

أنا استخدم هذه الوظيفة:

def cosine_distance(u, v):
    """
    Returns the cosine of the angle between vectors v and u. This is equal to
    u.v / |u||v|.
    """
    return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v))) 

أيضًا - هل ترتيب قيم TF_IDF في المتجهات مهم؟ هل يجب فرزها - أم أنها ليست ذات أهمية لهذا الحساب؟

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

المحلول

هل تقوم بحساب تشابه جيب التمام من ناقلات المصطلح؟ يجب أن تكون المتجهات المدى بنفس الطول. إذا لم تكن الكلمات موجودة في مستند ، فيجب أن يكون لها قيمة 0 لهذا المصطلح.

لست متأكدًا تمامًا من المتجهات التي تقوم بتطبيق تشابه جيب التمام إليها ، ولكن عند القيام بتشابه جيب التمام ، يجب أن تكون المتجهات الخاصة بك دائمًا بنفس الطول وأن ترتيب يهم كثيرًا.

مثال:

Term | Doc1 | Doc2
Foo     .3     .7
Bar  |  0   |  8
Baz  |  1   |  1

هنا لديك اثنين من المتجهات (.3،0،1) و (.7،8،1) ويمكن أن تحسب تشابه جيب التمام بينهما. إذا قارنت (.3،1) و (.7،8) ، فستقارن درجة DOC1 من BAZ مقابل درجة DOC2 التي لن يكون لها معنى.

نصائح أخرى

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

في الممارسة العملية ، إذا شوهد أحد المستندات من قبل الآخر ، فقد تمت إضافة الكلمات الواردة في المستند الثاني إلى الطلب العالمي بعد رؤية المستند الأول ، لذلك على الرغم من أن المتجهات لها نفس الترتيب ، فقد يكون المستند الأول أقصر ، منذ ذلك الحين ، منذ ذلك الحين ليس لديها إدخالات للكلمات التي لم تكن في هذا المتجه.

الوثيقة 1: قفز الثعلب البني السريع فوق الكلب الكسول.

Global order:     The quick brown fox jumped over the lazy dog
Vector for Doc 1:  1    1     1    1     1     1    1   1   1

الوثيقة 2: كان العداء سريعًا.

Global order:     The quick brown fox jumped over the lazy dog runner was
Vector for Doc 1:  1    1     1    1     1     1    1   1   1
Vector for Doc 2:  1    1     0    0     0     0    0   0   0    1     1

في هذه الحالة ، من الناحية النظرية ، تحتاج إلى وضع متجه المستند 1 مع الأصفار في النهاية. في الممارسة العملية ، عند حساب منتج DOT ، تحتاج فقط إلى مضاعفة العناصر حتى نهاية المتجه 1 (لأن حذف العناصر الإضافية من المتجه 2 وضربها على الصفر هي نفسها تمامًا ، لكن زيارة العناصر الإضافية أبطأ).

ثم يمكنك حساب حجم كل متجه بشكل منفصل ، ولهذا لا تحتاج المتجهات إلى أن تكون بنفس الطول.

حاول بناء المتجهات قبل إطعامها إلى وظيفة comtin_distance:

import math
from collections import Counter
from nltk import cluster

def buildVector(iterable1, iterable2):
    counter1 = Counter(iterable1)
    counter2= Counter(iterable2)
    all_items = set(counter1.keys()).union( set(counter2.keys()) )
    vector1 = [counter1[k] for k in all_items]
    vector2 = [counter2[k] for k in all_items]
    return vector1, vector2


l1 = "Julie loves me more than Linda loves me".split()
l2 = "Jane likes me more than Julie loves me or".split()


v1,v2= buildVector(l1, l2)
print(cluster.util.cosine_distance(v1,v2))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top