<jupyter_start><jupyter_text>TSNEを用いた埋め込みの可視化このノートブックでは、TSNEを用いて、埋め込みを可視化します。可視化する埋め込みは「Training_embeddings_using_gensim.ipnb」で学習したものとします。  埋め込みのアップロードまずは可視化する埋め込みをアップロードします。本ノートブックと同じ階層にModelsフォルダがあり、その下に`word2vec_cbow.bin`があるので、そちらをアップロードします。<jupyter_code>from google.colab import files
uploaded = files.upload()<jupyter_output><empty_output><jupyter_text>パッケージのインポート<jupyter_code>import warnings

import numpy as np
import matplotlib.pyplot as plt
from gensim.models import Word2Vec, KeyedVectors
from sklearn.manifold import TSNE
warnings.filterwarnings('ignore')<jupyter_output><empty_output><jupyter_text>モデルの読み込み<jupyter_code>model = KeyedVectors.load_word2vec_format('word2vec_cbow.bin', binary=True)<jupyter_output><empty_output><jupyter_text>TSNEt-SNE（t-distributed Stochastic Neighbouring Entities）は、高次元のデータを2次元または3次元まで次元を減らすことで可視化するためのテクニックです。まずは、きれいに可視化するために、埋め込みのボキャブラリからストップワードを除去しましょう。<jupyter_code>import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')

# ボキャブラリの全単語
words_vocab= list(model.wv.vocab)
print("Size of Vocabulary:", len(words_vocab))
print("Few words in Vocabulary", words_vocab[:50])

# きれいに可視化するために、ストップワードを除去
stopwords_en = stopwords.words()
words_vocab_without_sw = [word.lower() for word in words_vocab if not word in stopwords_en]
print("Size of Vocabulary without stopwords:", len(words_vocab_without_sw))
print("Few words in Vocabulary without stopwords", words_vocab_without_sw[:30])<jupyter_output>[nltk_data] Downloading package stopwords to /root/nltk_data...
[nltk_data]   Unzipping corpora/stopwords.zip.
Size of Vocabulary: 161018
Few words in Vocabulary ['the', 'of', 'and', 'in', 'to', 'was', 'is', 'for', 'on', 'as', 'by', 'with', 'he', 'at', 'from', 'that', 'his', 'it', 'an', 'were', 'are', 'also', 'which', 'or', 'this', 'first', 'new', 'be', 'has', 'one', 'had', 'after', 'who', 'their', 'not', 'its', 'but', 'two', 'her', 'they', 'th', 'she', 'school', 'references', 'time', 'have', 'all', 'other', 'when', 'been']
Size of Vocabulary without stopwords: 159749
Few words in Vocabulary without stopwords ['first', 'new', 'two', 'th', 'school', 'references', 'time', 'year', 'bar', 'links', 'external', 'world', 'city', 'state', 'may', 'years', 'national', 'university', 'united', 'team', 'three', 'later', 'american', 'text', 'st', 'born', 'season', 'film', 'would', 'used']<jupyter_text>データ量が増えるにつれて、可視化と解釈が難しくなります。実践的には、類似した単語をグループにまとめてしまいます。<jupyter_code>keys = ['school', 'year', 'college', 'city', 'states', 'university', 'team', 'film']
embedding_clusters = []
word_clusters = []

for word in keys:
    embeddings = []
    words = []
    for similar_word, _ in model.most_similar(word, topn=30):
        words.append(similar_word)
        embeddings.append(model[similar_word])
    embedding_clusters.append(embeddings) # 類似した単語のベクトルを追加
    word_clusters.append(words) # 類似した単語のリストを追加
print("Embedding clusters:", embedding_clusters[0][0]) # 最初の単語ベクトルにアクセス
print("Word Clousters:", word_clusters[:2])
from sklearn.manifold import TSNE
import numpy as np

embedding_clusters = np.array(embedding_clusters)
n, m, k = embedding_clusters.shape # 次元数の取得
tsne_model_en_2d = TSNE(
    perplexity=5,
    n_components=2,
    init='pca',
    n_iter=1500,
    random_state=2020
)
embeddings_en_2d = np.array(tsne_model_en_2d.fit_transform(embedding_clusters.reshape(n * m, k))).reshape(n, m, 2) # 可視化のため、2次元にreshape<jupyter_output><empty_output><jupyter_text>TSNEのハイパーパラメーター1. n_components: 埋め込み空間の次元数2. perplexity: 学習に用いる最近傍数に関する数。大きなデータセットではたいてい大きくする。3. n_iter: 最適化用の最大イテレーション数4. init: 埋め込みの初期化t-SNEで効果的な結果を得るためには、ハイパーパラメーターチューニングを十分に行う必要があります。ハイパーパラメータに関するさらなる詳細は、[公式ドキュメント](https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html)を参照してください。以下の記事も読むとよいでしょう。- [How to Use t-SNE Effectively](https://distill.pub/2016/misread-tsne/)<jupyter_code>from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
% matplotlib inline

#script for constructing two-dimensional graphics using Matplotlib
def tsne_plot_similar_words(labels, embedding_clusters, word_clusters, a=0.7):
    plt.figure(figsize=(16, 9))

    for label, embeddings, words in zip(labels, embedding_clusters, word_clusters):
        x = embeddings[:,0]
        y = embeddings[:,1]
        plt.scatter(x, y, alpha=a, label=label)
        for i, word in enumerate(words):
            plt.annotate(word, alpha=0.5, xy=(x[i], y[i]), xytext=(5, 2),
                         textcoords='offset points', ha='right', va='bottom', size=8)
    plt.legend(loc=4)
    plt.grid(True)
    plt.show()

tsne_plot_similar_words(words_vocab_without_sw, embeddings_en_2d, word_clusters)
tsne_model_en_2d = TSNE(
    perplexity=25,
    n_components=2,
    init='pca',
    n_iter=1500,
    random_state=2020
)
embeddings_en_2d = np.array(tsne_model_en_2d.fit_transform(embedding_clusters.reshape(n * m, k))).reshape(n, m, 2)
tsne_plot_similar_words(words_vocab_without_sw, embeddings_en_2d, word_clusters)
tsne_model_en_2d = TSNE(
    perplexity=5,
    n_components=2,
    init='pca',
    n_iter=1500,
    random_state=2020
)
embeddings_en_2d = np.array(tsne_model_en_2d.fit_transform(embedding_clusters.reshape(n * m, k))).reshape(n, m, 2)
tsne_plot_similar_words(words_vocab_without_sw, embeddings_en_2d, word_clusters)<jupyter_output><empty_output><jupyter_text>上記の3つの可視化を見てみましょう。perplexityが高いのが良いのか低いのが良いのかは一概には言えません。それは問題によって決まります。今回の場合、perplexityは5や10の方が25より良さそうに見えます。多くの場合は、5〜50の間で選ぶと良いでしょう。<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13848660391021, 'fraction_numerical': 0.01882693700217234, 'mean_word_length': 7.148967551622419, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '137560', 'license': 'MIT', 'n_tokens_mistral': 2644, 'n_tokens_neox': 2521, 'n_words': 361, 'path': 'ch03/09_Visualizing_Embeddings_Using_TSNE.ipynb', 'repo_name': 'oreilly-japan/practical-nlp-ja', 'size': '5524'}