Setiap orang yang menghabiskan waktu tertentu untuk mendukung sistem terbiasa dengan perasaan déjà vu ketika mereka menerima aplikasi baru: "seperti itu, itu sudah beres, tapi saya tidak ingat bagaimana tepatnya". Anda dapat menghabiskan waktu, mempelajari aplikasi-aplikasi sebelumnya dan mencoba menemukan yang serupa. Ini akan membantu: insiden akan ditutup lebih cepat, atau bahkan mungkin mendeteksi akar penyebab dan menutup masalah sekali dan untuk semua.
Karyawan “muda” yang baru saja bergabung dengan tim tidak memiliki kisah seperti itu di kepala mereka. Kemungkinan besar, mereka tidak tahu bahwa kejadian serupa, misalnya, terjadi enam bulan hingga setahun yang lalu. Dan kolega dari kamar sebelah memutuskan kejadian itu.
Kemungkinan besar, karyawan "muda" tidak akan mencari sesuatu yang serupa dalam database kejadian, tetapi akan menyelesaikan masalah dari awal. Luangkan lebih banyak waktu, dapatkan pengalaman, dan waktu berikutnya akan mengatasi lebih cepat. Atau mungkin mereka akan segera melupakannya di bawah aliran aplikasi baru. Dan lain kali semuanya akan terjadi lagi.
Kami sudah menggunakan model ML untuk mengklasifikasikan insiden . Untuk membantu tim kami memproses aplikasi lebih efisien, kami telah membuat model ML lain untuk menyiapkan daftar "insiden serupa yang sebelumnya ditutup". Detail - di bawah potongan.
Apa yang kita butuhkan
Untuk setiap insiden yang masuk, perlu untuk menemukan insiden tertutup "serupa" dalam sejarah. Definisi "kesamaan" harus terjadi pada awal insiden, lebih disukai sebelum staf pendukung memulai analisis.
Untuk membandingkan insiden, perlu menggunakan informasi yang disediakan oleh pengguna saat menghubungi: deskripsi singkat, deskripsi terperinci (jika ada), atribut apa pun dari catatan pengguna.
Tim mendukung 4 kelompok sistem. Jumlah total insiden yang ingin saya gunakan untuk mencari yang serupa adalah sekitar 10 ribu.
Keputusan pertama
Tidak ada informasi terverifikasi tentang "kesamaan" insiden yang ada. Jadi opsi canggih untuk melatih jaringan Siam harus ditunda untuk saat ini.
Hal pertama yang terlintas dalam pikiran adalah pengelompokan sederhana "kantong kata-kata" yang terdiri dari isi banding.
Dalam hal ini, proses penanganan insiden adalah sebagai berikut:
- Sorot fragmen teks yang diperlukan
- Pra-pemrosesan / pembersihan teks
- Vektorisasi TF-IDF
- Temukan tetangga terdekat Anda
Jelas bahwa dengan pendekatan yang dijelaskan, kesamaan akan didasarkan pada perbandingan kamus: menggunakan kata-kata yang sama atau n-gram dalam dua insiden yang berbeda akan dianggap sebagai "kesamaan".
Tentu saja, ini adalah pendekatan yang cukup disederhanakan. Tetapi dengan mengingat bahwa kami mengevaluasi teks-teks mengenai pengguna, jika masalahnya dijelaskan dengan kata-kata yang serupa - kemungkinan besar insidennya serupa. Selain teks, Anda dapat menambahkan nama departemen pengguna, berharap bahwa pengguna dari departemen yang sama di organisasi yang berbeda akan memiliki masalah yang sama.
Sorot fragmen teks yang diperlukan
Data insiden yang kami dapatkan dari service-now.com dengan cara yang paling sederhana - dengan menjalankan laporan khusus secara terprogram dan menerima hasilnya dalam bentuk file CSV.
Data pada pesan yang dipertukarkan antara dukungan dan pengguna sebagai bagian dari insiden dikembalikan dalam kasus ini dalam bentuk satu bidang teks besar, dengan seluruh riwayat korespondensi.
Informasi tentang panggilan pertama dari bidang seperti itu harus "dipotong" dengan ekspresi reguler.
- Semua pesan dipisahkan oleh garis karakteristik <when> - <who>.
- Pesan sering diakhiri dengan tanda tangan resmi, terutama jika permohonan diajukan melalui email. Informasi ini secara nyata "fonil" ada dalam daftar kata-kata penting, jadi tanda tangannya juga harus dihapus.
Ternyata sesuatu seperti ini:
def get_first_message(messages): res = "" if len(messages) > 0:
Memproses teks insiden
Untuk meningkatkan kualitas klasifikasi, teks banding telah diproses terlebih dahulu.
Menggunakan seperangkat ekspresi reguler dalam deskripsi kejadian, fragmen karakteristik ditemukan: tanggal, nama server, kode produk, alamat IP, alamat web, bentuk nama yang salah, dll. Fragmen seperti itu diganti dengan token konsep yang sesuai.
Pada akhirnya, gagap digunakan untuk membawa kata-kata ke bentuk umum. Ini memungkinkan kita untuk menyingkirkan bentuk jamak dan akhiran kata kerja. snowballstemmer
terkenal digunakan sebagai stemmer.
Semua proses pemrosesan digabungkan menjadi satu kelas transformasi, yang dapat digunakan dalam proses yang berbeda.
By the way, ternyata (percobaan, tentu saja) bahwa metode stemmer.stemWord()
tidak aman thread. Oleh karena itu, jika Anda mencoba menerapkan pemrosesan teks paralel dalam pipa, misalnya, menggunakan joblib
/ tertunda, maka akses ke instance umum stemmer harus dilindungi dengan kunci.
__replacements = [ ('(\d{1,3}\.){3}\d{1,3}', 'IPV4'), ('(?<=\W)((\d{2}[-\/ \.]?){2}(19|20)\d{2})|(19|20)\d{2}([-\/ \.]?\d{2}){2}(?=\W)', 'YYYYMMDD'), ('(?<=\W)(19|20)\d{2}(?=\W)', 'YYYY'), ('(?<=\W)(0|1)?\d\s?(am|pm)(?=\W)', 'HOUR'), ('http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', 'SOMEURL')
Vektorisasi
Vektorisasi dilakukan oleh TfidfVectorizer
standar dengan pengaturan berikut:
max_features
= 10000ngram
= (1,3) - dalam upaya untuk menangkap kombinasi stabil dan koneksi semantikmax_df
/ min_df
- dibiarkan secara defaultstop_words
- daftar standar kata-kata bahasa Inggris, ditambah set kata-kata tambahannya sendiri. Misalnya, beberapa pengguna menyebutkan nama analis, dan cukup sering nama yang tepat menjadi atribut yang signifikan.
TfidfVectorizer
sendiri melakukan normalisasi L2 secara default, sehingga vektor-vektor insiden siap untuk mengukur jarak kosinus di antara mereka.
Cari insiden serupa
Tugas utama dari proses ini adalah mengembalikan daftar tetangga N terdekat. Kelas sklearn.neighbors.NearestNeighbors
cukup cocok untuk ini. Satu masalah adalah bahwa ia tidak menerapkan metode transform
, yang tanpanya tidak dapat digunakan dalam pipeline
.
Oleh karena itu, perlu untuk membuatnya berdasarkan Transformer
, yang baru kemudian menempatkan pada langkah terakhir dari pipeline
:
class NearestNeighborsTransformer(NearestNeighbors, TransformerMixin): def __init__(self, n_neighbors=5, radius=1.0, algorithm='auto', leaf_size=30, metric='minkowski', p=2, metric_params=None, n_jobs=None, **kwargs): super(NearestNeighbors, self).__init__(n_neighbors=n_neighbors, radius=radius, algorithm=algorithm, leaf_size=leaf_size, metric=metric, p=p, metric_params=metric_params, n_jobs=n_jobs) def transform(self, X, y=None): res = self.kneighbors(X, self.n_neighbors, return_distance=True) return res
Proses pengolahan
Menyatukan semuanya, kami mendapatkan proses yang ringkas:
p = Pipeline( steps=[ ('grp', ColumnTransformer( transformers=[ ('text', Pipeline(steps=[ ('pp', CommentsTextTransformer(n_jobs=-1)), ("tfidf", TfidfVectorizer(stop_words=get_stop_words(), ngram_range=(1, 3), max_features=10000)) ]), ['short_description', 'comments', 'u_impacted_department'] ) ] )), ("nn", NearestNeighborsTransformer(n_neighbors=10, metric='cosine')) ], memory=None)
Setelah pelatihan, pipeline
dapat disimpan ke file menggunakan pickle
dan digunakan untuk menangani insiden yang masuk.
Bersama-sama dengan model, kita akan menyimpan bidang insiden yang diperlukan - untuk kemudian menggunakannya dalam output ketika model sedang berjalan.
Hasil aplikasi pertama
Reaksi kolega terhadap pengenalan sistem "petunjuk" pada umumnya sangat positif. Insiden berulang mulai diselesaikan lebih cepat, kami mulai mengerjakan pemecahan masalah.
Namun, orang tidak dapat mengharapkan keajaiban dari sistem pembelajaran yang tidak diawasi. Kolega mengeluh bahwa kadang-kadang sistem menawarkan tautan yang sama sekali tidak relevan. Kadang-kadang bahkan sulit untuk memahami dari mana rekomendasi tersebut berasal.
Sudah jelas bahwa bidang untuk meningkatkan model sangat besar. Beberapa kekurangan dapat diatasi, termasuk atau tidak termasuk beberapa atribut insiden. Bagian - dengan memilih tingkat cutoff yang memadai untuk jarak antara insiden saat ini dan "rekomendasi". Metode vektorisasi lain dapat dipertimbangkan.
Tetapi masalah utama adalah kurangnya metrik kualitas untuk rekomendasi. Dan jika demikian, tidak mungkin untuk memahami "apa yang baik dan apa yang buruk, dan berapa banyak", dan membangun perbandingan model pada ini.
Kami tidak memiliki akses ke log http, karena sistem layanan bekerja dari jarak jauh (SaaS). Kami melakukan survei pengguna - tetapi hanya secara kualitatif. Itu perlu untuk melanjutkan ke penilaian kuantitatif, dan membangun berdasarkan metrik kualitas yang jelas.
Tetapi lebih lanjut tentang itu di bagian selanjutnya ...