このモジュールでは、組み込みの Amazon SageMaker Neural Topic Model (NTM) アルゴリズムを使用してトピックモデルをトレーニングします。

Amazon SageMaker NTM は、ドキュメントのコーパスを統計的分布に基づいて単語のグループを含むトピックに整理するために使用される、教師なしの学習アルゴリズムです。たとえば、「自転車」、「車」、「電車」、「マイレージ」、「速度」などの単語が頻繁に出現するドキュメントは、「輸送」のトピックを共有している可能性があります。トピックモデリングを使用すると、検出されたトピックに基づいてドキュメントを分類または要約したり、トピックの類似性に基づいて情報を取得したり、コンテンツをレコメンドしたりできます。NTM が学習するドキュメントのトピックは、コーパス内の観察された単語の分布から推論されるため、潜在表現として特徴付けられます。トピックのセマンティクスは通常、トピックに含まれる上位の単語を調べることによって推論されます。この方法は教師なしのため、事前に指定されるのはトピック自体ではなく、トピックの数のみです。さらに、トピックは、人間がドキュメントを自然に分類する方法と一致するとは限りません。

次の手順では、トレーニングジョブの NTM アルゴリズムを指定し、モデルのインフラストラクチャを指定し、ハイパーパラメータ値を設定してモデルを調整し、モデルを実行します。次に、Amazon SageMaker が管理するエンドポイントにモデルをデプロイして予測を行います。

