Makine öğrenimi projeleri yinelemeli süreçlerdir. Başarılı bir modeli Jupyter defterinde elde etmekle iş bitmez. Model çevrimiçiyken ve insanlar erişebiliyorken de bitmez. Yayına aldıktan sonra bile, geliştirme aşamasındaki kadar iyi çalıştığından emin olmak için onu sürekli gözetmeniz gerekir.
Zillow skandalı, aksi halde neler olabileceğine mükemmel bir örnek. 2021’de Zillow, ev fiyatlarını tahmin eden makine öğrenimi modeli yüzünden şaşırtıcı bir şekilde 304 milyon dolar kaybetti. Zillow 7000’den fazla eve fazla ödeme yaptı ve bunları çok daha düşük bir fiyata elden çıkarmak zorunda kaldı. Şirket, kendi modeli tarafından “kazıklandı” ve iş gücünü %25 azaltmak zorunda kaldı.
Bu tür sessiz model hataları gerçek dünyadaki modellerde yaygındır; bu yüzden üretim performansı düşmeden önce modellerin sürekli güncellenmesi gerekir. Bunu yapmamak, şirketlerin itibarına, paydaşlarla olan güvene ve nihayetinde kasalarına zarar verir.
Bu makale, NannyML ile dağıtımdan sonra makine öğrenimi modellerini izlemek için uçtan uca bir iş akışını nasıl uygulayacağınızı öğretecek.
NannyML nedir?
NannyML, dağıtım sonrası makine öğrenimine odaklanan, büyüyen bir açık kaynak kütüphanesidir. Üretim ML ortamlarında ortaya çıkan her tür sorunu çözmek için geniş bir özellik yelpazesi sunar. Örnek vermek gerekirse:
Drift tespiti: Eğitim ve üretim verileri arasındaki veri dağılımı değişimlerini algılar.
Performans tahmini: Üretimde anlık gerçek değer olmadan model performansını tahmin eder.
Otomatik raporlama: Dağıtılan modelin sağlık ve performansına dair raporlar üretir.
Uyarı sistemi: Veri drift’i ve performans sorunları için uyarılar sağlar.
Model adaleti değerlendirmesi: Önyargıları önlemek için model adaletini izler.
ML çatılarıyla uyumluluk: Tüm makine öğrenimi çatılarıyla entegre olur.
Kullanıcı dostu arayüz: scikit-learn’e benzer tanıdık bir arayüz sunar.
Bu özelliklerin teknik yönlerini tek tek öğreneceğiz.
Önkoşul Kavramlar
Model izleme ile ilgili temel kavramları, okçuluğu ustalıkla öğrenen bir robot benzetmesi üzerinden öğreneceğiz.
Benzetmemizde:
Robot, makine öğrenimi modelimizi temsil eder.
Hedef, modelimizin amacı ya da hedef çıktısını temsil eder.
Okların tam ortaya (kırmızı noktaya) ne kadar isabet ettiğine göre skorlandığı için bunun bir regresyon problemi olduğunu söyleyebiliriz.
Okların ve yayların özellikleri ile robotun fiziksel özellikleri ve çevresel koşullar (rüzgâr, hava durumu gibi), modelimizin özellikleri ya da girdi değişkenleridir.
Öyleyse başlayalım.
Veri drift’i
Yayı, okları ve hedefi özenle hazırladığımızı (veri hazırlama gibi) hayal edin. Çok sayıda sensör ve kamerayla donatılmış robotumuz eğitim sırasında 10.000 kez atış yapıyor. Zamanla, hedefin tam ortasını etkileyici bir sıklıkla vurmaya başlıyor. Performanstan memnun kalıyoruz ve robotumuzu ve kopyalarını okçuluk meraklılarına satmaya (modeli dağıtmaya) başlıyoruz.
Ama kısa süre sonra şikâyetler gelmeye başlıyor. Bazı kullanıcılar robotun hedefi tamamen ıskaladığını bildiriyor. Şaşırıp neyin yanlış gittiğini tartışmak için bir ekip topluyoruz.
Bulduğumuz şey klasik bir veri drift’i vakası. Robotların çalıştığı ortam değişmiş — farklı rüzgâr desenleri, değişen nem seviyeleri ve hatta okların (ağırlık, denge) ve yayların fiziksel özelliklerinde değişimler.
Girdi özelliklerindeki bu gerçek dünya değişimi, robotumuzun doğruluğunu bozdu; tıpkı bir makine öğrenimi modelinin, özellikle özellikler arası ilişkiler zamanla değiştiğinde performansının düşmesi gibi.
Kavram drift’i
Bu sorunları ele aldıktan sonra yeni bir robot partisi çıkarıyoruz. Yine de birkaç hafta içinde benzer şikâyetler geliyor. Şaşkınlıkla daha derine iniyor ve kullanıcıların hedefleri sık sık değiştirdiğini keşfediyoruz.
Bu yeni hedefler farklı boyutlarda ve farklı mesafelere yerleştirilmiş. Bu değişim, robotun atış tekniğinde farklı bir yaklaşım gerektiriyor — kitabi bir kavram drift’i örneği.
Makine öğrenimi açısından, kavram drift’i, girdi değişkenleri ile hedef sonuç arasındaki ilişkinin değiştiğinde meydana gelir. Robotlarımız için yeni hedef türleri, artık farklı şekilde atış yapmaya uyum sağlamaları gerektiği anlamına geliyordu; tıpkı bir makine öğrenimi modelinin, eğitildiği verinin dinamikleri önemli ölçüde değiştiğinde uyum sağlaması gerektiği gibi.
Kavram ve veri drift’ine daha gerçek örnekler
Konuyu pekiştirmek için veri ve kavram drift’inin nasıl meydana geldiğine dair bazı gerçek dünya örneklerini inceleyelim.
Veri drift’i örnekleri
Kredi skorlama modelleri: Ekonomik dalgalanmalar insanların harcama ve kredi alışkanlıklarını değiştirir. Bir kredi skorlama modeli uyum sağlamazsa, yersiz reddetmelere ya da riskli onaylara yol açabilir.
Sağlık izleme sistemleri: Sağlıkta, kullanıcı demografisindeki değişimler veya sensör kalibrasyonu, hasta yaşamsal değerlerini izleyen modellerden hatalı sağlık değerlendirmeleri üretilmesine neden olabilir.
Perakende talep tahmini: Perakendede, tüketici davranışları ve trendlerdeki kaymalar, geçmiş satış verilerine dayalı modelleri mevcut ürün talebini tahminde etkisiz kılabilir.
Kavram drift’i örnekleri
Sosyal medya içerik moderasyonu: Moderasyon modelleri, uygunsuz kabul edileni yanlış sınıflandırma riskini azaltmak için sürekli evrilen dil ve kültürel olgulara uyum sağlamalıdır.
Otonom araçlar: Sürücüsüz araçlardaki modeller, en iyi performans için bölgeye özgü trafik kuralları ve koşulları için güncellenmelidir.
Sahtekârlık tespiti modelleri: Dolandırıcılık taktikleri geliştikçe, modellerin yeni ortaya çıkan örüntüleri tanımlayacak şekilde güncellenmesi gerekir.
Şimdi uçtan uca bir ML izleme iş akışını ele alalım.
Uçtan Uca Bir ML Model İzleme İş Akışı Nasıl Görünür?
Model izleme, ML mühendislerinin yinelemeli olarak takip etmesi gereken üç ana adımdan oluşur.
1. Performansı izleme
İlk adım elbette, modelin dağıtım ortamındaki performansını yakından takip etmektir. Ancak söylemesi kolay, yapması zordur.
Gerçek değer üretimde bir modele anında sağlanabiliyorsa, model davranışındaki değişiklikleri tespit etmek kolaydır. Örneğin, robot/okçuluk benzetmemizde kullanıcılar hedefe bakıp robotun ıskaladığını söyleyebilir — anlık gerçek değer.
Buna karşılık, kredi temerrüdünü tahmin eden bir modeli düşünün. Bu tür modeller, bir kullanıcının gelecek ay ödemeyi aksatıp aksatmayacağını tahmin eder. Tahmini doğrulamak için modelin gerçek ödeme tarihini beklemesi gerekir. Bu, gerçek dünyadaki makine öğrenimi sistemlerinde en yaygın olan gecikmeli gerçek değer örneğidir.
Bu gibi durumlarda, modellerin iyi performans gösterip göstermediğini görmek için gerçek değerin gelmesini beklemek çok maliyetlidir. Bu yüzden ML mühendislerinin, gerçek değer olmadan model performansını tahmin etme yöntemlerine ihtiyacı vardır. İşte bu noktada CBPE veya DLE gibi algoritmalar devreye girer (az sonra değineceğiz).
Modelleri izlemek, doğrudan iş etkisini ölçerek de yapılabilir; yani KPI’ları (temel performans göstergeleri) izlemek. Zillow örneğinde, uygun bir izleme sistemi kâr kaybını tespit edip mühendislere uyarı verebilirdi (varsayımsal).
2. Kök neden analizi
İzleme sistemi, ister gerçekleşmiş performansı (gerçek değerle) ister tahmini performansı (gerçek değer olmadan) analiz etsin, bir performans düşüşü algılarsa, ML mühendisleri düşüşün arkasındaki nedeni belirlemelidir.
Bu genellikle, veri (özellik drift’i) için özellikleri tek tek veya kombinasyon halinde ve kavram drift’i için hedefleri incelemeyi içerir.
Bulgularına dayanarak çeşitli sorun çözme teknikleri uygularlar.
3. Sorun çözümü
İşte dağıtımdan sonra performans düşüşünün yol açtığı hasarı azaltmak için kullanılan tekniklerden seçkisiz bir liste:
Veri yeniden dengeleme: Performans düşüşü veri drift’inden kaynaklanıyorsa, eğitim veri kümesini mevcut koşulları yansıtacak şekilde ayarlamak iyi bir seçenektir.
Özellik mühendisliği: Özellikleri güncellemek veya yenilerini oluşturmak model performansını iyileştirebilir. Bu, girdiler ile çıktılar arasındaki ilişkinin değiştiği kavram drift’i durumlarında iyi bir yaklaşımdır.
Modeli yeniden eğitme: Daha maliyetli bir yöntem, modelin güncel verilerle yeniden eğitilmesidir. Hem veri hem de kavram drift’inde iyi çalışır.
Modeli ince ayar yapma: Baştan eğitmek yerine, bazı modeller daha güncel bir veri kümesi üzerinde ince ayar yapılabilir. Bu, derin öğrenme ve üretken modellerle iyi çalışır.
Anomali tespiti: Anomali (yenilik) tespiti yöntemleri, üretim verilerindeki olağandışı örüntüleri erken safhada belirleyebilir.
Alan uzmanlığı katılımı: Alan uzmanlarını dâhil etmek, modellerin neden düşük performans gösterdiğine dair derin içgörüler sağlayabilir.
Her yöntemin uygulanacağı bağlam farklıdır ve çoğu zaman bunların bir kombinasyonunu hayata geçirmeniz gerekebilir.
NannyML bu yinelemeli sürecin ilk iki adımıyla ilgilenir. Öyleyse başlayalım.
Adım 1: NannyML için Veriyi Hazırlama
Eğitim ve doğrulama setlerine ek olarak, NannyML’in izlemeye başlaması için belirli formatlarda başvuru (reference) ve analiz (analysis) adında iki ek sete ihtiyacı vardır. Bu bölüm, bunları herhangi bir veriden nasıl oluşturacağınızı öğretir.
Öncelikle, izleyebilmemiz için hâlihazırda eğitilmiş ve üretime alınmaya hazır bir modele ihtiyacımız var. Bu amaçla diamonds veri kümesini kullanacak ve bir XGBoost regresörü eğiteceğiz.
Veriyi yükleme, özellikleri ve hedefi tanımlama
import warnings
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
warnings.filterwarnings("ignore")Altyapı:
Modülleri içe aktardıktan sonraki ilk adım, Seaborn’dan Diamonds veri setini yüklemektir. Ancak bu makalede izleme sürecinin nasıl göründüğünü göstermek için özel olarak hazırladığım bir veri seti sürümünü kullanacağız. Aşağıdaki parçacıkla veri setini ortamınıza yükleyebilirsiniz:
Bu özel sürümde “set” adlı bir sütun var; birazdan buna geleceğiz.
Şimdilik, tüm özellik adlarını, kategorik özellik adlarını ve hedef adını çıkaralım:
# Extract all feature names
all_feature_names = diamonds_special.drop(["price","set"], axis=1).columns.tolist()# Extract the columns and cast into category
cats = diamonds_special.select_dtypes(exclude=np.number).columns
# Define the target column
target ="price"Altyapı:
Görev bir regresyon — elmasların fiziksel özelliklerinden yola çıkarak fiyatlarını tahmin edeceğiz.
Diamonds veri seti oldukça temizdir. Bu nedenle yaptığımız tek ön işleme, metin özelliklerini Pandas category veri tipine dönüştürmektir. Bu, XGBoost’un kategorik verileri otomatik işlemesini etkinleştirmek için bir gereksinimdir.
for col in cats:
diamonds_special[col]= diamonds_special[col].astype("category")Altyapı:
Veriyi bölmeye geçelim.
Veriyi dört sete ayırma
Evet, doğru okudunuz. Veriyi dört sete böleceğiz. Geleneksel olarak yalnızca üçe bölebilirsiniz:
Eğitim seti modelin örüntüleri öğrenmesi için
Doğrulama seti hiperparametre ayarı için
Test seti dağıtımdan önce son değerlendirme için
Model izleme iş akışları, üretim verisini taklit etmek için başka bir sete ihtiyaç duyar. Bu, sistemimizin doğru algoritmaları kullanarak performans düşüşlerini doğru bir şekilde tespit ettiğinden ve neyin yanlış gittiğini raporladığından emin olmak içindir.
Bu amaçla, Diamonds Special’daki satırları set sütununda dört kategoriyle etiketledim:
Eğitim seti toplamın %70’ini, geri kalanı ise %10’arını temsil eder. Hadi bölelim:
tr = diamonds_special[diamonds_special.set=="train"].drop("set", axis=1)
val = diamonds_special[diamonds_special.set=="validation"].drop("set", axis=1)
test = diamonds_special[diamonds_special.set=="test"].drop("set", axis=1)
prod = diamonds_special[diamonds_special.set=="prod"].drop("set", axis=1)
tr.shape
(37758,10)Altyapı:
Ancak, gerçek dünya veri setleri yerleşik set etiketleriyle gelmez; dolayısıyla veriyi dört sete kendiniz elle bölmeniz gerekir. İşte sklearn’den train_test_split kullanarak bu işi yapan bir fonksiyon:
defsplit_into_four(df, train_size=0.7):"""
A function to split a dataset into four sets:
- Training
- Validation
- Testing
- Production
train_size is set by the user.
The remaining data will be equally divided between the three sets.
"""# Do the splits
training, the_rest = train_test_split(df, train_size=train_size)
validation, the_rest = train_test_split(the_rest, train_size=1/3)
testing, production = train_test_split(the_rest, train_size=0.5)# Reset the indices
sets =(training, validation, testing, production)forsetin sets:set.reset_index(inplace=True, drop=True)return sets
tr, val, test, prod = split_into_four(your_dataset)Altyapı:
Not: Fonksiyonun satır satır açıklaması için “Kodu Açıkla” düğmesini kullanın.
Şimdi model eğitimine geçelim.
Model eğitimi
Bir XGBoost modelini eğitmeden önce veri setlerini DMatrix’e dönüştürmemiz gerekir. Kod şöyle:
Şimdi, hiperparametreleri önceden ayarlanmış bir regresörü eğitmek için kod:
# Define optimized parameters
params ={"n_estimators":10000,"learning_rate":0.1,"tree_method":"gpu_hist","max_depth":6,"min_child_weight":1,"gamma":0,"subsample":0.8,"colsample_bytree":0.8,"objective":"reg:squarederror","reg_alpha":0.01,"reg_lambda":1,}# Training with early stopping
regressor = xgb.train(
params,
dtrain,
num_boost_round=10000,
evals=[(dtrain,"train"),(dval,"eval")],
early_stopping_rounds=50,
verbose_eval=500,)[0] train-rmse:3638.77217eval-rmse:0.00000[49] train-rmse:502.61376eval-rmse:0.00000Altyapı:
Harika — doğrulama setinde RMSE açısından 503$ elde eden bir modelimiz var. Modeli test setinde son bir kez değerlendirelim:
from sklearn.metrics import mean_squared_error
# Predict on the test set
y_test_pred = regressor.predict(dtest)# Evaluate
mean_squared_error(test[target], y_test_pred, squared=False)551.2763827068798Altyapı:
Test performansı 551$. Bu yeterince iyi.
Başvuru seti oluşturma
Bu noktaya kadar her şey oldukça düz ilerledi. Şimdi işin esas kısmına geliyoruz — başvuru ve analiz setlerini oluşturma.
Başvuru seti, model izleme bağlamında test setinin başka bir adıdır. NannyML, üretim performansı için modelin test setindeki performansını bir temel çizgi olarak kullanır. Başvuru setinde özelliklere ek olarak iki sütun olmalıdır:
Hedefin kendisi — gerçek değer — elmas fiyatları
Test tahminleri — bunları y_test_pred içinde ürettik
Şu anda test setimiz özellikleri ve hedefi içeriyor ama y_test_pred eksik:
test.columns # Ignore the `set` column
Index(['carat','cut','color','clarity','depth','table','price','x','y','z'],
dtype='object')Altyapı:
Bu noktada, regresörümüzün bulutta dağıtıldığını hayal edelim. Hayal etmek, bu makale için fazla kaçacak gerçek bir dağıtımdan daha kolay.
Elmas fiyatlama modelimizi dağıttıktan sonra, büyük bir elmas sevkiyatının yolda olduğu haberini alıyoruz. Kargo gelmeden önce, elmasların fiziksel ölçümleri bize prod olarak gönderildi (hâlâ hayal ediyoruz) ki biz de onlar için fiyat üretebilelim ve web sitemizde pazarlamaya başlayabilelim. Hadi üretelim.
# Generate prices for production data
y_prod_pred = regressor.predict(dprod)Altyapı:
Gerçek elmaslar gelmeden ve bir insan uzman, modelimizin ürettiği fiyatları doğrulamadan önce, modelimizin iyi performans gösterip göstermediğini kontrol etmeliyiz. Web sitemizde hatalı fiyatlarla elmas sergilemek istemeyiz.
Bunu yapmak için, y_prod_pred ile yeni elmasların gerçek fiyatlarını, yani gerçek değeri karşılaştırarak modelin performansını ölçmemiz gerekir. Ancak fiyatlar doğrulanmadan elimizde gerçek değer olmayacak. Dolayısıyla, gerçek değer olmadan modelin performansını tahmin etmemiz gerekecek.
Bu işi yapmak için NannyML, model tarafından yapılan tahminleri içeren üretim verilerinden oluşan bir analiz seti ister.
# Add the predictions of new diamonds to prod
prod["y_pred"]= y_prod_pred
analysis = prod.copy(deep=True)
analysis.columns
Index(['carat','cut','color','clarity','depth','table','price','x','y','z','y_pred'],
dtype='object')Altyapı:
Artık regressor’ün performansını tahmin etmeye hazırız.
Adım 2: NannyML’de Performansı Tahmin Etme
NannyML, regresyon ve sınıflandırma modellerinin performansını tahmin etmek için iki ana algoritma sağlar:
Doğrudan Kayıp Tahmini (DLE) — regresyon için
Güvene Dayalı Performans Tahmini (CBPE) — sınıflandırma için
Görevimiz için DLE algoritmasını kullanacağız. DLE, gerçek değer olmadan üretim modelinin performansını ölçebilir ve RMSE, RMSLE, MAE vb. çeşitli regresyon sahte-metriklerini raporlayabilir.
DLE kullanmak için önce temel performansı belirlemek amacıyla reference üzerinde onu fit etmemiz gerekir.
DLE’yi başlatmak üç parametre gerektirir — girdi özellik adları, test için gerçek değeri içeren sütunun adı ve test tahminlerini içeren sütunun adı.
Ayrıca metrik olarak RMSE ve 250’lik parça boyutu da geçiyoruz. Tahminleyiciyi reference’a fit edip analysis üzerinde performansı tahmin edelim:
# Fit to the reference set
estimator.fit(reference)# Estimate on the analysis set
estimated_results = estimator.estimate(analysis)
estimated_results
<nannyml.performance_estimation.direct_loss_estimation.result.Result at 0x7f3954af1c90>Altyapı:
Elimizde görselleştirilebilen bir NannyML Result nesnesi var. Ne ürettiğine bakalım:
Grafiği yorumlayalım — başvuru ve analiz setlerindeki performansı gösteren iki bölüm var. Üretimde tahmin edilen RMSE eşikleri aştığında, NannyML bunları uyarı olarak işaretler.
Gördüğümüz gibi, üretim verileri için birkaç uyarı var; bu da son yığınlarda ters giden bir şeyler olduğuna işaret ediyor.
Adım 3: İzlemede Tahmini ve Gerçekleşmiş Performans
İzleme sistemimiz, model performansının üretimde yaklaşık yarı yarıya düştüğünü söylüyor. Ancak bu yalnızca bir tahmin — kesin konuşamayız.
Biz tahmini performansı çizerken, sevkiyat geldi ve elmas uzmanımız gerçek fiyatlarını hesapladı. Bunları prod içine price olarak kaydettik.
Artık modelin gerçekleşmiş performansını (gerçek performans) tahmini performansla karşılaştırıp izleme sistemimizin iyi çalışıp çalışmadığını görebiliriz.
NannyML bunu yapmak için bir PerformanceCalculator sınıfı sağlar:
Görünüşe göre tahmini RMSE (mor), gerçekleşmiş performansa (mavi, gerçekleşmiş RMSE) oldukça yakın.
Bu bize tek bir şey söylüyor — izleme sistemimiz iyi çalışıyor, ama modelimiz değil; yükselen kayıp bunun göstergesi. Öyleyse nedeni(leri) ne?
Şimdi buna dalacağız.
Adım 4: Drift Tespit Yöntemleri
Girişte de belirtildiği gibi, modellerin üretimde başarısız olmasının en yaygın nedenlerinden biri drift’tir. Bu bölümde veri (özellik) drift’i tespitine odaklanacağız.
Drift tespiti, model izleme iş akışının kök neden analizi adımının bir parçasıdır. Genellikle çok değişkenli drift tespitiyle başlar.
Çok değişkenli drift tespiti
En iyi çok değişkenli drift tespit yöntemlerinden biri, PCA kullanarak veri yeniden oluşturma hatasını hesaplamaktır. Son derece iyi çalışır ve özellik dağılımlarındaki en küçük drift’leri bile yakalayabilir. Bu yöntemin üst düzey özeti şöyledir:
1. PCA, reference üzerine fit edilir ve daha düşük boyuta sıkıştırır — reference_lower.
Bu adımda, PCA’nın doğası gereği orijinal veri seti hakkında bir miktar bilgi kaybolur.
2. reference_lower ardından orijinal boyutuna geri açılır — reference_reconstructed.
1. adımda bilgi kaybı olduğundan, yeniden oluşturulan veriler reference ile tamamen aynı olmayacaktır.
3. reference ile reference_reconstructed arasındaki fark bulunur ve veri yeniden oluşturma hatası — reconstruct_error olarak adlandırılır.
reconstruct_error, üretim verisinin yeniden oluşturma hatasını karşılaştırmak için bir temel çizgi işlevi görür
4. Aynı indirgeme/yeniden oluşturma yöntemi, üretim verilerinin yığınlarına uygulanır.
Üretim verisinin yeniden oluşturma hatası temel çizgiden yüksekse, özelliklerin drift ettiğini söyleriz.
Sistem, üretim verisini daha fazla incelememizi isteyen bir uyarı gönderir
Bu dört adım, NannyML’de DataReconstructionDriftCalculator sınıfı olarak uygulanmıştır. Şöyle kullanılır:
Gördüğümüz gibi, yeniden oluşturma hatası çok yüksek; bu da özelliklerde drift olduğuna işaret ediyor. Hatayı gerçekleşmiş performansla da karşılaştırabiliriz:
Gördüğümüz üzere, kayıptaki tüm sıçramalar, yeniden oluşturma hatasındaki uyarılarla örtüşüyor.
Tek değişkenli drift tespiti
Veri yeniden oluşturma hatası, tüm özellikler için drift’i ölçen tek bir sayıdır. Peki ya tekil özelliklerin drift’i? Veri setimiz yüzlerce özellik içerseydi, en çok drift eden özellikleri nasıl bulur ve uygun önlemleri alırdık?
İşte burada tek değişkenli drift tespit yöntemlerini kullanırız. NannyML, özellik tipine bağlı olarak birkaç yöntem sunar:
Kategorik özellikler: L-infinity, Chi2
Sürekli özellikler: Wasserstein, Kolmogorov-Smirnov testi
Her ikisi: Jensen-Shannon uzaklığı, Hellinger uzaklığı
Hepsi, reference içindeki tekil özelliklerin dağılımını analysis setindekilerle karşılaştırır. Bunların bazılarını (hatta hepsini) UnivariateDriftCalculator sınıfı içinde kullanabiliriz:
Gerekli tek parametre column_names’tir; geri kalanı NannyML’in varsayılanlarını kullanabilir. Ancak basit tutmak için, sürekli özellikler için wasserstein, kategorikler için jensen_shannon kullanıyoruz.
Şu an 11 özelliğimiz var; bu yüzden doğrudan plot().show() çağırmak en uygun sonucu vermeyebilir. Bunun yerine, tüm parçalar dikkate alındığında en çok sayıda uyarı üreten özellikleri döndüren bir uyarı sayısı sıralayıcısı kullanabiliriz. Kod şöyle:
# Initialize the ranker
alert_count_ranker = nannyml.AlertCountRanker()# Filter the univariate results for only columns containing the metrics
filtered_univariate = univariate_results.filter(
continuous_methods=["wasserstein"],
categorical_methods=["jensen_shannon"],
only_drifting=False,)# Rank the alerts
ranker_results = alert_count_ranker.rank(filtered_univariate)Altyapı:
Sıralayıcı sonuçlarını aldıktan sonra, bir Pandas DataFrame olduğu için başını yazdırabiliriz:
En sorunlu özelliklerin color ve depth olduğunu görüyoruz. Bu beni şaşırtmamalı; zira makaleyi yazmadan önce drift’i yapay olarak ben oluşturmuştum.
Ama bu gerçek bir senaryo olsaydı, bu özellikler için sorun çözümüne zaman ayırmak isterdiniz.
Sonuç
Model izlemeyi ilgi çekici buluyorum; çünkü iyi bir model elde edildiğinde makine öğreniminin bittiği yanılgısını yıkıyor. Dünya döndükçe ve kullanıcı örüntüleri değiştikçe hiçbir model uzun süre güncel kalmaz. Bu da model izlemesini her ML mühendisi için kritik bir beceri yapar.
Bugün temel bir model izleme iş akışını ele aldık. Önce temel izleme kavramlarından bahsettik. Sonra doğrudan koda daldık: veriyi NannyML ile uyumlu bir formata getirdik; tahmini model performansı için ilk grafiğimizi oluşturduk, bunu gerçekleşmiş performansla karşılaştıran başka bir grafik yaptık; performans düşüşüne dair birkaç uyarı aldık; çok değişkenli drift tespitiyle kontrol ettik; güçlü özellik drift’i bulduk; tekil özellik drift tespitiyle tekrar doğruladık; drift eden özellikleri belirledik.
Ne yazık ki, sorun çözümü adımında durduk. İzleme iş akışının bu son adımı bu makalenin kapsamı dışında. Ancak bunu ve model izlemenin çok daha fazlasını kapsayan bazı harika önerilerim var:
Bu iki kurs da isteyebileceğiniz en iyi kişi tarafından — NannyML’in CEO’su ve kurucusu — hazırlandı. Kaçırmamanız gereken pek çok bilgi kırıntısı içeriyorlar.
2 yılı aşkın deneyime sahip bir veri bilimi içerik üreticisiyim ve Medium’da en büyük takipçi kitlelerinden birine sahibim. Yapay zekâ ve makine öğrenimi üzerine, biraz da alaycı bir üslupla yazılmış, ayrıntılı makaleler kaleme almayı seviyorum; çünkü onları biraz daha az sıkıcı hale getirmek için bir şeyler yapmak gerekiyor. 130’un üzerinde makale ve bir de DataCamp kursu ürettim; bir diğeri de hazırlık aşamasında. İçeriklerim 5 milyondan fazla kişi tarafından görüldü; bunların 20 bini Medium ve LinkedIn’de takipçim oldu.
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Neden ML Modelleri İzlenir?
Makine öğrenimi projeleri yinelemeli süreçlerdir. Başarılı bir modeli Jupyter defterinde elde etmekle iş bitmez. Model çevrimiçiyken ve insanlar erişebiliyorken de bitmez. Yayına aldıktan sonra bile, geliştirme aşamasındaki kadar iyi çalıştığından emin olmak için onu sürekli gözetmeniz gerekir.
Zillow skandalı, aksi halde neler olabileceğine mükemmel bir örnek. 2021’de Zillow, ev fiyatlarını tahmin eden makine öğrenimi modeli yüzünden şaşırtıcı bir şekilde 304 milyon dolar kaybetti. Zillow 7000’den fazla eve fazla ödeme yaptı ve bunları çok daha düşük bir fiyata elden çıkarmak zorunda kaldı. Şirket, kendi modeli tarafından “kazıklandı” ve iş gücünü %25 azaltmak zorunda kaldı.
Bu tür sessiz model hataları gerçek dünyadaki modellerde yaygındır; bu yüzden üretim performansı düşmeden önce modellerin sürekli güncellenmesi gerekir. Bunu yapmamak, şirketlerin itibarına, paydaşlarla olan güvene ve nihayetinde kasalarına zarar verir.
Bu makale, NannyML ile dağıtımdan sonra makine öğrenimi modellerini izlemek için uçtan uca bir iş akışını nasıl uygulayacağınızı öğretecek.
NannyML nedir?
NannyML, dağıtım sonrası makine öğrenimine odaklanan, büyüyen bir açık kaynak kütüphanesidir. Üretim ML ortamlarında ortaya çıkan her tür sorunu çözmek için geniş bir özellik yelpazesi sunar. Örnek vermek gerekirse:
Bu özelliklerin teknik yönlerini tek tek öğreneceğiz.
Önkoşul Kavramlar
Model izleme ile ilgili temel kavramları, okçuluğu ustalıkla öğrenen bir robot benzetmesi üzerinden öğreneceğiz.
Benzetmemizde:
Öyleyse başlayalım.
Veri drift’i
Yayı, okları ve hedefi özenle hazırladığımızı (veri hazırlama gibi) hayal edin. Çok sayıda sensör ve kamerayla donatılmış robotumuz eğitim sırasında 10.000 kez atış yapıyor. Zamanla, hedefin tam ortasını etkileyici bir sıklıkla vurmaya başlıyor. Performanstan memnun kalıyoruz ve robotumuzu ve kopyalarını okçuluk meraklılarına satmaya (modeli dağıtmaya) başlıyoruz.
Ama kısa süre sonra şikâyetler gelmeye başlıyor. Bazı kullanıcılar robotun hedefi tamamen ıskaladığını bildiriyor. Şaşırıp neyin yanlış gittiğini tartışmak için bir ekip topluyoruz.
Bulduğumuz şey klasik bir veri drift’i vakası. Robotların çalıştığı ortam değişmiş — farklı rüzgâr desenleri, değişen nem seviyeleri ve hatta okların (ağırlık, denge) ve yayların fiziksel özelliklerinde değişimler.
Girdi özelliklerindeki bu gerçek dünya değişimi, robotumuzun doğruluğunu bozdu; tıpkı bir makine öğrenimi modelinin, özellikle özellikler arası ilişkiler zamanla değiştiğinde performansının düşmesi gibi.
Kavram drift’i
Bu sorunları ele aldıktan sonra yeni bir robot partisi çıkarıyoruz. Yine de birkaç hafta içinde benzer şikâyetler geliyor. Şaşkınlıkla daha derine iniyor ve kullanıcıların hedefleri sık sık değiştirdiğini keşfediyoruz.
Bu yeni hedefler farklı boyutlarda ve farklı mesafelere yerleştirilmiş. Bu değişim, robotun atış tekniğinde farklı bir yaklaşım gerektiriyor — kitabi bir kavram drift’i örneği.
Makine öğrenimi açısından, kavram drift’i, girdi değişkenleri ile hedef sonuç arasındaki ilişkinin değiştiğinde meydana gelir. Robotlarımız için yeni hedef türleri, artık farklı şekilde atış yapmaya uyum sağlamaları gerektiği anlamına geliyordu; tıpkı bir makine öğrenimi modelinin, eğitildiği verinin dinamikleri önemli ölçüde değiştiğinde uyum sağlaması gerektiği gibi.
Kavram ve veri drift’ine daha gerçek örnekler
Konuyu pekiştirmek için veri ve kavram drift’inin nasıl meydana geldiğine dair bazı gerçek dünya örneklerini inceleyelim.
Veri drift’i örnekleri
Kavram drift’i örnekleri
Şimdi uçtan uca bir ML izleme iş akışını ele alalım.
Uçtan Uca Bir ML Model İzleme İş Akışı Nasıl Görünür?
Model izleme, ML mühendislerinin yinelemeli olarak takip etmesi gereken üç ana adımdan oluşur.
1. Performansı izleme
İlk adım elbette, modelin dağıtım ortamındaki performansını yakından takip etmektir. Ancak söylemesi kolay, yapması zordur.
Gerçek değer üretimde bir modele anında sağlanabiliyorsa, model davranışındaki değişiklikleri tespit etmek kolaydır. Örneğin, robot/okçuluk benzetmemizde kullanıcılar hedefe bakıp robotun ıskaladığını söyleyebilir — anlık gerçek değer.
Buna karşılık, kredi temerrüdünü tahmin eden bir modeli düşünün. Bu tür modeller, bir kullanıcının gelecek ay ödemeyi aksatıp aksatmayacağını tahmin eder. Tahmini doğrulamak için modelin gerçek ödeme tarihini beklemesi gerekir. Bu, gerçek dünyadaki makine öğrenimi sistemlerinde en yaygın olan gecikmeli gerçek değer örneğidir.
Bu gibi durumlarda, modellerin iyi performans gösterip göstermediğini görmek için gerçek değerin gelmesini beklemek çok maliyetlidir. Bu yüzden ML mühendislerinin, gerçek değer olmadan model performansını tahmin etme yöntemlerine ihtiyacı vardır. İşte bu noktada CBPE veya DLE gibi algoritmalar devreye girer (az sonra değineceğiz).
Modelleri izlemek, doğrudan iş etkisini ölçerek de yapılabilir; yani KPI’ları (temel performans göstergeleri) izlemek. Zillow örneğinde, uygun bir izleme sistemi kâr kaybını tespit edip mühendislere uyarı verebilirdi (varsayımsal).
2. Kök neden analizi
İzleme sistemi, ister gerçekleşmiş performansı (gerçek değerle) ister tahmini performansı (gerçek değer olmadan) analiz etsin, bir performans düşüşü algılarsa, ML mühendisleri düşüşün arkasındaki nedeni belirlemelidir.
Bu genellikle, veri (özellik drift’i) için özellikleri tek tek veya kombinasyon halinde ve kavram drift’i için hedefleri incelemeyi içerir.
Bulgularına dayanarak çeşitli sorun çözme teknikleri uygularlar.
3. Sorun çözümü
İşte dağıtımdan sonra performans düşüşünün yol açtığı hasarı azaltmak için kullanılan tekniklerden seçkisiz bir liste:
Her yöntemin uygulanacağı bağlam farklıdır ve çoğu zaman bunların bir kombinasyonunu hayata geçirmeniz gerekebilir.
NannyML bu yinelemeli sürecin ilk iki adımıyla ilgilenir. Öyleyse başlayalım.
Adım 1: NannyML için Veriyi Hazırlama
Eğitim ve doğrulama setlerine ek olarak, NannyML’in izlemeye başlaması için belirli formatlarda başvuru (reference) ve analiz (analysis) adında iki ek sete ihtiyacı vardır. Bu bölüm, bunları herhangi bir veriden nasıl oluşturacağınızı öğretir.
Öncelikle, izleyebilmemiz için hâlihazırda eğitilmiş ve üretime alınmaya hazır bir modele ihtiyacımız var. Bu amaçla diamonds veri kümesini kullanacak ve bir XGBoost regresörü eğiteceğiz.
Veriyi yükleme, özellikleri ve hedefi tanımlama
Modülleri içe aktardıktan sonraki ilk adım, Seaborn’dan Diamonds veri setini yüklemektir. Ancak bu makalede izleme sürecinin nasıl göründüğünü göstermek için özel olarak hazırladığım bir veri seti sürümünü kullanacağız. Aşağıdaki parçacıkla veri setini ortamınıza yükleyebilirsiniz:
Bu özel sürümde “set” adlı bir sütun var; birazdan buna geleceğiz.
Şimdilik, tüm özellik adlarını, kategorik özellik adlarını ve hedef adını çıkaralım:
Görev bir regresyon — elmasların fiziksel özelliklerinden yola çıkarak fiyatlarını tahmin edeceğiz.
Diamonds veri seti oldukça temizdir. Bu nedenle yaptığımız tek ön işleme, metin özelliklerini Pandas
categoryveri tipine dönüştürmektir. Bu, XGBoost’un kategorik verileri otomatik işlemesini etkinleştirmek için bir gereksinimdir.Veriyi bölmeye geçelim.
Veriyi dört sete ayırma
Evet, doğru okudunuz. Veriyi dört sete böleceğiz. Geleneksel olarak yalnızca üçe bölebilirsiniz:
Model izleme iş akışları, üretim verisini taklit etmek için başka bir sete ihtiyaç duyar. Bu, sistemimizin doğru algoritmaları kullanarak performans düşüşlerini doğru bir şekilde tespit ettiğinden ve neyin yanlış gittiğini raporladığından emin olmak içindir.
Bu amaçla, Diamonds Special’daki satırları
setsütununda dört kategoriyle etiketledim:Eğitim seti toplamın %70’ini, geri kalanı ise %10’arını temsil eder. Hadi bölelim:
Ancak, gerçek dünya veri setleri yerleşik set etiketleriyle gelmez; dolayısıyla veriyi dört sete kendiniz elle bölmeniz gerekir. İşte
sklearn’dentrain_test_splitkullanarak bu işi yapan bir fonksiyon:Not: Fonksiyonun satır satır açıklaması için “Kodu Açıkla” düğmesini kullanın.
Şimdi model eğitimine geçelim.
Model eğitimi
Bir XGBoost modelini eğitmeden önce veri setlerini DMatrix’e dönüştürmemiz gerekir. Kod şöyle:
Şimdi, hiperparametreleri önceden ayarlanmış bir regresörü eğitmek için kod:
Harika — doğrulama setinde RMSE açısından 503$ elde eden bir modelimiz var. Modeli test setinde son bir kez değerlendirelim:
Test performansı 551$. Bu yeterince iyi.
Başvuru seti oluşturma
Bu noktaya kadar her şey oldukça düz ilerledi. Şimdi işin esas kısmına geliyoruz — başvuru ve analiz setlerini oluşturma.
Başvuru seti, model izleme bağlamında test setinin başka bir adıdır. NannyML, üretim performansı için modelin test setindeki performansını bir temel çizgi olarak kullanır. Başvuru setinde özelliklere ek olarak iki sütun olmalıdır:
y_test_prediçinde ürettikŞu anda test setimiz özellikleri ve hedefi içeriyor ama
y_test_predeksik:Ekleyelim:
Şimdi test setini
referenceolarak yeniden adlandıracağız:Analiz seti oluşturma
Bu noktada, regresörümüzün bulutta dağıtıldığını hayal edelim. Hayal etmek, bu makale için fazla kaçacak gerçek bir dağıtımdan daha kolay.
Elmas fiyatlama modelimizi dağıttıktan sonra, büyük bir elmas sevkiyatının yolda olduğu haberini alıyoruz. Kargo gelmeden önce, elmasların fiziksel ölçümleri bize
prodolarak gönderildi (hâlâ hayal ediyoruz) ki biz de onlar için fiyat üretebilelim ve web sitemizde pazarlamaya başlayabilelim. Hadi üretelim.Gerçek elmaslar gelmeden ve bir insan uzman, modelimizin ürettiği fiyatları doğrulamadan önce, modelimizin iyi performans gösterip göstermediğini kontrol etmeliyiz. Web sitemizde hatalı fiyatlarla elmas sergilemek istemeyiz.
Bunu yapmak için,
y_prod_predile yeni elmasların gerçek fiyatlarını, yani gerçek değeri karşılaştırarak modelin performansını ölçmemiz gerekir. Ancak fiyatlar doğrulanmadan elimizde gerçek değer olmayacak. Dolayısıyla, gerçek değer olmadan modelin performansını tahmin etmemiz gerekecek.Bu işi yapmak için NannyML, model tarafından yapılan tahminleri içeren üretim verilerinden oluşan bir analiz seti ister.
Analiz seti oluşturmak,
referenceoluşturmaya benzer:Artık
regressor’ün performansını tahmin etmeye hazırız.Adım 2: NannyML’de Performansı Tahmin Etme
NannyML, regresyon ve sınıflandırma modellerinin performansını tahmin etmek için iki ana algoritma sağlar:
Görevimiz için
DLEalgoritmasını kullanacağız.DLE, gerçek değer olmadan üretim modelinin performansını ölçebilir ve RMSE, RMSLE, MAE vb. çeşitli regresyon sahte-metriklerini raporlayabilir.DLEkullanmak için önce temel performansı belirlemek amacıylareferenceüzerinde onu fit etmemiz gerekir.NannyML’de DLE ile performans tahmini
DLE’yi başlatmak üç parametre gerektirir — girdi özellik adları, test için gerçek değeri içeren sütunun adı ve test tahminlerini içeren sütunun adı.Ayrıca metrik olarak RMSE ve 250’lik parça boyutu da geçiyoruz. Tahminleyiciyi
reference’a fit edipanalysisüzerinde performansı tahmin edelim:Elimizde görselleştirilebilen bir NannyML
Resultnesnesi var. Ne ürettiğine bakalım:Grafiği yorumlayalım — başvuru ve analiz setlerindeki performansı gösteren iki bölüm var. Üretimde tahmin edilen RMSE eşikleri aştığında, NannyML bunları uyarı olarak işaretler.
Gördüğümüz gibi, üretim verileri için birkaç uyarı var; bu da son yığınlarda ters giden bir şeyler olduğuna işaret ediyor.
Adım 3: İzlemede Tahmini ve Gerçekleşmiş Performans
İzleme sistemimiz, model performansının üretimde yaklaşık yarı yarıya düştüğünü söylüyor. Ancak bu yalnızca bir tahmin — kesin konuşamayız.
Biz tahmini performansı çizerken, sevkiyat geldi ve elmas uzmanımız gerçek fiyatlarını hesapladı. Bunları
prodiçinepriceolarak kaydettik.Artık modelin gerçekleşmiş performansını (gerçek performans) tahmini performansla karşılaştırıp izleme sistemimizin iyi çalışıp çalışmadığını görebiliriz.
NannyML bunu yapmak için bir
PerformanceCalculatorsınıfı sağlar:Sınıf dört parametre ister:
problem_type: Görev nedir?y_true: Etiketler neler?y_pred: Tahminleri nerede bulabilirim?metrics: Performansı hesaplamak için hangi metrikleri kullanayım?Bunları geçtikten ve hesaplayıcıyı
referenceüzerinde fit ettikten sonra, analiz seti üzerindecalculateederiz.realized_resultsileestimated_results’i karşılaştırmak için yine bir görsel kullanırız:Görünüşe göre tahmini RMSE (mor), gerçekleşmiş performansa (mavi, gerçekleşmiş RMSE) oldukça yakın.
Bu bize tek bir şey söylüyor — izleme sistemimiz iyi çalışıyor, ama modelimiz değil; yükselen kayıp bunun göstergesi. Öyleyse nedeni(leri) ne?
Şimdi buna dalacağız.
Adım 4: Drift Tespit Yöntemleri
Girişte de belirtildiği gibi, modellerin üretimde başarısız olmasının en yaygın nedenlerinden biri drift’tir. Bu bölümde veri (özellik) drift’i tespitine odaklanacağız.
Drift tespiti, model izleme iş akışının kök neden analizi adımının bir parçasıdır. Genellikle çok değişkenli drift tespitiyle başlar.
Çok değişkenli drift tespiti
En iyi çok değişkenli drift tespit yöntemlerinden biri, PCA kullanarak veri yeniden oluşturma hatasını hesaplamaktır. Son derece iyi çalışır ve özellik dağılımlarındaki en küçük drift’leri bile yakalayabilir. Bu yöntemin üst düzey özeti şöyledir:
1. PCA,
referenceüzerine fit edilir ve daha düşük boyuta sıkıştırır —reference_lower.2.
reference_lowerardından orijinal boyutuna geri açılır —reference_reconstructed.referenceile tamamen aynı olmayacaktır.3.
referenceilereference_reconstructedarasındaki fark bulunur ve veri yeniden oluşturma hatası —reconstruct_errorolarak adlandırılır.reconstruct_error, üretim verisinin yeniden oluşturma hatasını karşılaştırmak için bir temel çizgi işlevi görür4. Aynı indirgeme/yeniden oluşturma yöntemi, üretim verilerinin yığınlarına uygulanır.
Bu dört adım, NannyML’de
DataReconstructionDriftCalculatorsınıfı olarak uygulanmıştır. Şöyle kullanılır:Her veri parçası (250 satırlık) için hatayı elde ettikten sonra görselleştirebiliriz:
Gördüğümüz gibi, yeniden oluşturma hatası çok yüksek; bu da özelliklerde drift olduğuna işaret ediyor. Hatayı gerçekleşmiş performansla da karşılaştırabiliriz:
Gördüğümüz üzere, kayıptaki tüm sıçramalar, yeniden oluşturma hatasındaki uyarılarla örtüşüyor.
Tek değişkenli drift tespiti
Veri yeniden oluşturma hatası, tüm özellikler için drift’i ölçen tek bir sayıdır. Peki ya tekil özelliklerin drift’i? Veri setimiz yüzlerce özellik içerseydi, en çok drift eden özellikleri nasıl bulur ve uygun önlemleri alırdık?
İşte burada tek değişkenli drift tespit yöntemlerini kullanırız. NannyML, özellik tipine bağlı olarak birkaç yöntem sunar:
Hepsi,
referenceiçindeki tekil özelliklerin dağılımınıanalysissetindekilerle karşılaştırır. Bunların bazılarını (hatta hepsini)UnivariateDriftCalculatorsınıfı içinde kullanabiliriz:Gerekli tek parametre
column_names’tir; geri kalanı NannyML’in varsayılanlarını kullanabilir. Ancak basit tutmak için, sürekli özellikler içinwasserstein, kategorikler içinjensen_shannonkullanıyoruz.Şu an 11 özelliğimiz var; bu yüzden doğrudan
plot().show()çağırmak en uygun sonucu vermeyebilir. Bunun yerine, tüm parçalar dikkate alındığında en çok sayıda uyarı üreten özellikleri döndüren bir uyarı sayısı sıralayıcısı kullanabiliriz. Kod şöyle:Sıralayıcı sonuçlarını aldıktan sonra, bir Pandas DataFrame olduğu için başını yazdırabiliriz:
En sorunlu özelliklerin color ve depth olduğunu görüyoruz. Bu beni şaşırtmamalı; zira makaleyi yazmadan önce drift’i yapay olarak ben oluşturmuştum.
Ama bu gerçek bir senaryo olsaydı, bu özellikler için sorun çözümüne zaman ayırmak isterdiniz.
Sonuç
Model izlemeyi ilgi çekici buluyorum; çünkü iyi bir model elde edildiğinde makine öğreniminin bittiği yanılgısını yıkıyor. Dünya döndükçe ve kullanıcı örüntüleri değiştikçe hiçbir model uzun süre güncel kalmaz. Bu da model izlemesini her ML mühendisi için kritik bir beceri yapar.
Bugün temel bir model izleme iş akışını ele aldık. Önce temel izleme kavramlarından bahsettik. Sonra doğrudan koda daldık: veriyi NannyML ile uyumlu bir formata getirdik; tahmini model performansı için ilk grafiğimizi oluşturduk, bunu gerçekleşmiş performansla karşılaştıran başka bir grafik yaptık; performans düşüşüne dair birkaç uyarı aldık; çok değişkenli drift tespitiyle kontrol ettik; güçlü özellik drift’i bulduk; tekil özellik drift tespitiyle tekrar doğruladık; drift eden özellikleri belirledik.
Ne yazık ki, sorun çözümü adımında durduk. İzleme iş akışının bu son adımı bu makalenin kapsamı dışında. Ancak bunu ve model izlemenin çok daha fazlasını kapsayan bazı harika önerilerim var:
Bu iki kurs da isteyebileceğiniz en iyi kişi tarafından — NannyML’in CEO’su ve kurucusu — hazırlandı. Kaçırmamanız gereken pek çok bilgi kırıntısı içeriyorlar.
Ayrıca uygulamalı öğreticiler için Nanny ML dokümantasyonunu okumanızı öneririm.