Halo, Habr!
Saya akan membagikan pengalaman saya tentang bagaimana kami menyusun sistem personalisasi kami sendiri berdasarkan “pengetahuan” tentang pembeli potensial.

Satu-satunya perbedaan antara solusi kami dan yang klasik adalah penggunaan bundel gabungan sejumlah solusi dan memenuhi daftar persyaratan:
- layanan seharusnya bekerja segera di situs N
- segmentasi audiens yang dinamis
- Penyaringan kolaboratif untuk keperluan perkiraan dalam berbagai kondisi segmen audiens
- statis yang dihasilkan sebelumnya dalam bentuk konten yang disarankan + campuran dinamis barang berdasarkan analisis clickstream
- perubahan konten, hampir secara real time, dari RAM, dengan mempertimbangkan koefisien dinamis akun
Ini lebih rinci :) Dan tentang rake yang membantu kami mengubah tumpukan menjadi lebih baik.
Latar belakang
Ada sekelompok situs dengan subjek yang sama, yang pemirsanya mirip - situs satu holding. Kontennya berbeda, sebagai aturannya, setiap situs menerbitkan informasi tentang barang yang diproduksi oleh perusahaan induk. Selain situs "konten" ini, ada juga toko online sendiri tempat produk ini dijual.
Setiap situs memiliki tim pemasarannya sendiri, penghitung GA dan Ya Metriknya sendiri. Menganalisis audiens mereka sendiri, sesama pemasar menyesuaikan konten situs, dengan mempertimbangkan kebutuhan pengunjung. Secara alami, audiensi dari situs-situs ini berpotongan, tetapi karena pada saat itu tidak ada penghitung tunggal, hasil analisisnya bersifat lokal.
Analis mana pun akan membuat keputusan yang tepat, siap dengan lebih banyak data. Demi tujuan yang baik ini, ia mengembangkan versi konternya sendiri.
Mengapa tidak Google Analytics?Sampling, kurangnya kemampuan untuk menarik segala sesuatu tentang pengguna dengan rantai perpindahannya dari situs eksternal, melalui banyak situs kami, dengan detail yang ia tonton, dll. Ya, dalam hal tugas GA, ini adalah alat yang bagus, tetapi ketika Anda ingin mendapatkan data secara langsung dan segera memutuskan konten apa yang akan ditampilkan kepada pengunjung, maka ... raksasa analitik tidak memiliki solusi seperti itu. Menari dengan rebana ID klien untuk transfer antar situs bukan pilihan kami.
Menempatkan penghitung tunggal untuk semua situs bukanlah keputusan "politik" yang sepenuhnya benar, dan mereka akan langsung jatuh ke dalam pembatasan versi gratis.
Saya harus segera mengatakan bahwa saya tidak mulai menemukan kembali roda dan membatasi diri pada fungsional sederhana yang tugasnya adalah:
- Perbaiki setiap pengguna unik, apa pun situsnya. Ini diperlukan untuk membuat profil klien tunggal di mana semua datanya akan ditulis dengan referensi ke setiap situs.
- Melacak rantai transisi yang panjang antara semua situs grup dalam satu sesi. Ini diperlukan untuk mengidentifikasi: kepentingan pengguna; apa yang mereka tonton; apa yang mereka beli; apa yang dimasukkan ke dalam keranjang tetapi tidak dibeli; produk apa dari situs yang berbeda dapat menjadi “produk pengganti” selama proses pembelian, dll.
- Melacak aktivitas periklanan dari semua pemasar (di setiap tim situs) untuk analisis selanjutnya. Ini diperlukan untuk: memperkaya profil setiap pengunjung; identifikasi kampanye iklan optimal yang dikaitkan dengan produk; identifikasi saluran iklan yang efektif dengan mengacu pada suatu produk atau kampanye, dll. daftarnya sangat panjang.
Semua data dituangkan secara real time ke dalam koleksi lokal. Ternyata tidak terlalu buruk. Di masa mendatang, dimungkinkan untuk membuat laporan agregat apa pun berdasarkan produk dan oleh: audiens, kampanye iklan, sumber lalu lintas, dan apa pun yang muncul di pikiran. Untuk setiap unit barang ada data tentang harga, jumlah dalam stok, diskon, promosi, dan bahkan lautan data.
Puji situasi ini, saya seorang analis + pengembang + pemasar + manajer + saya memiliki akses ke segala sesuatu yang didigitalkan dalam holding. Saya tidak punya tugas teknis di awal, saya melakukannya sendiri untuk menyelesaikan tugas analisis data biasa.
Momen teknis:
- MongoDB digunakan sebagai sistem penyimpanan terpadu
- pengumpulan data real-time berbasis javascript
- pertukaran data lokal antara situs berdasarkan rabbitmq
Sementara segalanya, seperti orang lain ... Tapi kemudian dimulai
Mengingat fakta bahwa pengetahuan yang diperoleh tentang pembeli dan produk telah cukup terakumulasi, kami memutuskan untuk membuat sistem rekomendasi kami sendiri untuk toko online.
Semuanya ternyata hebat. Kami menganalisis segalanya, tetapi tanpa fanatisme. Modelnya bertambah besar dan, seperti biasanya, saatnya tiba ketika saya menginginkan lebih.
Momen teknis 2:
- Replikasi MongoDB membantu hidup, tetapi sharding segera ditinggalkan. Momen ini belum melewati sejumlah aspek internal. Jika koleksi clickstream dapat tersebar di sekitar pecahan, maka koleksi profil pengguna tidak lagi ada. Dimungkinkan untuk mengumpulkan hasil kueri teragregasi dari bagian yang berbeda untuk sebagian laporan, tetapi kecepatan eksekusi meninggalkan banyak hal yang diinginkan. Tanpa pecahan, itu bekerja lebih baik dan lebih stabil
- Pengumpulan data waktu nyata berdasarkan javascript - di sini bundel CORS + HTTPS adalah diktator. Contohnya, ketika seorang pengguna datang ke salah satu situs grup, dan layanan kami "memberinya wewenang" segera di zona multi-domain (saya ingat, ada 5 situs terpisah yang terpisah pada waktu itu) itu indah secara teknologi dan misterius untuk sesama pemasar yang sekarang dapat melihat semua tekan rantai untuk semua situs sekaligus.
- Model layanan rekomendasi ditulis dalam Python. Namun pelatihan itu butuh waktu lama. File model beberapa puluh GB.
- Layanan pemberi rekomendasi bekerja secara standar pada APInya sendiri, tetapi respons server menjadi hambatan, atau lebih tepatnya, waktu yang dibutuhkan untuk mendapatkan hasilnya. Semakin banyak data, semakin besar model, semakin besar model, semakin lambat hasilnya. Sebagai tanggapan, perlu memperhitungkan banyak faktor yang berubah setiap jam (stok barang dalam persediaan, karakteristik pengguna dan mode, semua jenis diskon, dll.)
Beberapa bulan kemudian, kualitas API telah melewati semua batas "kualitas" yang waras. Untuk pengguna, kecepatan respons melebihi tanda 400ms. Blok konten berkumpul perlahan, situs mulai terasa membosankan. Koleksi MongoDB berjumlah puluhan juta catatan ...
Sudah waktunya untuk mengubah sesuatu
Hampir semua instrumen dicatat pada tingkat operasi, masing-masing bersin diukur.
Apa yang berubah untuk apa:
- Clickhouse di MongoDB
- lanjut MongoDB ke MongoDB + Tarantool
- EVE di Labu
- Labu Selanjutnya di Falcon
- file terpisah dengan janji di js dan dengan otorisasi pengguna di semua domain. Mereka tidak mengubah logika, refactoring menang
Mengapa tidak metrik API?Pada awalnya, saya hanya melihat ke arah solusi siap pakai dari Yandex, tetapi itu tidak lama. Ini bagus ketika satu situs sedang beroperasi. dan ketika ada n, dan Anda ingin memproses data segera, maka tidak ada waktu untuk menari dengan rebana.
Mengapa MongoDB?Spesifikasi produk terus ditambahkan, beberapa dari mereka, sayangnya, tidak selalu disajikan.
Menggunakan kueri teragregasi - sangat cocok dengan format gaya teknologi lokal tim. SQL klasik tidak ingin menghasilkan tabel.
Cukup sering, jenis dan varian data yang disimpan dan diproses diubah.
Pada awalnya, saya berpikir bahwa saya akan menggunakan Yandex clickhouse sebagai dasar untuk layanan ini, tetapi kemudian saya meninggalkan ide ini, tetapi clickhouse juga ada di stack holder kami.
Saat yang baru telah tiba, 2000 permintaan per detik ... asalkan dalam seminggu luncurkan fungsionalitas baru dan beban akan semakin meningkat.
Selama pembelajaran mesin, untuk pertama kalinya di htop saya melihat beban 100% dari 12 core sekaligus dan pertukaran penuh pada server yang produktif. Zabbix secara aktif menginformasikan bahwa MongoDB telah mengubah master dalam replika dua kali dalam 10 menit. Semua orang menginginkan stabilitas dan keadaan yang dapat diprediksi.
Sudah waktunya untuk mengubah sesuatu 2.0
Jumlah pengguna telah meningkat. Jumlah pelanggan serupa. Untuk semua orang yang pernah berkunjung ke salah satu situs, kami telah mengumpulkan profil pribadi. Penonton pengunjung reguler sebagian terbentuk.
Apa yang kamu tahu bagaimana melakukannya? Ya, laporan tidak standar apa pun untuk analytics + keanekaragaman konten:
- Pilih semua pengguna yang datang dari kampanye iklan A, yang berada pada kuartal terakhir, di antara mereka, temukan orang-orang yang tertarik pada barang dari pos N, kemudian mengecualikan mereka yang membeli hanya pada saham, mengecualikan mereka yang memasukkan produk apa pun di keranjang dan pergi situs Menurut mereka, buat penyortiran dengan urutan menurun dari pendapatan toko jika pengguna ini sekarang datang ke situs web toko dan membeli barang Z. Sesuatu seperti itu, dan dengan kancing mutiara lainnya ...
- Untuk menganalisis lalu lintas masuk, bagi pengguna dengan utm tag Y untuk membentuk penawaran konten, tetapi SEBELUM membangun, mengidentifikasi pengguna, mengecualikan mereka yang minggu lalu tetapi berada di situs S (salah satu grup dari situs memegang) dan tertarik pada produk Q - untuk itu menghasilkan konten yang diurutkan berdasarkan kriteria x, y, z
- Adalah basi untuk menemukan mereka yang sering mengunjungi situs A, kadang-kadang itu terjadi di situs B (mereka mengunjungi bagian tertentu), dan yang memiliki rata-rata cek di toko online lebih dari N rubel
Sebenarnya, ini bukan dalam format "pemrograman abnormal", saya menginginkan sesuatu yang lain. Yang lain mendatangi kami. Pada saat kampanye iklan, toko online dibungkuk karena beban, apa yang dapat kita katakan tentang API-shki kami, yang menangkap beban ini “berdiri di sebelahnya”.
Keputusan diambil tepat waktu
Kami melakukan analisis terhadap audiens, memutuskan untuk mengumpulkan konten bukan untuk semua orang, tetapi untuk kelompok pengunjung. Seluruh kerumunan berkerumun. Setiap cluster memiliki karakteristik dan “rasa” tersendiri untuk berbelanja. Clustering dilakukan setiap hari. Ini diperlukan agar pada saat kunjungan berikutnya pengguna akan menunjukkan konten yang paling sesuai dengannya.
Dari sesi ke sesi, minat dan kebutuhan klien berubah, dan jika terakhir kali ia secara otomatis ditugaskan ke cluster No. 788897, maka dengan mempertimbangkan minatnya saat ini, sistem dapat mentransfernya ke cluster No. 9464, yang akan lebih efektif mempengaruhi konversi berikutnya.
Setelah prosedur pengelompokan harian, tahap berikutnya diluncurkan - melatih model, memperhitungkan data dan pengetahuan baru tentang pelanggan dan memperhitungkan barang akun yang muncul di rak toko atau meninggalkannya selamanya.
Untuk setiap cluster, kami membentuk blok konten terlebih dahulu dan merekamnya dalam memori. Kemudian Tarantool datang ke tempat kejadian dengan segala kemuliaan. Sebelumnya, kami menggunakannya untuk menyimpan data cepat, yang kemudian digunakan dalam pembelajaran mesin. Ini adalah solusi terbaik, agar tidak mengoceh MongoDB yang sudah sibuk dengan tugas-tugas lain. Di ruang angkasa Tarantool menyimpan data barang, data pengguna (pengetahuan yang diperlukan tentang pembeli).
Secara kasar, malam ini kami "menyiapkan" konten untuk setiap kelompok khalayak yang mungkin mengunjungi situs tersebut besok. Pengguna masuk, kami dengan cepat menentukan apakah kami tahu sesuatu tentang dia, dan jika jawabannya ya, paket konten yang diperlukan akan terbang ke Nginx. Secara terpisah, untuk pengguna NoName, kluster default dikumpulkan dengan kontennya.
Postprocessing untuk personalisasi
Kami tahu bahwa ada pengguna sederhana, dan ada orang-orang yang kami miliki seluruh file pengetahuannya. Semua ini ada di Tarantool dan diperbarui secara real time.
Pada saat merakit halaman, kami mengetahui seluruh sejarah pembelian dan keranjang yang ditinggalkan setiap pengunjung (jika sebelumnya ia adalah klien kami), menentukan afiliasi klusternya, modul clickstream memberikan pengetahuan tentang sumber lalu lintas, kami tahu tentang minatnya di masa lalu dan yang mendesak. Membangun array TOP50 dengan cepat dari produk yang dilihat sebelumnya (di salah satu situs grup), kami "menentukan mode" dan dicampur dalam konten "rasa" dari produk-produk tersebut, subjek yang paling sering menjadi filum di TOP50. Analisis sederhana dari produk yang terakhir dilihat ini memberikan keuntungan nyata. Konten cluster, kami memperkaya hasil personalisasi.
Hasil dari pengalaman kami
- Kami mendapat percepatan proses pembuatan konten pribadi sebanyak N kali
- Mengurangi beban server sebanyak 15 kali
- Kami dapat membuat hampir semua konten secara pribadi, dengan mempertimbangkan banyak pemasar Wishlist, fitur presentasi produk dan banyak pengecualian, dengan mempertimbangkan data akun dari profil pengguna dan peristiwa yang terjadi di situs saat ini - dan semua ini untuk ~ 25 ms
- Konversi untuk blok tersebut tidak jatuh di bawah 5,6% - pengguna bersedia membeli apa yang lebih dekat dengan kebutuhan mereka saat ini
- Kecepatan pemuatan halaman ideal - mereka menghapus konten yang "melewati" cluster sebesar> 67%, yang benar
- Kami mendapatkan alat yang, sesuai dengan tugas pemasar, tidak hanya memberikan jawaban "apa yang terjadi sebelumnya", tetapi juga membantu merumuskan konten dalam waktu dekat, dengan mempertimbangkan minat dan kebutuhan pembeli potensial
- Informasi dari DMP ditambahkan ke profil setiap pembeli, sekarang kita dapat melakukan pengelompokan, termasuk oleh jejaring sosial, minat, tingkat pendapatan, dan permen lainnya.
- Layanan rekomendasi kami menjadi lebih baik, lebih banyak pesanan di toko
Apa bagusnya ini?
Kami mendapat pengalaman baru, menguji sejumlah hipotesis yang kami tidak tahu cara melakukan pendekatan sebelumnya, kami tidak menggunakan solusi berbayar pihak ketiga untuk layanan rekomendasi yang tidak memperhitungkan semua fitur kami dan bekerja pada domain yang sama. Tim menerima kasus yang bagus dan menarik, yang berhasil mereka kelola.
Nafsu makan bertambah ... sekarang kami menguji logika baru perakitan konten. Kami ingin mengumpulkan halaman untuk kampanye iklan, buletin, dan aktivitas eksternal lainnya. Paket termasuk mentransfer logika konfigurasi dari mode manul ke arah pembelajaran mesin. Situs akan menjalani kehidupan mereka sendiri, dan kami, selain dari "popcorn," akan mengamati evolusi penyajian konten situs berdasarkan pendapat AI.