Maşın öyrənməsi ilə satışın artırılması

Lazım olanlar üçün təbii dil emalından necə istifadə edirik

Bu blog yazıda Xeneta-da satış prosesimizi şirkət təsvirlərinə əsaslanan rəhbərliyimizin keyfiyyətini proqnozlaşdırmaq üçün bir maşın öyrənmə alqoritmi hazırlamaqla daha effektiv etdiyimizi izah edəcəyəm.

Dərhal skriptlə tanış olmaq və davamlı inkişaf şəraitində yaxşılaşdırmağı təklif etmək istəsəniz GitHub-a baş çəkin.

Problem

Bu, şirkət adları ilə doldurulmuş böyük Excel vərəqlərindən keçmək üçün yorucu bir işi yerinə yetirməkdən bezmiş, hansınınla əlaqə saxlamağımızı müəyyənləşdirməyə çalışan yorğun vəzifəni yerinə yetirməkdən bezən, biznesin inkişafı üzrə nümayəndəsi Edvardın tələbi ilə başladı.

Əlaqə qura biləcək potensial şirkətlərin siyahısına misal, sec.gov saytından götürülmüşdür

Satış aparıcılarının bu cür qabaqcadan ixtisas seçimi saatlarla davam edə bilər, çünki satış nümayəndəsini hər bir şirkətin nə etdiyini (məsələn, LinkedIn-də oxu vasitəsilə oxumağı) anlamağa məcbur edir və beləliklə, o, ixtisaslı bir tahmin edə bilər. şirkət SaaS tətbiqimiz üçün yaxşı bir uyğunluqdur.

Bir ixtisaslı tahmini necə edirsiniz? Bunu başa düşmək üçün əvvəlcə nə etdiyimizi bilməlisiniz:

Əslində, Xeneta konteyner gəmisi göndərən şirkətlərə dəniz yük bazarının kəşfiyyatı ilə qənaət potensialını aşkar etməyə kömək edir.
Bu müştəri 748K ABŞ dolları dəyərində dəniz yük xərcləri ilə bazar ortalamasına qədər qənaət potensialına sahib idi.

Daha dəqiq desək, şirkətiniz ildə 500 konteynerdən yuxarı göndərirsə, Xeneta'dan istifadə edərək əhəmiyyətli qənaət potensialı tapacaqsınız, çünki bazarın orta qiymətindən yuxarı harada ödədiyinizi deyə bilərik.

Bu widget, bir müştərinin Çindən Şimali Avropaya gedən 20 aylıq konteyner üçün bazar nisbətini (bənövşəyi xətt) bazar ortalaması (yaşıl qrafik) ilə müqayisə edir.

Bu o deməkdir ki, hədəf müştərilərimiz bir-birlərindən tamamilə fərqlənirlər, çünki onların yeganə ortaq məxrəci dəniz nəqliyyatında bir qədər iştirak etdikləri deməkdir. Hədəfləndirdiyimiz şirkət kateqoriyasına aid bəzi nümunələr:

  • Avtomobil
  • Ekspeditor
  • Kimyəvi maddələr
  • İstehlakçı və pərakəndə satış
  • Az ödəyən mallar

Fərziyyə

Müştərilərin geniş çeşidi rəhbərlik tapmaqda bir problem yaratsa da, şirkətin təsvirini oxuyaraq bir şirkətin Xeneta üçün maraqlandığını və ya tez-tez məhsul göndərməkdə iştirak edib-etmədiyini göstərə biləcəyini söyləyə bilərik. dünya ətrafında.

Bu bizi düşünməyə vadar etdi:

Bir şirkətin təsvirini nəzərə alaraq, potensial Xeneta müştəri olub olmadığını təxmin etmək üçün bir alqoritm hazırlaya bilərikmi?

Əgər belədirsə, bu alqoritm satış qrupu üçün böyük bir vaxt qoruyucu kimi sübut edə bilər, belə ki, əl vərəqələrini əl ilə seçməyə başlamazdan qabaq kobud çeşidlənə bilər.

İnkişaf

Bu işə başladıqda tez bir zamanda maşın öyrənmə hissəsinin problem olmadığını başa düşdüm. Şirkət açıqlamalarını tutmaq üçün bir yola da ehtiyac duyduq.

Şirkətlərin veb saytlarını gəzməyi və Haqqımızda hissəsini götürməyi düşündük. Ancaq bu, qarışıq, gözlənilməz və vaxt aparan bir fəaliyyət kimi iyləndi, buna görə API-nin əvəzinə istifadə ediləcəyini axtarmağa başladıq. Bəzi axtarışlardan sonra milyonlarla şirkətin təsvirlərini təqdim edən bir şirkət API-si olan FullContact-ı aşkar etdik.

