Dalam modul ini, Anda menggunakan Algoritme k-Nearest Neighbor (k-NN) Amazon SageMaker bawaan untuk melatih model rekomendasi konten.

K-Nearest Neighbors (k-NN) Amazon SageMaker adalah algoritme pembelajaran nonparametrik, berbasis indeks, yang diawasi yang dapat digunakan untuk tugas klasifikasi dan regresi. Untuk klasifikasi, mengkueri algoritme ke titik k closest ke target dan mengembalikan label yang paling sering digunakan untuk kelas mereka sesuai label yang diprediksi. Untuk masalah regresi, algoritme mengembalikan rata-rata nilai yang diprediksi yang dihasilkan oleh k closest neighbor.

Melatih dengan algoritme k-NN memiliki tiga langkah: pengambilan sampel, pengurangan dimensi, dan membangun indeks. Pengambilan sampel mengurangi ukuran dataset awal, sehingga sesuai dengan memori. Untuk pengurangan dimensi, algoritme mengurangi dimensi fitur data untuk mengurangi footprint model k-NN dalam memori dan latensi inferensi. Kami menyediakan dua metode pengurangan dimensi: proyeksi acak dan Fast Johnson-Lindenstrauss Transform. Biasanya, Anda menggunakan pengurangan dimensi untuk dataset berdimensi tinggi (d> 1000) untuk menghindari "kutukan dimensi" yang menyulitkan analisis statistik data yang menjadi jarang seiring dengan meningkatnya dimensi. Tujuan utama pelatihan k-NN adalah membangun indeks. Indeks memungkinkan pencarian jarak secara efisien antara titik-titik yang nilainya atau label kelasnya belum ditentukan dan k nearest point yang akan digunakan untuk inferensi.

Dalam langkah berikut, Anda menentukan algoritme k-NN untuk tugas pelatihan, mengatur nilai hyperparameter untuk menyesuaikan model, dan menjalankan model. Kemudian, Anda menerapkan model ke titik akhir yang dikelola oleh Amazon SageMaker untuk membuat prediksi.

Waktu untuk Menyelesaikan Modul: 20 Menit


  • Langkah 1. Membuat dan menjalankan tugas pelatihan

    Di modul sebelumnya, Anda membuat vektor topik. Dalam modul ini, Anda membangun dan menggunakan modul rekomendasi konten yang mempertahankan indeks vektor topik.

    Pertama, buat kamus yang menautkan label yang diacak ke label asli dalam data pelatihan. Dalam notebook Anda, salin dan tempel kode berikut dan pilih Jalankan.

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

    Selanjutnya, simpan data pelatihan dalam bucket S3 Anda menggunakan kode berikut:

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

    Selanjutnya, gunakan fungsi pembantu berikut untuk membuat penilai k-NN seperti penilai NTM yang Anda buat di Modul 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)
    

    Saat tugas pelatihan berjalan, lihat lebih dekat parameter dalam fungsi bantuan.

    Algoritme k-NN Amazon SageMaker menawarkan jumlah metrik jarak berbeda untuk menghitung nearest neighbor. Satu metrik populer yang digunakan dalam pemrosesan bahasa alami adalah jarak cosine. Secara matematis, cosine “serupa” di antara kedua vektor A dan B dengan persamaan:

    Dengan mengatur index_metric ke COSINE, Amazon SageMaker secara otomatis menggunakan kemiripan cosine untuk komputasi nearest neighbor. Jarak default adalah L2 norm, yang merupakan jarak Euclidean standar. Perhatikan bahwa, pada publikasi, COSINE hanya didukung untuk jenis indeks faiss.IVFFlat dan bukan metode pengindeksan faiss.IVFPQ.

    Anda akan melihat output berikut di terminal Anda.

    Completed - Training job completed

    Berhasil! Karena Anda ingin model ini mengembalikan nearest neighbor yang diberi topik pengujian tertentu, Anda perlu menerapkannya sebagai titik akhir yang di-hosting secara langsung.

  • Langkah 2. Menerapkan model rekomendasi konten

    Seperti yang Anda lakukan dengan model NTM, tentukan fungsi pembantu berikut ke model k-NN untuk meluncurkan titik akhir. Di fungsi pembantu, token yang menerima applications/jsonlines; verbose=true memberi tahu model k-NN untuk mengembalikan semua jarak cosine dan bukan hanya closest neighbor. Untuk membangun mesin rekomendasi, Anda perlu mendapatkan saran top-k oleh model, yang Anda butuhkan untuk mengatur parameter verbose menjadi true, bukan false default.

    Salin dan tempelkan kode berikut ke notebook Anda dan pilih Jalankan.

    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)

    Berikutnya, praproses data tes sehingga Anda dapat menjalankan inferensi.

    Salin dan tempelkan kode berikut ke notebook Anda dan pilih Jalankan.

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

    Pada langkah terakhir modul ini, Anda menjelajahi model rekomendasi konten Anda.

  • Langkah 3. Jelajahi model rekomendasi konten

    Sekarang setelah Anda memperoleh prediksi, Anda dapat menyusun distribusi topik dari topik tes, bandingkan dengan topik k closest yang direkomendasikan oleh model k-NN.

    Salin dan tempelkan kode berikut ke notebook Anda dan pilih Jalankan.

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

    Jalankan kode berikut untuk menyusun plot distribusi topik:

    plot_topic_distribution(18)
    

    Sekarang, coba beberapa topik lainnya. Jalankan sel kode berikut:

    plot_topic_distribution(25)
    plot_topic_distribution(5000)

    Plot Anda mungkin terlihat agak berbeda berdasarkan jumlah topik (NUM_TOPICS) yang Anda pilih. Namun secara keseluruhan, plot ini menunjukkan bahwa distribusi topik dari dokumen nearest neighbor yang ditemukan menggunakan kesamaan Cosine oleh model k-NN yang sangat mirip dengan distribusi topik dari dokumen tes yang kami masukkan ke dalam model.

    Hasilnya menunjukkan bahwa k-NN mungkin merupakan cara yang baik untuk membangun sistem pengambilan informasi berbasis semantik dengan terlebih dahulu memasukkan dokumen ke dalam vektor topik dan kemudian menggunakan model k-NN untuk melayani rekomendasi.


Selamat! Dalam modul ini, Anda melatih, menerapkan, dan menjelajahi model rekomendasi konten.

Dalam modul berikutnya, Anda membersihkan sumber daya yang digunakan di lab ini.