В Части 1 этой статьи мы обсудили две важные концепции полевого тестирования, такие как тестирование стабильности и A/B-тестирование.
в этой статье мы предоставим то же самое на Python.
В первой части этой статьи есть код, касающийся тестирования стабильности модели ИИ (подход к бэк-тестированию), а во второй части этой статьи упоминается реализация A/B-тестирования.
- Тестирование модели ИИ на стабильность
Тестирование стабильности говорит о согласованности и эффективности модели ИИ и помогает понять проблемы с данными, изменения в бизнес-процессах с течением времени (если таковые имеются), дрейф данных между различными переменными, используемыми для тестирования, и проверить качество прогнозов модели ИИ. . Тестирование стабильности обеспечивает общую оценку модели ИИ.
Шаг 1. Импортируйте все необходимые библиотеки Python.
import pandas as pd import numpy as np from datetime import timedelta from datetime import datetime from dateutil. relativedelta import relativedelta from sklearn.metrics import confusion_matrix, classification_report,accuracy_score,precision_score,recall_score,f1_score from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestClassifier from tensorflow.keras.backend import epsilon
Шаг 2. Загрузите данные и выполните их обработку.
Чтобы продемонстрировать пример использования тестирования стабильности, были использованы синтетически сгенерированные данные для понимания характера дохода (1 — высокий, а 0 — низкий) на основе драйверов функций, используемых в наборе данных.
modelDF = pd.read_csv("Back_Testing_Sample.csv") # Converting the column from object to datetime format modelDF['Baseline_Date']=pd.to_datetime(modelDF['Baseline_Date'].astype(str), format='%Y-%m-%d') # Select only the required feature drivers filterGroupDF = modelDF.copy() selected_features = ['Baseline_Date', 'Amount', 'RPM', 'Marketing Spend', 'Paper Advertising Spend', 'Digital or not', 'TV Advertising Spend', 'Revenue', 'Revenue_Response'] filterGroupDF = filterGroupDF[selected_features] filterGroupDF.head()
Шаг 3: Определите функции полезности, чтобы вернуть параметры матрицы путаницы и пометить целевую переменную на основе порога вероятности.
# Computing TP, FP, TN and FN # TP: True Positive # FP: False Positive # TN: True Negative # FN: False Negative def confusion_metrics(y_test, y_pred): TP = 0 TN = 0 FP = 0 FN = 0 CM = confusion_matrix(y_test,y_pred) TN = CM[0][0] FP = CM[0][1] FN = CM[1][0] TP = CM[1][1] return (TP, FP, TN, FN) # Function to create y_pred using y_pred_prob & thresholds def create_y_pred(y_pred_prob, thresh): y_pred_list = [] for i in range(len(y_pred_prob)): y_pred = 1 if y_pred_prob[i] > thresh else 0 y_pred_list.append(y_pred) return y_pred_list
Существует шесть переменных, которые вы должны определить на основе данных и размера окна в зависимости от требований.
windowStartDate = datetime.strptime('2019-07-01', '%Y-%m-%d') windowEndDate = datetime.strptime('2020-07-01', '%Y-%m-%d') trainWindowSize = 4 testWindowSize = 4 slideWindowSize = 1
Примечание. Параметр number_iterations должен быть получен на основе общего окна данных и размера скользящего окна. Следующее изображение иллюстрирует то же самое
Case 1: trainWindowSize = 4 testWindowSize = 4 slideWindowSize = 1
number_iterations будет 4
Case 2: trainWindowSize = 4 testWindowSize = 4 slideWindowSize = 2
number_iterations будет 2
# Define thresholds in a list to iterate for each threshold threshold_list = [0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9] for threshold in threshold_list: WindowStartDate = datetime.strptime('2019-07-01', '%Y-%m-%d') WindowEndDate = datetime.strptime('2020-07-01', '%Y-%m-%d') trainWindowSize = 4 testWindowSize = 4 slideWindowSize = 1 Number_iterations = 4 back_testing_df = pd.DataFrame(columns = ['Iteration','Probability_Threshold','Train_Starte_Date','Train_End_Date','Test_Start_Date','Test_End_Date','Train_Sample_Size','Test_Sample_Size','TP','TN','FP','FN','Recall','Precision','Accuracy','F-Score'], index = range(Number_iterations)) for i in range(Number_iterations): trainStartDate = WindowStartDate trainEndDate = trainStartDate + relativedelta(months=trainWindowSize) testStartDate = trainEndDate testEndDate = testStartDate + relativedelta(months=testWindowSize) if(testEndDate>WindowEndDate): break trainDF = filterGroupDF[(filterGroupDF['Date']>=trainStartDate) & (filterGroupDF['Date']<trainEndDate)] testDF = filterGroupDF[(filterGroupDF['Date']>=testStartDate) & (filterGroupDF['Date']<testEndDate)] X_train_stage_1 = trainDF.drop(['Date','Revenue_Response'], axis=1) y_train_stage_1 = trainDF['Revenue_Response'] X_test_stage_1 = testDF.drop(['Date','Revenue_Response'], axis=1) y_test_stage_1 = testDF['Revenue_Response'] clf = RandomForestClassifier(max_depth=8, max_features='auto', min_samples_leaf=4, n_estimators=500,random_state=41) clf.fit(X_train_stage_1,y_train_stage_1) y_pred_test = clf.predict(X_test_stage_1) y_pred_proba = clf.predict_proba(X_test_stage_1) back_testing_df['Iteration'][i] = i+1 back_testing_df['Probability_Threshold'][i] = threshold back_testing_df['Train_Starte_Date'][i] = trainStartDate back_testing_df['Train_End_Date'][i] = trainEndDate + timedelta(days=-1) back_testing_df['Test_Start_Date'][i] = testStartDate back_testing_df['Test_End_Date'][i] = testEndDate + timedelta(days=-1) back_testing_df['Train_Sample_Size'][i] = X_train_stage_1.shape[0] back_testing_df['Test_Sample_Size'][i] = X_test_stage_1.shape[0] y_pred_prob = np.array(y_pred_proba[:,-1]) y_pred_thresh = create_y_pred(y_pred_prob, threshold) TP, FP, TN, FN = confusion_metrics(y_test_stage_1, y_pred_thresh) back_testing_df['TP'][i] = TP back_testing_df['TN'][i] = TN back_testing_df['FP'][i] = FP back_testing_df['FN'][i] = FN back_testing_df['Recall'][i] = TP/(TP + FN + epsilon()) back_testing_df['Precision'][i] = TP/(TP + FP + epsilon()) back_testing_df['Accuracy'][i] = float((TP + TN)/(TP + TN + FP + FN + epsilon())) back_testing_df['F-Score'][i] = 2*back_testing_df['Precision'][i]*back_testing_df['Recall'][i]/(back_testing_df['Precision'][i] + back_testing_df['Recall'][i] + epsilon()) # Update the Window start date based on the sliding window size WindowStartDate = WindowStartDate + relativedelta(months=slideWindowSize) print(back_testing_df.head(20))
Здесь показатели производительности для порога вероятности 0,5 указывают на то, что точность неодинакова в разных окнах тестирования, что ясно указывает на необходимость улучшения модели ИИ.
2. A/B-тестирование
Как мы упоминали в Части 1 этой статьи, для проведения A/B-тестирования мы должны разделить результат ИИ на тестовую и контрольную группы, и они должны быть схожими по своему характеру, потому что результаты ИИ следует сравнивать в одинаковых условиях для эффективного A/B-тестирования. Б тестирование.
Это самый сложный и важный шаг в проведении A/B-тестирования. Итак, чтобы разделить эти данные на тестовые и контрольные группы, мы провели стратифицированную выборку.
Шаг 1. Импортируйте все необходимые библиотеки Python.
import pandas as pd import numpy as np
Шаг 2: Загрузите данные и выполните обработку данных
df = pd.read_csv("Back_Testing_Sample.csv") df.head()
Здесь столбец идентификатора является синонимом любой нечисловой (категориальной) переменной, такой как бизнес-единица, подразделение, регион и т. д.
Шаг 3:
## Stratify sampling list_pk=list(df['ID'].unique()) def stratified_sample(df,perc): df_final=pd.DataFrame() for i in list_pk: df_stratified = df[df['ID']==i] if len(df_stratified)>1: df_stratified = df_stratified.sample(frac=perc) df_final=df_final.append(df_stratified) return df_final test_data=stratified_sample(df=df,perc=0.5) df=df.reset_index() test_data=test_data.reset_index() control_data=df[~df['index'].isin(list(test_data['index']))] control_data=control_data.reset_index() print(control_data.shape,test_data.shape,df.shape) test_data['ID'].value_counts() control_data['ID'].value_counts()
Предположения:
- Данные одинаково распределяются по всем идентификаторам
- Существует много записей для одного и того же идентификатора
Поскольку характеристики одинаковы как в тестовой, так и в контрольной группах, мы можем проверить результаты ИИ, сравнив бизнес-показатели между тестовой и контрольной группами, как только у нас появятся достоверные данные.
Об авторах
Шрихари Налаболу — специалист по данным с опытом работы в различных областях здравоохранения, фармацевтики, банковского дела и телекоммуникаций. Он интересуется обнаружением аномалий, рекомендательными системами, анализом текста и компьютерным зрением.
Адитья Н — специалист по данным, в настоящее время работающий в сфере здравоохранения и фармацевтики. Он интересуется экономикой, машинным обучением и управлением продуктами ИИ.
Отказ от ответственности: эта статья написана на основе опыта авторов, работающих над различными типами данных и проблемами искусственного интеллекта в разных областях