In diesem Modul verwenden Sie den integrierten Amazon SageMaker k-Nearest Neighbors (k-NN)-Algorithmus, um das Inhaltsempfehlungsmodell zu schulen.

Amazon SageMaker K-Nearest Neighbors (k-NN) ist ein nicht-parametrischer, indexbasierter, überwachter Lernalgorithmus, der für Klassifizierungs- und Regressionsaufgaben verwendet werden kann. Bei der Klassifizierung fragt der Algorithmus die k-Punkte ab, die dem Ziel am nächsten liegen, und gibt die am häufigsten verwendete Bezeichnung ihrer Klasse als prognostizierte Bezeichnung zurück. Bei Regressionsproblemen gibt der Algorithmus den Durchschnitt der prognostizierten Werte zurück, die von den k nächstgelegenen Nachbarn zurückgegeben werden.

Das Training mit dem k-NN-Algorithmus umfasst drei Schritte: Sampling, Dimensionsreduzierung und Indexerstellung. Durch Sampling wird die Größe des anfänglichen Datensatzes reduziert, sodass es in den Arbeitsspeicher passt. Bei der Dimensionsreduzierung verringert der Algorithmus die Funktionsdimension der Daten, um den Ressourcenbedarf des k-NN-Modells im Speicher und die Inferenzlatenz zu senken. Wir stellen zwei-Methoden der Dimensionsreduzierung zur Verfügung: zufällige Projektion und die schnelle Johnson-Lindenstrauss-Transformation. In der Regel verwenden Sie die Dimensionsreduzierung für hochdimensionale Datensätze (d > 1000), um die „Nachteile der Dimensionalität“ zu vermeiden, die die statistische Analyse von Daten beeinträchtigt, deren Dichte mit steigender Dimensionalität geringer wird. Das Hauptziel des k-NN-Trainings ist die Erstellung des Index. Der Index ermöglicht ein effizientes Suchen von Entfernungen zwischen Punkten, deren Werte oder Klassenbezeichnungen noch nicht festgelegt wurden, und den k nächstgelegenen Punkten zur Inferenz.

In den folgenden Schritten geben Sie den k-NN-Algorithmus für den Trainingsauftrag an, setzen die Hyperparameterwerte fest, um das Modell zu optimieren, und führen das Modell aus. Anschließend stellen Sie das Modell auf einem Endpunkt bereit, der von Amazon SageMaker verwaltet wird, um Prognosen vorzunehmen.

