本次實驗以AAAI 2014會議論文數據為基礎,要求實現或調用無監督聚類算法,了解聚類方法。
任務介紹
每年國際上召開的大大小小學術會議不計其數,發表了非常多的論文。在計算機領域的一些大型學術會議上,一次就可以發表涉及各個方向的幾百篇論文。按論文的主題、內容進行聚類,有助于人們高效地查找和獲得所需要的論文。本案例數據來源于AAAI 2014上發表的約400篇文章,由UCI公開提供,提供包括標題、作者、關鍵詞、摘要在內的信息,希望大家能根據這些信息,合理地構造特征向量來表示這些論文,并設計實現或調用聚類算法對論文進行聚類。最后也可以對聚類結果進行觀察,看每一類都是什么樣的論文,是否有一些主題。
基本要求:
-
將文本轉化為向量,實現或調用無監督聚類算法,對論文聚類,例如10類(可使用已有工具包例如sklearn);
-
觀察每一類中的論文,調整算法使結果較為合理;
-
無監督聚類沒有標簽,效果較難評價,因此沒有硬性指標,跑通即可,主要讓大家了解和感受聚類算法,比較簡單。
擴展要求:
-
對文本向量進行降維,并將聚類結果可視化成散點圖。
注:group和topic也不能完全算是標簽,因為
-
有些文章作者投稿時可能會選擇某個group/topic但實際和另外group/topic也相關甚至更相關;
-
一篇文章可能有多個group和topic,作為標簽會出現有的文章同屬多個類別,這里暫不考慮這樣的聚類;
-
group和topic的取值很多,但聚類常常希望指定聚合成出例如5/10/20類;
-
感興趣但同學可以思考利用group和topic信息來量化評價無監督聚類結果,不作要求。
提示:
-
高維向量的降維旨在去除一些高相關性的特征維度,保留最有用的信息,用更低維的向量表示高維數據,常用的方法有PCA和t-SNE等;
-
降維與聚類是兩件不同的事情,聚類實際上在降維前的高維向量和降維后的低維向量上都可以進行,結果也可能截然不同;
-
高維向量做聚類,降維可視化后若有同一類的點不在一起,是正常的。在高維空間中它們可能是在一起的,降維后損失了一些信息
實驗結果?
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import calinski_harabasz_score
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import pandas as pd
import numpy as npdef load_data(path='data/[UCI] AAAI-14 Accepted Papers - Papers.csv'):df_data = pd.read_csv(path)df_data = df_data.dropna()return df_datadf = load_data()
df.describe()
# 去除不好的特征
df_selected = df.drop(['groups', 'topics'], axis=1)
cv = CountVectorizer()
X_features = np.array([[i] for i in range(df.shape[0])])for col in df_selected.columns:tmp = cv.fit_transform(df_selected[col].tolist())feature = tmp.toarray()X_features = np.concatenate((X_features, feature), axis=1)print("特征矩陣的形狀:", X_features.shape)
?特征矩陣的形狀: (392, 9899)
# 取出group和topics特征作為評價指標
df_cls = df[['groups', 'topics']]
cv = CountVectorizer()
X_cls = [[i] for i in range(df.shape[0])]
for col in df_cls.columns:tmp = cv.fit_transform(df_cls[col])feature = tmp.toarray()X_cls = np.concatenate((X_cls, feature), axis=1)
SSE(Sum of Squared Errors)測量聚類結果中每個樣品與所屬聚類中心距離的平方和。SSE越小,聚類樣品越致密,聚類效果越好。SSE是衡量簇內密度的指標,越小越好。
CH指標(Calinski-HarabaszIndex)是綜合考慮集群內密度和集群間分辨率的指標。計算集群間分散度與集群內密度之比。CH指標越大,集群之間的距離越大,集群內的距離越小,集群效果越好。
for pca_num in [2, 5, 7, 10, 30]:X_pca = PCA(n_components=pca_num).fit_transform(X_features)X_cs = PCA(n_components=pca_num).fit_transform(X_cls)print(X_pca.shape)for k in range(5, 16):kmeans = KMeans(n_clusters=k)labels = kmeans.fit_predict(X_pca)# 獲取聚類中心centroids = kmeans.cluster_centers_# 計算每個樣本與所屬簇中心的距離的平方distances = np.sum((X_cs - centroids[labels])**2, axis=1)# 計算 SSEsse = np.sum(distances)# CH指標ch = calinski_harabasz_score(X_cs, labels)score = sse/chprint('k:', k, 'ch:', ch, 'SSE:', sse, 'score:', score)
從結果可以看出降維度在2,k為15的時候聚類效果更好。這里我用了sse和ch的比值作為成績,越小證明聚類效果越好。?