Lakin, onların API yalnız şirkət URL-lərinin nadir hallarda üstün vərəqlərimizdə olan girişləri qəbul edir.

Buna görə URL-in də əldə edilməsi üçün bir yol tapmalı olduq.

  • Şirkət adını google etmək üçün Google API-dən istifadə (hacky, bilirəm ...)
  • Axtarış nəticəsinə baxın və çox güman ki, düzgün URL tapın
  • Bu URL-i FullContact API-i soruşmaq üçün istifadə edin

Əlbətdə burada hər addımda itki var, buna görə daha yaxşı bir yol tapacağıq. Ancaq bu, fikri sınamaq üçün kifayət qədər yaxşı işlədi.

Məlumat bazası

Bu skriptlərin yerində olması, növbəti addım təlim məlumatlarımızı yaratmaq idi. Bunun üçün ən azı 1000 ixtisaslı şirkət və 1000 diskvalifikasiya edilmiş şirkətin olması lazım idi.

Birinci kateqoriya asan idi, çünki SalesForce-dən 1000 Xeneta istifadəçisinin siyahısını ixrac edə bildik.

Əlil 1000 tapılması biraz daha sərt oldu, çünki əlaqə qurmaqdan çəkindiyimiz şirkətləri izləmirik. Beləliklə, Edvard 1000 şirkəti əllə əlil etdi.

Məlumatların təmizlənməsi

Bununla, təbii dildə işləmə skriptini yazmağa başlamağın vaxtı gəldi, addımın əvvəlində təsvirləri təmizləmək lazım idi, çünki onlar olduqca çirklidir və çox sayda yersiz məlumatlar var.

Aşağıdakı nümunələrdə, hal-hazırda tətbiq etdiyimiz təmizlik texnikalarının hər birinə baxsam da, bir xam təsvirin nömrələr silsiləsi olaraq necə bitdiyini sizə göstərəcəyəm.

Xam təsvirə nümunə.

RegExp

Etdiyimiz ilk şey, əlifba olmayan simvollardan qurtulmaq üçün adi ifadələrdən istifadə etməkdir, çünki modelimiz yalnız sözləri öyrənə biləcəkdir.

təsvir = re.sub ("[^ a-zA-Z]", "", təsvir)
Əlifba olmayan simvolları çıxardıqdan sonra.

Kəklik

Sözləri də kökləyirik. Bu eyni sözün çox dəyişkənliyini kökünə endirmək deməkdir. Buna görə istehsalçı, manufasiya, istehsal və istehsal kimi sözləri qəbul etmək əvəzinə, onları istehsal etmək üçün daha da asanlaşdırırıq.

nltk.stem.snowball idxalından SnowballStemmer stemmer = QartopuStemmer ('english') təsviri = getDescription ()
təsviri = [təsvirdəki söz üçün stemmer.stem (söz)]
Sözləri dayandırdıqdan sonra.

Sözləri dayandırın

Daha sonra Natural Language Toolkit istifadə edərək stop sözləri çıxarırıq. Stop sözləri mətnin konseptual qavranılması üçün az əhəmiyyəti olan sözlərdir, məsələn, üçün, at, mən, bu və s.

nltk.corpus-dan idxal stopwords stopWords = set (stopwords.words ('english')) description = getDescription ()
description = [stopWords-da söz yox, təsvirdəki söz üçün söz]
Stop sözləri çıxardıqdan sonra.

Məlumatların dəyişdirilməsi

Lakin məlumatların təmizlənməsi və köklənməsi əslində hər hansı bir maşın öyrənməyimizə kömək etməyəcək, çünki təsvirləri də maşının başa düşdüyü bir şeyə çevirməyimiz lazımdır.

Sözlər çantası

Bunun üçün Sözlər Çantası (BoW) yanaşmasından istifadə edirik. BoW ilə tanış deyilsinizsə, bu Kaggle təlimini oxumağı məsləhət görərdim.

BoW, mətn ifadələrini vektorlara çevirmək üçün sadə bir texnikadır, burada vektorlarda hər bir maddə müəyyən bir söz təmsil edir. Scikit learn's CountVectorizer sizə bunun üçün super sadə yol təqdim edir:

sklearn.feature_extraction.text idxal CountVectorizer-dən
vektorizator = CountVectorizer (analizator = 'söz', max_feature = 5000) vektorizator.fit (təlim_data) vektorlaşdırılmış_training_data = vektorizator.transform (təlim_data)

Max_features parametri vektorizatora bizim lüğətimizdə neçə söz istədiyinizi bildirir. Bu misalda vektorizator, verilənlər bazamızda ən çox rast gəlinən və qalanlarını rədd edən 5000 sözləri əhatə edəcəkdir.

