Blog film online ivi memiliki banyak artikel tentang arsitektur sistem rekomendasi Hydra. Namun, rekomendasi tidak hanya API eksternal, tetapi juga algoritma yang hidup "di bawah tenda" dan menerapkan logika bisnis yang cukup kompleks.
Dalam artikel ini, saya akan berbicara tentang masalah "mulai dingin" dari konten. Jika Anda tertarik mempelajari cara kami merekomendasikan konten yang baru saja ditambahkan ke katalog dan tidak berhasil mendapatkan umpan balik dari pengguna, selamat datang di cat.
Artikel ini akan berisi sampel kode Python yang dapat direproduksi menggunakan Keras.
Mulai Dingin Konten: Pernyataan Masalah
Bagaimana cara kerja rekomendasi? Kira-kira sebagai berikut:
Kami menggunakan pipa berikut untuk rekomendasi:
- memuat statistik tampilan konten dalam bentuk matriks konten pengguna
- terapkan kotak ajaib pembelajaran mesin
- di pintu keluar dari kotak untuk setiap unit fitur katalog muncul
- kami menggunakan fitur konten untuk rekomendasi
Semua tahapan pipa pelatihan model mulai dingin dapat ditemukan di repositori ini
github.com/ivi-ru/hydraKami mendapatkan fitur konten menggunakan pustaka implisit sebagai berikut
train_model.pyimport implicit import numpy as np from scipy.sparse import load_npz
Bagaimana cara merekomendasikan konten yang keluar pada layanan baru-baru ini? Konten tersebut tidak akan memiliki tampilan (atau akan ada sangat sedikit tampilan) - ini berarti bahwa tidak akan ada fitur untuk konten tersebut di knalpot kotak ajaib pembelajaran mesin dan tidak akan muncul dalam rekomendasi pengguna. Ngomong-ngomong, fitur yang kami dapatkan berdasarkan interaksi pengguna-konten disebut kolaborasi.
Jadi, kita sampai pada masalah awal yang sulit: bagaimana kami dapat merekomendasikan konten yang tidak memiliki umpan balik pengguna? Misalnya, dimungkinkan untuk mencampur konten baru menjadi output acak dan menunggu hingga tampilan "organik" dikumpulkan.
Pilihan lain adalah membangun model yang dapat memprediksi fitur konten "dingin".
Kami memutuskan untuk pergi ke jalan kedua dan ke sanalah kami datang
Mulai Dingin 1.0
Untuk menyelesaikan masalah cold start, kami dibantu oleh fitur konten yang diketahui sebelumnya tentang konten baru, misalnya
- Orang: sutradara, penulis skenario, pemeran
- genre konten: aksi, komedi, dll.
- kategori: film fitur, kartun, dokumenter
- tag editor
Tag editorial adalah deskripsi singkat tentang konten dalam bentuk seperangkat karakteristik yang terbatas (biasanya beberapa ratus). Di bawah ini adalah satu set tag konten Beaver Zombie
Dalam perkiraan pertama, kami memecahkan masalah cold start sebagai berikut:
- untuk setiap konten "dingin", bersihkan semirip mungkin dengan tag
- mengambil fitur kolaboratif dari konten serupa
- fitur kolaboratif konten dingin adalah rata-rata fitur tetangganya yang "panas"
Dengan python, tampilannya seperti ini for row in new_items_neighbors: neighbors_als_indices = row.neighbors_ids[:self.cold_start_neighbors_count] neighbors_average_factors = item_factors[neighbors_als_indices].mean(axis=0)
Metode ini
entah bagaimana berhasil , tetapi memiliki dua kelemahan:
- ekstensibilitas yang lemah: sulit untuk menambahkan, misalnya, kesamaan poster dengan model
- tidak ada yang menjamin kesamaan fitur ALS untuk konten yang serupa dalam tag, dan tanpa ini, menggunakan rata-rata terlihat aneh
Kami menyadari bahwa Anda tidak dapat hidup seperti itu lagi, dan menghasilkan model yang lebih transparan dan dapat diperluas.
Refactoring model awal yang dingin
Alih-alih menghitung fitur konten ALS menggunakan heuristik (seperti rata-rata), kita dapat melatih jaringan saraf yang akan memprediksi fitur konten kolaboratif - misalnya, dengan tag editor. Model serupa sudah
muncul di Habr's di sini , dan sebelum Yandex
layanan musik Spotify berbicara tentang model yang sama
Kode prototipe model tersedia
di repositori ivi , jaringan saraf untuk cold start adalah sebagai berikut:
cold_start_model.py def _get_model(self, dims: List[int]) -> Sequential: model = Sequential() model.add( Dense( units=dims[1], activation='linear', input_dim=dims[0], kernel_initializer=WeightInitializer.custom_normal, bias_initializer='zeros' ) ) model.compile( loss=lambda y_true, y_pred: K.sum(K.square(y_pred - y_true), axis=-1), optimizer=optimizers.Adam(lr=self.learning_rate, decay=self.decay) ) return model
Kesulitan apa yang Anda temui saat menerapkan percobaan ini?
- Ternyata cukup sulit untuk melatih jaringan: fitur dikodekan satu panas, dan jaringan kurang terlatih karena dimensi besar dari lapisan input. Saya harus melakukan pemilihan fitur dengan hati-hati, pada akhirnya kami hanya menggunakan kategori, genre, dan dari tag editor kami memilih yang paling "penting" menggunakan tf-idf
- masalah dengan menginstal Keras menggunakan manajer paket pipenv: python, lingkungan tidak akan, saya harus menyelesaikan paket maxvolpy pihak ketiga yang Keras tidak berteman dengan
Hasil Eksperimen
Akibatnya, kami menghapus fungsionalitas baru sedikit kurang, yang untuk beberapa sprint, pengembang menghabiskan waktu sekitar 100 jam - dan ini adalah pengalaman pertama menggunakan jaringan saraf dalam produksi pada proyek kami. Waktu ini didistribusikan sebagai berikut:
- 60 jam untuk membaca artikel dan pengembangan prototipe
- 30 jam untuk mengintegrasikan prototipe ke dalam basis kode proyek
- 10 jam pada penyebaran model baru - menyeret Keras ke lingkungan python tidak begitu sederhana karena ketergantungan khusus kami (seperti maxvolpy)
Kami mendapat ruang untuk percobaan lebih lanjut - penggunaan jaringan saraf memungkinkan Anda untuk belajar tidak hanya pada tag editor, tetapi juga pada fitur lain: gambar, skrip, komentar pengguna, rekaman, dll.