1. Обучим модель, сохраним её и проверим совпадение
прогнозов.
import joblib
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
X, y = make_classification(
n_samples=400,
n_features=5,
n_informative=3,
n_redundant=0,
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
stratify=y,
random_state=42
)
model = make_pipeline(
StandardScaler(),
LogisticRegression(max_iter=1000)
)
model.fit(X_train, y_train)
before = model.predict(X_test)
artifact = {
"model":
model,
"version": "1.0",
"feature_names": [
"feature_1",
"feature_2",
"feature_3",
"feature_4",
"feature_5"
],
"accuracy":
accuracy_score(y_test, before)
}
joblib.dump(artifact, "saved_model.joblib")
loaded = joblib.load("saved_model.joblib")
after = loaded["model"].predict(X_test)
print("Версия:", loaded["version"])
print("Точность:",
round(loaded["accuracy"], 3))
print("Прогнозы совпадают:",
np.array_equal(before, after))
Результат:
Прогнозы совпадают: True.
Сохранение всего Pipeline обеспечивает повторное применение
тех же преобразований, которые использовались при обучении.
Для воспроизводимости промышленной системы также необходимо
фиксировать версии данных, библиотек и конфигурации эксперимента.
2. Реализуем проверку схемы JSON-запроса.
import numpy as np
feature_names = [
"age",
"income",
"experience"
]
def validate_request(request):
if not
isinstance(request, dict):
raise
ValueError("Ожидается JSON-объект")
if
set(request.keys()) != set(feature_names):
raise
ValueError("Неверная схема признаков")
values = []
for name in
feature_names:
value =
request[name]
if (
isinstance(value, bool)
or not
isinstance(value, (int, float))
or not
np.isfinite(value)
):
raise
ValueError(
f"Некорректное значение признака: {name}"
)
values.append(float(value))
return
np.array([values])
valid_request = {
"age":
30,
"income": 250000,
"experience": 5
}
invalid_request = {
"age":
30,
"income": 250000
}
print("Корректный запрос:")
print(validate_request(valid_request))
print("Некорректный запрос:")
try:
print(validate_request(invalid_request))
except ValueError as error:
print("Ошибка:", error)
Результат:
Корректный запрос преобразуется в массив с тремя признаками.
Некорректный запрос отклоняется из-за отсутствующего
признака experience.
Проверка схемы необходима, поскольку модель ожидает
определённое количество, порядок и типы признаков. Изменение контракта может
привести к ошибкам сервиса или неправильным прогнозам.
3. Реализуем учебный мониторинг входных данных и
качества модели.
import numpy as np
from sklearn.metrics import accuracy_score
rng = np.random.default_rng(42)
train_feature = rng.normal(
loc=50,
scale=10,
size=1000
)
current_feature = rng.normal(
loc=60,
scale=10,
size=1000
)
current_feature[::20] = np.nan
train_mean = np.mean(train_feature)
current_mean = np.nanmean(current_feature)
difference = abs(current_mean - train_mean)
missing_rate = np.mean(
np.isnan(current_feature)
)
y_true = np.array([1, 0, 1, 1, 0, 0, 1, 0])
y_pred = np.array([1, 0, 0, 1, 0, 0, 1, 1])
accuracy = accuracy_score(y_true, y_pred)
print("Среднее train:", round(train_mean, 2))
print("Среднее current:", round(current_mean, 2))
print("Изменение:", round(difference, 2))
print("Доля пропусков:", round(missing_rate, 3))
print("Точность:", round(accuracy, 3))
if difference > 5:
print("Требуется анализ изменения распределения")
Результат:
Доля пропусков: 0.05, или 5%.
Точность: 0.75.
Изменение среднего значения превышает учебный порог 5,
поэтому программа выводит предупреждение.
При промышленном мониторинге необходимо отслеживать ошибки
сервиса, время ответа, распределения признаков, долю пропусков и качество после
появления истинных меток.
Обнаружение data drift само по себе не доказывает ухудшения
качества модели и не означает, что переобучение необходимо выполнять
немедленно.