Ana içeriğe geç

Python'da NannyML ile Uçtan Uca ML Model İzleme İş Akışı

Jupyter defterinizdeki herhangi bir modeli üretim ortamlarında izlemek için uçtan uca bir iş akışını öğrenin.
· 15 dk. oku

Yapay Zeka ile Keşfedin

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:

  • 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

  1. 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.
  2. 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.
  3. 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

  1. 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.
  2. 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.
  3. 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:

  1. 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.
  2. Ö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.
  3. 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.
  4. 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.
  5. Anomali tespiti: Anomali (yenilik) tespiti yöntemleri, üretim verilerindeki olağandışı örüntüleri erken safhada belirleyebilir.
  6. 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")

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:

dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv"

diamonds_special = pd.read_csv(dataset_link)
diamonds_special.head()

image8.png

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"

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")

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:

diamonds_special.set.unique()
['train', 'val', 'test', 'prod']
Categories (4, object): ['prod', 'test', 'train', 'val']

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)

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:

def split_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)
   for set in sets:
       set.reset_index(inplace=True, drop=True)

   return sets


tr, val, test, prod = split_into_four(your_dataset)

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:

dtrain = xgb.DMatrix(tr[all_feature_names], label=tr[target], enable_categorical=True)
dval = xgb.DMatrix(val[all_feature_names], label=val[target], enable_categorical=True)

dtest = xgb.DMatrix(
   test[all_feature_names], label=test[target], enable_categorical=True
)
dprod = xgb.DMatrix(
   prod[all_feature_names], label=prod[target], enable_categorical=True
)

Ş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.77217	eval-rmse:0.00000
[49]	train-rmse:502.61376	eval-rmse:0.00000

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.2763827068798

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')

Ekleyelim:

test["y_pred"] = y_test_pred

Şimdi test setini reference olarak yeniden adlandıracağız:

reference = test.copy(deep=True)

reference.columns
Index(['carat', 'cut', 'color', 'clarity', 'depth', 'table', 'price', 'x', 'y',
      'z', 'y_pred'],
     dtype='object')

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 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)

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.

Analiz seti oluşturmak, reference oluşturmaya benzer:

# 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')

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.

NannyML’de DLE ile performans tahmini

import nannyml  # pip install nannyml

estimator = nannyml.DLE(
   feature_column_names=all_feature_names,
   y_true=target,
   y_pred="y_pred",
   metrics=["rmse"],
   chunk_size=250,
)

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>

Elimizde görselleştirilebilen bir NannyML Result nesnesi var. Ne ürettiğine bakalım:

estimated_results.plot().show()

image1.png

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:

calculator = nannyml.PerformanceCalculator(
   problem_type="regression",
   y_true=target,
   y_pred="y_pred",
   metrics=["rmse"],
   chunk_size=250,
)

calculator.fit(reference)
realized_results = calculator.calculate(analysis)

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 üzerinde calculate ederiz.

realized_results ile estimated_results’i karşılaştırmak için yine bir görsel kullanırız:

estimated_results.compare(realized_results).plot().show()

image5.png

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:

# Initialize
multivariate_calc = nannyml.DataReconstructionDriftCalculator(
   column_names=all_feature_names,
   chunk_size=250,
)

# Fit
multivariate_calc.fit(reference)
# Calculate error
multivariate_results = multivariate_calc.calculate(analysis)

Her veri parçası (250 satırlık) için hatayı elde ettikten sonra görselleştirebiliriz:

multivariate_results.plot().show()

image3.png

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:

multivariate_results.compare(realized_results).plot().show(config={"staticPlot": True})

image7.png

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:

univariate_calc = nannyml.UnivariateDriftCalculator(
   column_names=all_feature_names,
   continuous_methods=["wasserstein"],
   categorical_methods=["jensen_shannon"],
   chunk_size=250,
)

univariate_calc.fit(reference)
univariate_results = univariate_calc.calculate(analysis)

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)

Sıralayıcı sonuçlarını aldıktan sonra, bir Pandas DataFrame olduğu için başını yazdırabiliriz:

ranker_results.head(10)

image4.png

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.

Bexruz (Bex) Tuychiev

Yazar

Bexruz (Bex) Tuychiev

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. 

Konular

İlgili