การแยกคำหลักอัตโนมัติ: ใช้ความคล้ายคลึงโคไซน์เป็นคุณสมบัติ


12

ฉันมีเมทริกซ์เอกสารและตอนนี้ฉันต้องการแยกคำหลักสำหรับแต่ละเอกสารด้วยวิธีการเรียนรู้ภายใต้การดูแล (SVM, Naive Bayes, ... ) ในรุ่นนี้ฉันใช้แท็ก Tf-idf, Pos tag, ...M

แต่ตอนนี้ฉันสงสัยเกี่ยวกับเน็กซ์ ฉันมีเมทริกซ์มีความเหมือนโคไซน์ระหว่างคำC

มีความเป็นไปได้ไหมที่จะใช้ความคล้ายคลึงกันนี้เป็นคุณสมบัติสำหรับโมเดลของฉัน? ผมคิดว่าสำหรับระยะในเอกสาร , การใช้ค่าเฉลี่ยของความคล้ายคลึงกันโคไซน์ของข้อความทั้งหมดในเอกสารที่มีระยะเวลาฉันสิ่งนี้มีประโยชน์หรือไม่?iddi


คุณค้นหาบน Google หรือไม่ ฉันพบการเข้าชมจำนวนมากภายใต้ "การแยกคำหลักที่คล้ายกันแบบโคไซน์" ซึ่งดูเหมือนว่าพวกเขาจะช่วยให้คุณเริ่มต้นได้
shadowtalker

ฉันค้นหามากบน Google และฉันได้อ่านบทความมากมายด้วยคำว่า "ความเหมือนโคไซน์ที่คล้ายคลึงกัน" และ "การแยกคำหลัก" ในนั้น แต่ฉันไม่พบกระดาษที่ใช้คล้ายโคไซน์เพื่อแยกคำหลัก
Silke

คำตอบ:


12

ฉันไม่ทราบว่าเป็นไปได้อย่างไรที่จะทำการแยกคำหลักด้วยการเรียนรู้ภายใต้การดูแล แต่ฉันรู้วิธีการเรียนรู้แบบไม่ดูแลด้วยวิธีนี้

มีหลายวิธีในการทำเช่นนี้ดังนั้นที่นี่:

ตามลำดับชั้น

คุณสามารถใช้วิธีการจัดกลุ่มแบบลำดับชั้นใด ๆ บนเมทริกซ์ความคล้ายคลึงกันของคำโดยตรง (กับฟังก์ชันความคล้ายคลึงใด ๆ ไม่ใช่แค่โคไซน์)

ใน Scikit เรียนรู้คุณจะทำสิ่งนี้:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.cluster import AgglomerativeClustering

vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(data)
C = 1 - cosine_similarity(X.T)
ward = AgglomerativeClustering(n_clusters=k, linkage='ward').fit(C)
label = ward.labels_

ที่มา: [1]

แต่เนื่องจากเป็นการรวมกลุ่มแบบ agglomerative จึงมีราคาแพงและใช้เวลาในการคำนวณ

K-หมายถึง

ความเป็นไปได้อีกอย่างหนึ่งคือการทำ k-mean บนแถวของเมทริกซ์คำว่าเอกสารและจากนั้นหาคำศัพท์ที่พบบ่อยที่สุดสำหรับแต่ละเซนทรอยด์

ตัวอย่างเช่นใน scikit เรียนรู้นี้เป็นวิธีการทำมัน:

from sklearn.cluster import KMeans

km = KMeans(n_clusters=k, init='k-means++', max_iter=100, n_init=1)
km.fit(X)
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(k):
    print("Cluster %d:" % i, end='')
    for ind in order_centroids[i, :10]:
        print(' %s' % terms[ind], end='')

ที่มา: [2]

แต่ค่า k นั้นหมายถึงระยะทางแบบยุคลิดซึ่งไม่ดีสำหรับข้อมูลมิติสูง มีเทคนิคอื่น ๆ ที่ใช้งานได้ดีกว่ากับข้อความและใช้ความคล้ายคลึงกันแบบโคไซน์

Cosine K-Means และ Scatter / Gather

เป็นไปได้ที่จะใช้โคไซน์ด้วยค่าเฉลี่ย K (ดูเช่น[3] ): คำนวณเซนทรอยด์เป็นค่าเฉลี่ยสำหรับเอกสารทั้งหมดในแต่ละกลุ่มแล้วใช้โคไซน์เพื่อคำนวณระยะทางไปหาเซนทรอยด์ที่ใกล้เคียงที่สุด

