先將csv檔做預處理,像是將標點符號刪除,以及將英文字體都變成小寫,可以看到我的title_abstract_processed即為處理過後的樣子。
import pandas as pd
papers = pd.read_csv('Google_AI_published_research.csv')
#加載正則表達式庫
import re
#刪除標點符號
papers['title_abstract_processed']=papers['title_abstract'].map(lambda x:re.sub('[,\.!?:-]','',x))
#將標題轉換為小寫的
papers ['title_abstract_processed'] = papers ['title_abstract_processed'].map(lambda x:x.lower())
#打印出論文的第一行
papers ['title_abstract_processed'].head()
papers.head(10)
再來是將資料處理成數字,利用TfidfVectorizer,將一些常用的英文助詞刪去(ex:I,and,or)。因為在Kmean的方法裡,已經使用過Elbow method去做過分析,因此這裡的cluster數直接採用和kmean一樣等於6。
from sklearn.cluster import KMeans
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(stop_words='english')
text = vectorizer.fit_transform(papers.title_abstract_processed)
true_k = 6
model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
model.fit(text)
再來使用兩種降維的方式去做圖值分析。以下分別用PCA跟TSNE兩種方法去做圖,在用PCA降維的時候,我們希望留下最重要的特徵,剩下的比較不重要的特徵我們直接捨棄掉。而TSNE則是用了更複雜的公式來表達高維與低維之間的關係,TSNE主要是將高維的數據用高斯分佈的機率密度函數近似,而低維數據的部分使用t分佈的方式來近似,在使用KL距離計算相似度,最後再以梯度下降(或隨機梯度下降)求最佳解 。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
def plot_tsne_pca(data, labels):
max_label = max(labels)
max_items = np.random.choice(range(data.shape[0]), size=3000, replace=True)
pca = PCA(n_components=2).fit_transform(data[max_items,:].todense())
tsne = TSNE().fit_transform(PCA(n_components=50).fit_transform(data[max_items,:].todense()))
idx = np.random.choice(range(pca.shape[0]), size=300, replace=False)
label_subset = labels[max_items]
label_subset = [cm.hsv(i/max_label) for i in label_subset[idx]]
f, ax = plt.subplots(1, 2, figsize=(14, 6))
ax[0].scatter(pca[idx, 0], pca[idx, 1], c=label_subset)
ax[0].set_title('PCA Cluster Plot')
ax[1].scatter(tsne[idx, 0], tsne[idx, 1], c=label_subset)
ax[1].set_title('TSNE Cluster Plot')
clusters = model.fit_predict(text)
plot_tsne_pca(text, clusters)
最後則是利用kmeans++得出6種centers的前十個topics。
order_centroids = model.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(true_k):
print ("Cluster %d:" %i),
for ind in order_centroids[i, :10]:
print (' %s' % terms[ind]),
print