Tôi không biết làm thế nào có thể thực hiện trích xuất từ khóa với việc học có giám sát, nhưng tôi biết làm thế nào với việc học không giám sát.
Có một số phương pháp để làm điều này, vì vậy đây là:
Thứ bậc
Bạn có thể áp dụng bất kỳ phương pháp phân cụm phân cấp nào trên ma trận tương tự thuật ngữ trực tiếp (với bất kỳ chức năng tương tự nào, không chỉ cosine)
Trong scikit-learn bạn sẽ làm một cái gì đó như thế này:
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_
Nguồn: [1]
Nhưng vì nó là cụm kết tụ, nó đắt tiền về mặt tính toán và sẽ mất một thời gian để tính toán.
Phương tiện
Một khả năng khác là thực hiện các phương tiện k thông thường trên các hàng của ma trận tài liệu thuật ngữ và sau đó tìm các thuật ngữ phổ biến nhất cho mỗi centroid
Ví dụ, trong scikit tìm hiểu đây là cách làm:
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='')
Nguồn: [2]
Nhưng k-mean phụ thuộc vào khoảng cách Euclide, điều này không tốt cho dữ liệu chiều cao thưa thớt. Có các kỹ thuật khác hoạt động tốt hơn cho các văn bản và sử dụng sự tương tự cosine
Cosine K-Means và Scatter / Gather
Có thể sử dụng Cosine với K- mean (xem ví dụ [3] ): tính toán trọng tâm như một giá trị trung bình trên tất cả các tài liệu trong mỗi cụm, sau đó sử dụng cosine để tính khoảng cách đến tâm gần nhất.
Cuối cùng, bạn có thể trích xuất từ khóa theo cách tương tự như đối với phương tiện k thông thường.
Tính toán trung bình trung bình là trung bình của tất cả các tài liệu trong cụm không phải lúc nào cũng tốt. Một cách tiếp cận khác được đề xuất trong thuật toán Scatter / Gather [4] : trọng tâm của một cụm là nối tất cả các tài liệu trong cụm này.
Đối với phương pháp này, bạn sẽ chỉ cần sử dụng các thuật ngữ thường xuyên nhất cho mỗi cụm centroid.
Không có triển khai các thuật toán này trong scikit learn, nhưng bạn có thể dễ dàng tự thực hiện chúng bằng cách mở rộng KMeans
.
Lưu ý rằng trong cả hai trường hợp, trọng tâm trở nên khá dày đặc: dày đặc hơn các tài liệu còn lại trong mỗi cụm, vì vậy bạn có thể muốn cắt bớt các thuật ngữ trong tâm, tức là loại bỏ các thuật ngữ "không quan trọng". (xem [8]).
Phân cụm phổ
Một cách khác là áp dụng phân cụm phổ. Bạn sẽ cần cung cấp một ma trận tương tự mà bạn đã có và nó sẽ tìm thấy các cụm trên đó.
Nó được triển khai trong SpectralClustering
lớp, xem các ví dụ trong [5] . Lưu ý rằng vì bạn đã có một ma trận được tính toán trước, bạn cần sử dụngaffinity='precumputed'
thuộc tính khi khởi tạo.
Phân cụm phổ có liên quan đến Kernel KMeans: có giấy (xem [7]) cho thấy chúng là cùng một thứ. Gần đây tôi đã bắt gặp một triển khai Kernel KMeans có thể hữu ích: https://gist.github.com/mblondel/6230787
Hệ số ma trận không phủ định
Cuối cùng, bạn có thể phân cụm ma trận tài liệu thuật ngữ của bạn với một số kỹ thuật phân tách từ Đại số tuyến tính, như SVD (đây sẽ được gọi là "Phân tích ngữ nghĩa tiềm ẩn") hoặc Hệ số ma trận không âm. Cái sau có thể được xem như là phân cụm, và nó có thể phân cụm cả hai hàng và cột của ma trận cùng một lúc.
Ví dụ: bạn có thể trích xuất từ khóa bằng cách thực hiện
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()
Nguồn mã: [6]
Mặc dù ở đây các ví dụ là trong python scikit-learn, tôi nghĩ rằng đó không phải là một vấn đề lớn để tìm một số ví dụ cho R
Nguồn