ในตอนท้ายคุณสามารถแยกคำหลักในลักษณะเดียวกับวิธี k ปกติได้

การคำนวณค่าเซนทรอยด์เฉลี่ยเป็นค่าเฉลี่ยของเอกสารทั้งหมดในคลัสเตอร์นั้นไม่ดีเสมอไป แนะนำให้ใช้วิธีอื่นในอัลกอริธึมการกระจาย / การรวบรวม[4] : เซนทรอยด์ของคลัสเตอร์คือการต่อเอกสารทั้งหมดในคลัสเตอร์นี้เข้าด้วยกัน

สำหรับวิธีการนี้คุณจะต้องใช้คำที่พบบ่อยที่สุดสำหรับแต่ละกลุ่ม centroid

มีการดำเนินการตามขั้นตอนวิธีการเหล่านี้ใน scikit เรียนรู้ไม่ได้ KMeansแต่คุณสามารถใช้พวกเขาด้วยตัวคุณเองโดยการขยาย

โปรดทราบว่าในทั้งสองกรณีเซนทรอยด์จะค่อนข้างหนาแน่น: ทึบกว่าส่วนที่เหลือของเอกสารในแต่ละกลุ่มดังนั้นคุณอาจต้องการตัดคำในเซนทรอยด์เช่นลบ "ไม่สำคัญ" ออก (ดู [8])

การจัดกลุ่มสเปกตรัม

อีกวิธีหนึ่งคือการใช้การจัดกลุ่มสเปกตรัม คุณจะต้องระบุเมทริกซ์ความคล้ายคลึงกันซึ่งคุณมีอยู่แล้วและจะพบกลุ่มมัน

ก็ดำเนินการในSpectralClusteringชั้นดูตัวอย่างใน[5] โปรดทราบว่าเนื่องจากคุณมีเมทริกซ์ที่คำนวณล่วงหน้าแล้วคุณต้องใช้แอaffinity='precumputed'ททริบิวท์เมื่อเริ่มต้น

การจัดกลุ่มสเปกตรัมเกี่ยวข้องกับ Kernel KMeans: มีกระดาษ (ดู [7]) ที่แสดงว่าพวกมันเป็นสิ่งเดียวกัน ฉันเพิ่งเจอการใช้ Kernel KMeans ซึ่งอาจเป็นประโยชน์: https://gist.github.com/mblondel/6230787

การแยกตัวประกอบเมทริกซ์ที่ไม่เป็นลบ

ในที่สุดคุณสามารถจัดกลุ่มเอกสารคำว่าเมทริกซ์ด้วยเทคนิคการสลายตัวจากพีชคณิตเชิงเส้นเช่น SVD (ซึ่งจะเรียกว่า "การวิเคราะห์ความหมายแฝง") หรือเมทริกซ์ Non-Negative Matrix หลังสามารถมองเห็นเป็นการจัดกลุ่มและสามารถจัดกลุ่มทั้งแถวและคอลัมน์ของเมทริกซ์ในเวลาเดียวกัน

ตัวอย่างเช่นคุณสามารถแยกคำหลักโดยทำ

from sklearn.decomposition import NMF
nmf = NMF(n_components=k, random_state=1).fit(X)

feature_names = vectorizer.get_feature_names()

for topic_idx, topic in enumerate(nmf.components_):
    print("Topic #%d:" % topic_idx)
    print(" ".join([feature_names[i]
                    for i in topic.argsort()[:-10-1:-1]]))
    print()

รหัสแหล่งที่มา: [6]

แม้ว่าตัวอย่างนี้จะอยู่ใน python scikit-Learn แต่ฉันคิดว่ามันไม่ควรเป็นปัญหาใหญ่ที่จะหาตัวอย่างสำหรับ R

แหล่งที่มา


1
นี่เป็นคำตอบที่มีคุณภาพสูงอย่างไม่น่าเชื่อ ขอบคุณ! คุณมีความคิดเกี่ยวกับการใช้อัลกอริทึมการเผยแพร่ความสัมพันธ์ของ Scikit เพื่อจัดกลุ่มคำหรือไม่ ค่าความเหมือนโคไซน์สามารถใช้ได้ (ฉันเชื่อว่าต้องการความเหมือนกันไม่ใช่ระยะทาง) เป็นเมทริกซ์ความสัมพันธ์ที่คำนวณล่วงหน้าในอัลกอริทึม
neelshiv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.