Veranschlagte Zeit für das Modul: 20 Minuten


  • Schritt 1. Erstellen und Ausführen des Trainingsauftrags

    Im vorherigen Modul haben Sie Themenvektoren erstellt. In diesem Modul erstellen und stellen Sie das Inhaltsempfehlungsmodul bereit, das einen Index der Themenvektoren beibehält.

    Erstellen Sie zunächst ein Wörterbuch, das die gemischten Bezeichnungen mit den ursprünglichen Bezeichnungen in den Trainingsdaten verknüpft. Kopieren Sie den folgenden Code in Ihr Notebook und wählen Sie Run aus.

    labels = newidx 
    labeldict = dict(zip(newidx,idx))

    Speichern Sie dann die Trainingsdaten in Ihrem S3-Bucket mit dem folgenden Code:

    import io
    import sagemaker.amazon.common as smac
    
    
    print('train_features shape = ', predictions.shape)
    print('train_labels shape = ', labels.shape)
    buf = io.BytesIO()
    smac.write_numpy_to_dense_tensor(buf, predictions, labels)
    buf.seek(0)
    
    bucket = BUCKET
    prefix = PREFIX
    key = 'knn/train'
    fname = os.path.join(prefix, key)
    print(fname)
    boto3.resource('s3').Bucket(bucket).Object(fname).upload_fileobj(buf)
    s3_train_data = 's3://{}/{}/{}'.format(bucket, prefix, key)
    print('uploaded training data location: {}'.format(s3_train_data))
    

    Verwenden Sie danach die folgende Hilfsfunktion, um einen k-NN-Schätzer ähnlich dem NTM-Schätzer zu erstellen, den Sie im Modul 3 erstellt haben.

    def trained_estimator_from_hyperparams(s3_train_data, hyperparams, output_path, s3_test_data=None):
        """
        Create an Estimator from the given hyperparams, fit to training data, 
        and return a deployed predictor
        
        """
        # set up the estimator
        knn = sagemaker.estimator.Estimator(get_image_uri(boto3.Session().region_name, "knn"),
            get_execution_role(),
            train_instance_count=1,
            train_instance_type='ml.c4.xlarge',
            output_path=output_path,
            sagemaker_session=sagemaker.Session())
        knn.set_hyperparameters(**hyperparams)
        
        # train a model. fit_input contains the locations of the train and test data
        fit_input = {'train': s3_train_data}
        knn.fit(fit_input)
        return knn
    
    hyperparams = {
        'feature_dim': predictions.shape[1],
        'k': NUM_NEIGHBORS,
        'sample_size': predictions.shape[0],
        'predictor_type': 'classifier' ,
        'index_metric':'COSINE'
    }
    output_path = 's3://' + bucket + '/' + prefix + '/knn/output'
    knn_estimator = trained_estimator_from_hyperparams(s3_train_data, hyperparams, output_path)
    

    Während der Trainingsauftrag ausführt, schauen Sie sich die Parameter in der Hilfsfunktion genauer an.

    Der Amazon SageMaker k-NN-Algorithmus bietet eine Reihe unterschiedlicher Entfernungsmetriken zur Berechnung der nächsten Nachbarn an. Eine beliebte Metrik, die in der Verarbeitung natürlicher Sprache verwendet wird, ist die Kosinus-Entfernung. Mathematisch wird die Kosinus-"Ähnlichkeit" zwischen zwei Vektoren A und B durch die folgende Gleichung gegeben:

    Wenn Sie die index_metric auf COSINE festsetzen, verwendet Amazon SageMaker automatisch die Kosinusähnlichkeit, um die nächsten Nachbarn zu berechnen. Die Standard-Entfernung ist die L2-Norm, die die standardmäßige euklidische Entfernung ist. Beachten Sie, dass bei der Veröffentlichung COSINE nur für den Indextyp faiss.IVFFlat und nicht für die Indizierungsmethode faiss.IVFPQ unterstützt wird.

    Sie sollten die folgende Ausgabe in Ihrem Terminal sehen.

    Completed - Training job completed

    Erfolg! Da dieses Modell die nächstgelegenen Nachbarn zurückgeben soll, die ein bestimmtes Testthema erhalten, müssen Sie es als live gehosteten Endpunkt bereitstellen.

  • Schritt 2. Bereitstellen des Inhaltsempfehlungsmodells

    Definieren Sie wie beim NTM-Modell die folgende Hilfsfunktion für das k-NN-Modell, um den Endpunkt zu starten. In der Hilfsfunktion weist das Accept-Token applications/jsonlines; verbose=true das k-NN-Modell an, alle Kosinus-Entfernungen zurückzugeben, anstatt nur den nächstgelegenen Nachbarn. Um eine Empfehlungs-Engine zu erstellen, müssen Sie vom Modell die Top-k-Vorschläge erhalten. Dazu müssen Sie den ausführlichen Parameter auf true festsetzen, anstelle des Standardwerts oder false.

    Kopieren Sie den folgenden Code in Ihr Notebook und wählen Sie Run aus.

    def predictor_from_estimator(knn_estimator, estimator_name, instance_type, endpoint_name=None): 
        knn_predictor = knn_estimator.deploy(initial_instance_count=1, instance_type=instance_type,
                                            endpoint_name=endpoint_name,
                                            accept="application/jsonlines; verbose=true")
        knn_predictor.content_type = 'text/csv'
        knn_predictor.serializer = csv_serializer
        knn_predictor.deserializer = json_deserializer
        return knn_predictor
    import time
    
    instance_type = 'ml.m4.xlarge'
    model_name = 'knn_%s'% instance_type
    endpoint_name = 'knn-ml-m4-xlarge-%s'% (str(time.time()).replace('.','-'))
    print('setting up the endpoint..')
    knn_predictor = predictor_from_estimator(knn_estimator, model_name, instance_type, endpoint_name=endpoint_name)

    Bereiten Sie dann die Testdaten auf, damit Sie Inferenzen ausführen können.

    Kopieren Sie den folgenden Code in Ihr Notebook und wählen Sie Run aus.

    def preprocess_input(text):
        text = strip_newsgroup_header(text)
        text = strip_newsgroup_quoting(text)
        text = strip_newsgroup_footer(text)
        return text    
        
    test_data_prep = []
    for i in range(len(newsgroups_test)):
        test_data_prep.append(preprocess_input(newsgroups_test[i]))
    test_vectors = vectorizer.fit_transform(test_data_prep)
    
    test_vectors = np.array(test_vectors.todense())
    test_topics = []
    for vec in test_vectors:
        test_result = ntm_predictor.predict(vec)
        test_topics.append(test_result['predictions'][0]['topic_weights'])
    
    topic_predictions = []
    for topic in test_topics:
        result = knn_predictor.predict(topic)
        cur_predictions = np.array([int(result['labels'][i]) for i in range(len(result['labels']))])
        topic_predictions.append(cur_predictions[::-1][:10])       
    

    Im letzten Schritt dieses Moduls erkunden Sie das Inhaltsempfehlungsmodell.

  • Schritt 3. Erkunden des Inhaltsempfehlungsmodells

    Nun, da Sie die Prognosen erhalten haben, können Sie die Themenverteilungen der Testthemen im Vergleich zu den nächstgelegenen vom k-NN-Modell empfohlenen k-Themen darstellen.

    Kopieren Sie den folgenden Code in Ihr Notebook und wählen Sie Run aus.

    # set your own k.
    def plot_topic_distribution(topic_num, k = 5):
        
        closest_topics = [predictions[labeldict[x]] for x in topic_predictions[topic_num][:k]]
        closest_topics.append(np.array(test_topics[topic_num]))
        closest_topics = np.array(closest_topics)
        df = pd.DataFrame(closest_topics.T)
        df.rename(columns ={k:"Test Document Distribution"}, inplace=True)
        fs = 12
        df.plot(kind='bar', figsize=(16,4), fontsize=fs)
        plt.ylabel('Topic assignment', fontsize=fs+2)
        plt.xlabel('Topic ID', fontsize=fs+2)
        plt.show()
    

    Führen Sie den folgenden Code aus, um die Themenverteilung darzustellen:

    plot_topic_distribution(18)
    

    Probieren Sie nun einige andere Themen aus. Führen Sie die folgenden Codezellen aus:

    plot_topic_distribution(25)
    plot_topic_distribution(5000)

    Ihre Diagramme können je nach Anzahl der Themen (NUM_TOPICS) etwas anders aussehen. Aber insgesamt zeigen diese Diagramme, dass die Themenverteilung der nächstgelegenen Nachbardokumente, die vom k-NN-Modell mit Kosinus-Ähnlichkeit gefunden wurden, ziemlich ähnlich wie die Themenverteilung des Testdokuments ist, das wir in das Modell eingespeist haben.

    Die Ergebnisse deuten darauf hin, dass k-NN eine gute Möglichkeit sein kann, ein semantisches Informationsabrufsystem zu erstellen, indem Sie die Dokumente zuerst in Themenvektoren einbetten und dann ein k-NN-Modell verwenden, um die Empfehlungen zu generieren.


Herzlichen Glückwunsch! In diesem Modul haben Sie Ihr Inhaltsempfehlungsmodell geschult, bereitgestellt und erkundet.

Im nächsten Modul bereinigen Sie die von Ihnen in dieser Übung verwendeten Ressourcen.