Sözlər vektorunun çox kiçik (35 element) çantasına nümunə. (Bizimki 5K maddədir).

Tf-idf çevrilmə

Nəhayət, müddətli tərs tərs sənəd tezliyi üçün qısa olan tf-idf çevrilməsini də tətbiq edirik. Sənədlərinizdəki fərqli sözlərin əhəmiyyətini tənzimləyən bir texnikadır.

Daha dəqiq desək, tf-idf tez-tez bir təsvirdə (müddət tezliyi) meydana çıxan sözləri, bütün verilənlər bazasında tez-tez meydana çıxan sözləri (tərs sənəd tezliyi) vurğulayacaqdır.

sklearn.feature_extraction.text idxalından TfidfTransformer tfidf = TfidfTransformer (norm = 'l1')
tfidf.fit (vectorized_training_data) tfidf_vectorized_data = tfidf.transform (vectorized_training_data)

Yenə də skikit öyrənmə, tf-idf qutusundan çıxartmaqla günə qənaət edir. Sadəcə modeli vektorlaşdırılmış təlim məlumatlarınıza uyğunlaşdırın və sonra çevirmək üçün transformasiya metodundan istifadə edin.

Tf-idf tətbiq edildikdən sonra vektor. (Pis formatlandığınız üçün üzr istəyirik)

Alqoritm

Bütün məlumatlar təmizləndikdən, vektorlaşdırıldıqdan və dəyişdirildikdən sonra nəhayət bu tapşırığın ən sadə hissələrindən olan maşın öyrənməsinə başlaya bilərik.

Əvvəlcə məlumatları 70% təlim məlumatlarına və 30% test məlumatlarına ayırdım və sonra iki skikit öyrənmə alqoritmləri ilə başladım: Random Meşə (RF) və K Yaxın Qonşular (KNN). Tez məlum oldu ki, RF KNN-ni qabaqladı, çünki əvvəllər 80% -dən çox dəqiqliyə çatdı, ikincisi 60% qaldı.

Bir skikit öyrənmə modelinə uyğunlaşmaq çox sadədir:

def runForest (X_train, X_test, Y_train, Y_test): meşə = RandomForestClassifier (n_estimators = 100) meşə = meşə.fit (X_train, Y_train) hesab = meşə.score (X_test, Y_test) qayıtma
meşə sahəsi = qaçış meşəsi (X_train, X_test, Y_train, Y_test)

Beləliklə, aşağıdakı parametrləri tənzimləyərək dəqiqliyi nə qədər artıra biləcəyimi görmək üçün RF ilə davam etdim:

  • Lüğət: CountVectorizer lüğətə neçə söz daxildir (hazırda 5K)
  • Gram Range: Sözlər Çantasına daxil ediləcək ifadələrin ölçüsü (hal-hazırda 1-3, '3 söz' qədər ifadələr daxil edilir)
  • Qiymətləndiricilər: Random Meşə daxil ediləcək qiymətləndiricilərin miqdarı (hazırda 90)

Bu parametrlər tənzimlənərək alqoritm sınaq məlumat bazasında 86,4% dəqiqliyə çatır və satış komandamız üçün faydalı olmağa başlayır.

Qarşıda yol

Lakin, skript heç bitməyib. Bunu yaxşılaşdırmağın bir çox yolu var. Məsələn, alqoritm hazırkı təlim məlumatlarımızdakı təsvirlərin növünə qarşı qərəzli ola bilər. Daha çox real dünya məlumatlarında test edərkən bu bir performans şüşəsinin boynuna çevrilə bilər.

Qarşıda yolda etməyi düşündüyümüz bir neçə iş var.

  • Daha çox məlumat əldə edin (qırıntılar, digər API-lər, məlumatların təmizlənməsini yaxşılaşdırın)
  • Məlumatların dəyişdirilməsinin digər növlərini sınayın (məsələn word2vec)
  • Digər ml alqoritmlərini sınayın (məsələn, sinir torları)

Tərəqqi izləmək istəyirsinizsə mütəmadi olaraq GitHub-a itələyəcəyik. Əlavə etmək istədikləriniz varsa aşağıda bir şərh yazmaqdan çekin.

Salam,

Harald Borgen başına

Oxuduğunuz üçün təşəkkür edirik! Biz Xeneta - dünyanın aparıcı dəniz yük kəşfiyyatı platformasıyıq. Bizə qoşulmaq üçün həmişə parlaq ağıl axtarırıq, əgər maraqlanırsınızsa veb saytımıza keçin!

Həm Twitter, həm də Orta olaraq bizi izləyə bilərsiniz.