モジュールの所要時間: 20 分


  • ステップ 1:トレーニングジョブを作成して実行する

    組み込みの Amazon SageMaker アルゴリズムは、Docker コンテナとして Amazon Elastic Container Registry (Amazon ECR) に保存されます。モデルトレーニングの場合、最初に Amazon ECR 内の NTM コンテナの場所を、リージョンに最も近い場所に指定する必要があります。

    ノートブックインスタンスで、以下のコードをコピーして新しいコードセルに貼り付け、[実行] を選択します。

    import boto3
    from sagemaker.amazon.amazon_estimator import get_image_uri
    container = get_image_uri(boto3.Session().region_name, 'ntm')

    Amazon SageMaker Python SDK には、sagemaker.estimator.Estimator 推定器が含まれています。この推定器を使用すると、インフラストラクチャ (Amazon EC2 インスタンスタイプ、インスタンスの数、ハイパーパラメータ、出力パス、およびオプションで、Amazon VPC ではなく、選択したカスタム VPC でモデルをトレーニングしている場合に関係する可能性のあるセキュリティ関連の設定 (仮想プライベートクラウド (VPC)、セキュリティグループなど)) を指定できます。NTM は GPU ハードウェアの利点を活かして、一般に、CPU よりも GPU の方がおよそ 1 桁速くトレーニングします。マルチ GPU またはマルチインスタンストレーニングは、通信オーバーヘッドが計算時間に比べて低い場合、トレーニング速度をほぼ比例的にさらに向上させます。

    sagemaker.estimator.Estimator クラスのインスタンスを作成するには、次のコードをコピーして新しいコードセルに貼り付け、[実行] を選択します。

    sess = sagemaker.Session()
    ntm = sagemaker.estimator.Estimator(container,
                                        role, 
                                        train_instance_count=2, 
                                        train_instance_type='ml.c4.xlarge',
                                        output_path=output_path,
                                        sagemaker_session=sess)
    

    これで、トピックモデルのハイパーパラメータを設定できます。

    ntm.set_hyperparameters(num_topics=NUM_TOPICS, feature_dim=vocab_size, mini_batch_size=128, 
                            epochs=100, num_patience_epochs=5, tolerance=0.001)
    

    SageMaker には、データチャネル用に 2 つのモードがあります。

    • FullyReplicated: すべてのデータファイルがすべてのワーカーにコピーされます。
    • ShardedByS3Key: データファイルは異なるワーカーにシャーディングされます。つまり、各ワーカーは完全なデータセットの異なる部分を受け取ります。

    執筆時点では、デフォルトで、Amazon SageMaker Python SDK はすべてのデータチャネルに FullyReplicated モードを使用しています。複数のワーカーを使用する場合、このモードは検証 (テスト) チャネルには望ましいですが、トレーニングチャネルには効率的ではありません。

    この場合、各ワーカーに完全なデータセットの異なる部分を通過させて、エポック内で異なる勾配を提供する必要があります。次のように、トレーニングデータチャネルの ShardedByS3Key になるように分布を指定します。

    from sagemaker.session import s3_input
    s3_train = s3_input(s3_train_data, distribution='ShardedByS3Key') 
    ntm.fit({'train': s3_train, 'test': s3_val_data})
    

    ターミナルに次の出力が表示されます。

    Completed - Training job completed

    成功しました。 NTM アルゴリズムを使用してトピックモデルをトレーニングしました。

    次のステップでは、モデルを Amazon Sagemaker ホスティングサービスにデプロイします。

  • ステップ 2.トピックモデルをデプロイする

    トレーニングされたモデル自体は、モデルの重みで構成される tar ファイルであり、それ自体では何もしません。モデルを役立てて予測を得るには、モデルをデプロイする必要があります。

    推論を生成する方法に応じて、モデルを Amazon SageMaker にデプロイする方法は 2 つあります。

    • 一度に 1 つの推論を取得するには、Amazon SageMaker ホスティングサービスを使用して永続的なエンドポイントをセットアップします。
    • データセット全体の推論を取得するには、Amazon SageMaker バッチ変換を使用します。

    このラボでは、ユースケースに最適なアプローチを選択できるようにするため、両方のオプションを提供します。

    Amazon SageMaker ホスティングサービスの場合、ライブ HTTPs エンドポイントは、ペイロードを渡して推論を取得できる Amazon EC2 インスタンス上にあります。

    モデルをデプロイするときは、sagemaker.estimator.Estimator オブジェクトの deploy メソッドを呼び出します。deploy メソッドを呼び出すときに、エンドポイントのホストに使用する ML インスタンスの数とタイプを指定します。

    次のコードをコピーして貼り付け、[実行] を選択してモデルをデプロイします。

    ntm_predictor = ntm.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')

    deploy メソッドはデプロイ可能なモデルを作成し、Amazon SageMaker ホスティングサービスエンドポイントを設定し、エンドポイントを起動してモデルをホストします。

    エンドポイントに対して推論を実行するには、トレーニング済みモデルによる読み取りが可能な形式で入力ペイロードがシリアル化され、人間が読める形式に推論出力が逆シリアル化されることを確認する必要があります。次のコードでは、csv_serializer および json_deserializer を使用して、CSV 形式のデータを (ベクターとして) モデルに渡し、JSON 出力を生成します。

    以下のコードをコピーしてコードセルに貼り付け、[実行] を選択します。

    from sagemaker.predictor import csv_serializer, json_deserializer
    
    ntm_predictor.content_type = 'text/csv'
    ntm_predictor.serializer = csv_serializer
    ntm_predictor.deserializer = json_deserializer

    次に、K-NN モデルで使用するトレーニングデータのトピックベクトルを抽出します。

    以下のコードをコピーして新しいコードセルに貼り付け、[実行] を選択します。

    predictions = []
    for item in np.array(vectors.todense()):
        np.shape(item)
        results = ntm_predictor.predict(item)
        predictions.append(np.array([prediction['topic_weights'] for prediction in results['predictions']]))
        
    predictions = np.array([np.ndarray.flatten(x) for x in predictions])
    topicvec = train_labels[newidx]
    topicnames = [categories[x] for x in topicvec]
    

    成功しました。 これで、モデルの出力を確認できます。

    バッチ変換を使用すると、一度にデータのバッチに対して推論を実行できます。Amazon SageMaker は必要なコンピューティングインフラストラクチャを作成し、バッチジョブが完了するとそれを破棄します。

    バッチ変換コードは、トピックモデルから sagemaker.transformer.Transformer オブジェクトを作成します。次に、そのオブジェクトの transform メソッドを呼び出して、変換ジョブを作成します。sagemaker.transformer.Transformer オブジェクトを作成するときに、バッチ変換ジョブの実行に使用するインスタンスの数とタイプ、および推論を保存する Amazon S3 内の場所を指定します。 

    推論をバッチジョブとして実行するには、次のコードをコピーしてコードセルに貼り付け、[実行] を選択します。

    np.savetxt('trainvectors.csv',
               vectors.todense(),
               delimiter=',',
               fmt='%i')
    batch_prefix = '20newsgroups/batch'
    
    train_s3 = sess.upload_data('trainvectors.csv', 
                                bucket=bucket, 
                                key_prefix='{}/train'.format(batch_prefix))
    print(train_s3)
    batch_output_path = 's3://{}/{}/test'.format(bucket, batch_prefix)
    
    ntm_transformer = ntm.transformer(instance_count=1,
                                      instance_type ='ml.m4.xlarge',
                                      output_path=batch_output_path
                                     )
    ntm_transformer.transform(train_s3, content_type='text/csv', split_type='Line')
    ntm_transformer.wait()
    

    変換ジョブが完了したら、次のコードを使用して、出力をローカルのノートブックインスタンスにダウンロードして検査できます。

    !aws s3 cp --recursive $ntm_transformer.output_path ./
    !head -c 5000 trainvectors.csv.out

    成功しました。 モデルは各ドキュメントを NUM_TOPICS 次元トレーニングベクトルに変換しました。これでトピックモデルを探索できます。

  • ステップ 3.トピックモデルを探索する

    モデル出力を探索する 1 つのアプローチは、T-SNE プロットを使用して生成されたトピックベクトルを視覚化することです。T-SNE (t 分布型確率的近傍埋め込み法) は、次元削減のための非線形手法であり、元の高次元空間の最近傍間の距離が結果として得られる低次元空間で確実に保持されるようにすることを目的としています。次元数を 2 に設定すると、トピックベクトルを 2D 空間で視覚化する視覚化ツールとして使用できます。

    Jupyter ノートブックインスタンスで、以下のコードをコピーして新しいコードセルに貼り付け、[実行] を選択します。

    from sklearn.manifold import TSNE
    time_start = time.time()
    tsne = TSNE(n_components=2, verbose=1, perplexity=50, n_iter=5000)
    tsne_results = tsne.fit_transform(predictions)
    print('t-SNE done! Time elapsed: {} seconds'.format(time.time()-time_start))
    tsnedf = pd.DataFrame()
    tsnedf['tsne-2d-one'] = tsne_results[:,0]
    tsnedf['tsne-2d-two'] = tsne_results[:,1]
    tsnedf['Topic']=topicnames
    plt.figure(figsize=(25,25))
    sns.lmplot(
        x="tsne-2d-one", y="tsne-2d-two",
        hue='Topic',
        palette=sns.color_palette("hls", NUM_TOPICS),
        data=tsnedf,
        legend="full",
        fit_reg=False
    )
    plt.axis('Off')
    plt.show()

    TSNE プロットには、次の画像のような大きなトピッククラスターがいくつか表示されます。このようなプロットを使用して、データセット内の異なるトピッククラスターの数を抽出できます。現在、NUM_TOPICS は 30 に設定されていますが、TSNE プロットで互いに近接している多くのトピックがあり、1 つのトピックに結合することができます。最終的に、トピックモデリングは主として教師なし学習問題であるため、これらのような視覚化を使用して、データセットをパーティショニングするトピックの適切な数を決定する必要があります。

    さまざまなトピック数を試し、視覚化がどのように見えるかを確認してください。


このモジュールでは、Amazon SageMaker Neural Topic Model (NTM) アルゴリズムを Amazon ECR から取得しました。次に、アルゴリズム固有のハイパーパラメータを指定し、アーティファクトストレージ用の Amazon S3 バケットを提供しました。次に、Amazon SageMaker ホスティングサービスまたはバッチ変換を使用して、モデルをエンドポイントにデプロイしました。最後に、トピック数にさまざまな値を使用してモデルを探索しました。

次のモジュールでは、コンテンツレコメンドモデルをトレーニングしてデプロイします。