コーパス全体の一意の単語ごとに、ドキュメントのリストとtf-idfスコアがあります。これを2次元プロットで視覚化して、k-meansを実行するために必要なクラスターの数を測定するにはどうすればよいですか?
これが私のコードです:
sentence_list=["Hi how are you", "Good morning" ...]
vectorizer=TfidfVectorizer(min_df=1, stop_words='english', decode_error='ignore')
vectorized=vectorizer.fit_transform(sentence_list)
num_samples, num_features=vectorized.shape
print "num_samples: %d, num_features: %d" %(num_samples,num_features)
num_clusters=10
ご覧のとおり、文をtf-idfドキュメントマトリックスに変換できます。しかし、tf-idfスコアのデータポイントをプロットする方法がわかりません。
私が考えていた:
ありがとう
私は現在、テキストのデータセットの2D、tf-idfスコアでプロットしようとして、同様のことを行っています。私のアプローチは、他のコメントの提案と同様に、scikit-learnのPCAとt-SNEを使用することです。
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
num_clusters = 10
num_seeds = 10
max_iterations = 300
labels_color_map = {
0: '#20b2aa', 1: '#ff7373', 2: '#ffe4e1', 3: '#005073', 4: '#4d0404',
5: '#ccc0ba', 6: '#4700f9', 7: '#f6f900', 8: '#00f91d', 9: '#da8c49'
}
pca_num_components = 2
tsne_num_components = 2
# texts_list = some array of strings for which TF-IDF is being computed
# calculate tf-idf of texts
tf_idf_vectorizer = TfidfVectorizer(analyzer="Word", use_idf=True, smooth_idf=True, ngram_range=(2, 3))
tf_idf_matrix = tf_idf_vectorizer.fit_transform(texts_list)
# create k-means model with custom config
clustering_model = KMeans(
n_clusters=num_clusters,
max_iter=max_iterations,
precompute_distances="auto",
n_jobs=-1
)
labels = clustering_model.fit_predict(tf_idf_matrix)
# print labels
X = tf_idf_matrix.todense()
# ----------------------------------------------------------------------------------------------------------------------
reduced_data = PCA(n_components=pca_num_components).fit_transform(X)
# print reduced_data
fig, ax = plt.subplots()
for index, instance in enumerate(reduced_data):
# print instance, index, labels[index]
pca_comp_1, pca_comp_2 = reduced_data[index]
color = labels_color_map[labels[index]]
ax.scatter(pca_comp_1, pca_comp_2, c=color)
plt.show()
# t-SNE plot
embeddings = TSNE(n_components=tsne_num_components)
Y = embeddings.fit_transform(X)
plt.scatter(Y[:, 0], Y[:, 1], cmap=plt.cm.Spectral)
plt.show()
PCAは1つのアプローチです。 TF-IDFの場合、非線形次元削減のためにScikitLearnのマニホールドパッケージも使用しました。私が役立つと思うことの1つは、TF-IDFスコアに基づいてポイントにラベルを付けることです。
次に例を示します(最初にTF-IDF実装を挿入する必要があります)。
from sklearn import manifold
# Insert your TF-IDF vectorizing here
##
# Do the dimension reduction
##
k = 10 # number of nearest neighbors to consider
d = 2 # dimensionality
pos = manifold.Isomap(k, d, eigen_solver='auto').fit_transform(.toarray())
##
# Get meaningful "cluster" labels
##
#Semantic labeling of cluster. Apply a label if the clusters max TF-IDF is in the 99% quantile of the whole corpus of TF-IDF scores
labels = vectorizer.get_feature_names() #text labels of features
clusterLabels = []
t99 = scipy.stats.mstats.mquantiles(X.data, [ 0.99])[0]
clusterLabels = []
for i in range(0,vectorized.shape[0]):
row = vectorized.getrow(i)
if row.max() >= t99:
arrayIndex = numpy.where(row.data == row.max())[0][0]
clusterLabels.append(labels[row.indices[arrayIndex]])
else:
clusterLabels.append('')
##
# Plot the dimension reduced data
##
pyplot.xlabel('reduced dimension-1')
pyplot.ylabel('reduced dimension-2')
for i in range(1, len(pos)):
pyplot.scatter(pos[i][0], pos[i][1], c='cyan')
pyplot.annotate(clusterLabels[i], pos[i], xytext=None, xycoords='data', textcoords='data', arrowprops=None)
pyplot.show()
Van der MaatenとHintonによる t-SNE を探していたと思います。
出版物: http://jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf
このリンクsklearn
でこれを行うためのIPythonNotebookに。
一言で言えば、t-SNEはPCAに似ていますが、2次元の高次元空間に関連するオブジェクトをグループ化するのに優れています。プロットのスペース。
要件に応じて、scipy.sparse.csr.csr_matrixをプロットできます
TfidfVectorizer.fit_transform()は、(ドキュメントID、用語番号)tf-idfスコアを提供します。これで、x軸として用語ごとにnumpy行列を作成し、y軸としてドキュメントを作成できます。2番目のオプションは、(temm、tf-tdfスコア)をプロットするか、(term、ドキュメント、頻度)を使用して3次元をプロットすることです。ここでは、PCAも適用できます。
scipy.sparse.csr.csr_matrix からnumpy行列を作成し、matplotlibを使用するだけです。