En este módulo, utilice el algoritmo de vecino k más próximo (k-NN) integrado de Amazon SageMaker para entrenar el modelo de recomendación de contenido.

Los vecinos k más próximos (k-NN) de Amazon SageMaker es un algoritmo de aprendizaje supervisado, basado en índice, no paramétrico que se puede utilizar para las tareas de clasificación y regresión. Para la clasificación, el algoritmo consulta los puntos k más próximos al objetivo y devuelve la etiqueta de la clase utilizada más frecuentemente como la etiqueta prevista. Para los problemas de regresión, el algoritmo arroja el promedio de valores de predicción arrojado por los vecinos k más próximos.

El entrenamiento con el algoritmo k-NN tiene tres pasos: muestreo, reducción de dimensión y creación de índice. El muestreo reduce el tamaño del conjunto de datos inicial para ajustarlo a la memoria. Para la reducción de dimensión, el algoritmo disminuye la dimensión de las características de los datos a fin de reducir la capacidad del modelo k-NN en la memoria y la latencia de la inferencia. Ofrecemos dos métodos de reducción de dimensionalidad: proyección aleatoria y la transformación rápida Johnson-Lindenstrauss. Generalmente, utiliza la reducción de dimensión para conjuntos de datos de alta dimensión (d>1000) a fin de evitar la “maldición de la dimensionalidad” que complica el análisis estadístico de datos que se vuelve disperso a medida que la dimensionalidad aumenta. El objetivo principal del entrenamiento de k-NN es construir el índice. El índice permite búsquedas rápidas eficaces de distancias entre puntos cuyos valores o etiquetas de clase aún no fueron determinados y los puntos k más cercanos para utilizar para inferencia.

En los pasos siguientes, especifique el algoritmo k-NN para el trabajo de entrenamiento, configure los valores de hiperparámetros a fin de ajustar y ejecutar el modelo. Luego, implemente el modelo en un punto de enlace administrado por Amazon SageMaker para hacer predicciones.

Tiempo para completar el módulo: 20 minutos


  • Paso 1. Cree y ejecute el trabajo de entrenamiento

    En el módulo anterior, creó vectores de tema. En este módulo, creará e implementará el módulo de recomendación de contenido que retiene un índice de los vectores de tema.

    Primero, cree un diccionario que enlace las etiquetas mezcladas con las etiquetas originales en los datos de entrenamiento. En el bloc de notas, copie y pegue el siguiente código y elija Ejecutar.

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

    Luego, almacene los datos de entrenamiento en el bucket S3 con el siguiente código:

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

    A continuación, utilice la siguiente función de asistencia para crear un estimador k-NN tal como el estimador NTM que creó en el módulo 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)
    

    Mientras se ejecuta el trabajo de entrenamiento, examine en mayor profundidad los parámetros en la función de asistencia.

    El algoritmo k-NN de Amazon SageMaker ofrece una cantidad de métricas de distancia diferentes para calcular los vecinos más próximos. Una métrica popular que se utiliza en el procesamiento de lenguaje natural es la distancia coseno. Desde el punto de visto matemático, la “similitud” coseno entre dos vectores A y B se da por la siguiente ecuación:

    Al configurar index_metric como COSENO, Amazon SageMaker utiliza automáticamente la similitud coseno para calcular los vecinos más cercanos. La distancia predeterminada es la norma L2, que es la distancia euclidiana estándar. Tenga en cuenta que, en la publicación, COSENO es compatible solo para el tipo de índice faiss.IVFFIat y no para el método de indexación faiss.IVFPQ.

    Debe ver los siguientes resultados en la terminal.

    Completed - Training job completed

    ¡Correcto! Como desea que este modelo arroje los vecinos más cercanos con un tema de prueba concreto, necesita implementarlo como un punto de enlace activo alojado.

  • Paso 2. Implemente el modelo de recomendación de contenido

    Al igual que con el modelo NTM, defina la siguiente función de asistencia para el modelo k-NN a fin de lanzar el punto de enlace. En la función de asistente, el token de aceptación applications/jsonlines; verbose=true indica al modelo k.NN que arroje todas las distancias coseno en lugar de solo los vecinos más cercanos. A fin de crear un motor de recomendación, el modelo debe arrojar las principales sugerencias k, para el que necesita configurar el parámetro verbose como verdadero, en lugar del falso predeterminado.

    Copie y pegue el siguiente código en el bloc de notas y elija Ejecutar.

    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)

    Luego, preprocese los datos de prueba para poder ejecutar las inferencias.

    Copie y pegue el siguiente código en el bloc de notas y elija Ejecutar.

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

    En el último paso de este módulo, explore el modelo de recomendación de contenido.

  • Paso 3. Explore el modelo de recomendación de contenido

    Ahora que obtuvo las predicciones, puede trazar las distribuciones de temas de los temas de prueba, en comparación con los temas k más cercanos recomendados por el modelo k-NN.

    Copie y pegue el siguiente código en el bloc de notas y elija Ejecutar.

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

    Ejecute el siguiente código para trazar la distribución de tema:

    plot_topic_distribution(18)
    

    Ahora, pruebe algunos otros temas. Ejecute las siguientes celdas de código:

    plot_topic_distribution(25)
    plot_topic_distribution(5000)

    Los plots podrían verse diferentes en función del número de temas (NUM_TOPICS) que elija. Pero en general, estos plots muestran que la distribución de temas de los documentos de vecinos más cercanos encontrados con la similitud coseno del modelo k-NN es bastante similar a la distribución de temas del documento de prueba que introdujimos en el modelo.

    Los resultados sugieren que k-NN puede ser una buena manera de crear una semántica en función del sistema de recuperación de información, primero al integrar los documentos en vectores de tema y luego al utilizar un modelo k-NN para atender a las recomendaciones.


¡Felicitaciones! En este módulo entrenó, implementó y exploró el modelo de recomendación de contenido.

En el siguiente módulo, puede limpiar los recursos que utilizó en este laboratorio.