In questo modulo utilizzerai l'algoritmo Amazon SageMaker k-Nearest Neighbors (k-NN) per addestrare il modulo di raccomandazione dei contenuti.

Amazon SageMaker K-Nearest Neighbors (k-NN) è un algoritmo di apprendimento supervisionato, non parametrico e basato sugli indici, che è possibile utilizzare per attività di classificazione e regressione. Per la classificazione, l'algoritmo esegue la query dei punti k più vicini alla destinazione e restituisce l'etichetta più utilizzata della classe come etichetta prevista. Per i problemi di regressione, l'algoritmo restituisce la media dei valori previsti restituiti da k punti adiacenti più vicini.

L'addestramento con l'algoritmo k-NN è costituito da tre fasi: campionamento, riduzione della dimensione e creazione dell'indice. Il campionamento riduce la dimensione del set di dati iniziale in modo che possa essere contenuto in memoria. Per la riduzione della dimensione, l'algoritmo diminuisce la dimensione della caratteristica dei dati per ridurre l'ingombro del modello k-NN nella latenza della memoria e dell'interferenza. Sono forniti due metodi di riduzione della dimensione: la proiezione casuale e la trasformazione veloce Johnson-Lindenstrauss. In genere, si utilizza la riduzione della dimensione per set di dati ad alta dimensionalità (d >1000) per evitare la "maledizione della dimensionalità" che disturba l'analisi statistica dei dati limitandola man mano che aumenta la dimensionalità. L'obiettivo principale dell'addestramento k-NN è la creazione dell'indice. L'indice consente ricerche efficienti di distanze tra i punti i cui valori o etichette di classe non sono ancora stati determinati e dei punti k più vicini da utilizzare per l'inferenza.

Nelle fasi seguenti, specifichi l'algoritmo k-NN per l'attività di addestramento, imposti i valori degli iperparametri per ottimizzare il modello e lo esegui. Dopodiché, distribuisci il modello a un endpoint gestito da Amazon SageMaker per effettuare previsioni.

Tempo necessario per completare il modulo: 20 minuti


  • Fase 1. Creazione ed esecuzione dell'attività di addestramento

    Nel modulo precedente hai creato i vettori di argomento. In questo modulo, creerai e distribuirai il modulo di raccomandazione dei contenuti in cui è conservato un incide dei vettori di argomento.

    In primo luogo, crea un dizionario che collega le etichette sparse a quelle originali nei dati di addestramento. Copia e incolla nel notebook il seguente codice e scegli Esegui.

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

    Quindi, archivia i dati di addestramento nel bucket S3 utilizzando il seguente codice:

    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))
    

    Successivamente, utilizza la seguente funzione del gestore per creare uno strumento di stima k-NN simile a quello NTM creato nel Modulo 3.

    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)
    

    Durante l'esecuzione dell'attività di addestramento, osserva attentamente i parametri nella funzione del gestore.

    L'algoritmo Amazon SageMaker k-NN offre alcuni parametri di distanza diversi per calcolare i punti adiacenti più vicini. Uno dei parametri comunemente utilizzato nell'elaborazione del linguaggio naturale è la distanza del coseno. In matematica, la "similarità" del coseno tra due vettori A e B è data dalla seguente equazione:

    Impostando index_metric su COSINE, Amazon SageMaker utilizza automaticamente la similarità del coseno per calcolare i punti adiacenti più vicini. La distanza predefinita è la L2 norm, che è la distanza euclidea standard. Al momento della pubblicazione, COSINE è supportato solo per il tipo di indice faiss.IVFFlat e non per il metodo di indicizzazione faiss.IVFPQ.

    Dovresti visualizzare l'output seguente nel terminale.

    Completed - Training job completed

    Operazione riuscita. Poiché vuoi che il modello restituisca i punti adiacenti più vicini in base a un determinato argomento di prova, devi distribuirlo come endpoint ospitato in diretta.

  • Fase 2. Distribuzione di un modello di raccomandazione dei contenuti

    Come per il modello NTM, definisci la funzione del gestore seguente per il modello k-NN al fine di avviare l'endpoint. Nella funzione del gestore, il token di conferma applications/jsonlines; verbose=true indica al modello k-NN di restituire tutte le distanze del coseno anziché il solo punto adiacente più vicino. Per costruire un motore di raccomandazione, devi ottenere i suggerimenti top-k dal modello, per cui devi impostare il parametro verbose su true, anziché su quello predefinito, false.

    Copia e incolla il seguente codice nel tuo notebook e scegli Esegui.

    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)

    Quindi, pre-elabora i dati dei test in modo da poter eseguire le interferenze.

    Copia e incolla il seguente codice nel tuo notebook e scegli Esegui.

    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])       
    

    Nell'ultima fase del modulo, esplorerai il modello di raccomandazione dei contenuti.

  • Fase 3. Esplorazione di un modello di raccomandazione dei contenuti

    Ora che hai ottenuto le previsioni, puoi tracciare graficamente le distribuzioni degli argomenti dei test rispetto agli argomenti k più vicini consigliati dal modello k-NN.

    Copia e incolla il seguente codice nel tuo notebook e scegli Esegui.

    # 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()
    

    Esegui il codice seguente per tracciare graficamente la distribuzione degli argomenti:

    plot_topic_distribution(18)
    

    Adesso, prova altri argomenti. Esegui le seguenti celle di codice:

    plot_topic_distribution(25)
    plot_topic_distribution(5000)

    I diagrammi potrebbero apparire diversamente in base al numero di argomenti (NUM_TOPICS) selezionato. Ma soprattutto, questi diagrammi mostrano che la distribuzione degli argomenti dei documenti dei punti adiacenti più vicini individuati mediante la similarità del coseno dal modello k-NN è piuttosto simile alla distribuzione dell'argomento del documento di prova alimentato nel modello.

    Dai risultati emerge che k-NN può essere un buon metodo per costruire un sistema di recupero delle informazioni basato sulla semantica incorporando prima i documenti nei vettori di argomento, quindi utilizzando un modello k-NN per le raccomandazioni.


Complimenti! In questo modulo ti sei addestrato, hai distribuito e hai esplorato il modello di raccomandazione dei contenuti.

Nel prossimo modulo, rimuoverai le risorse che hai utilizzato in questa esercitazione.