錯誤分析協助您識別和改進AI模型的預測偏差。通過在PAI DSW中整合responsible-ai-toolbox,可對模型進行系統的錯誤分析,找出高錯誤率的資料分組及其原因。
原理介紹
錯誤分析作為Responsible AI實踐的一部分,是理解和改進模型效能的關鍵步驟。其核心原理圍繞系統識別、分析和解決AI模型預測中的錯誤,以提升準確性和公平性。核心原理包括:
-
識別錯誤:識別出模型的預測錯誤。這通常通過比較模型的預測結果與真實值來實現,從而找出不一致的案例。錯誤可以分為不同的類型,如假陽性、假陰性等。
-
分類錯誤:按性質對錯誤分類,有助於理解錯誤背後的原因,如資料不平衡、特徵不足或模型偏見。此過程通常需要領域知識和人工判斷。
-
分析錯誤原因:分析每類錯誤背後的原因。此步驟直接決定後續的最佳化方向,可能涉及資料品質、模型設計、特徵工程或資料表示等方面。
-
採取改進措施:根據錯誤分析結果,採取措施解決模型問題。常見措施包括資料清洗、重新平衡資料集、修改模型架構、引入新特徵或更換演算法。
-
迭代和評估:錯誤分析是持續迭代的過程。每次修改模型後,都需要重新分析,以評估修改效果並排查新問題。
-
文檔和報告:詳盡記錄錯誤分析的過程、發現的問題及解決措施,有助於團隊理解模型局限,並為後續階段提供參考。
以下以”預測人口普查資料集中不同類型人群年度營收是否大於50K”為例,示範如何在PAI DSW中使用responsible-ai-toolbox進行錯誤分析。
準備環境和資源
-
DSW執行個體:如果您還沒有DSW執行個體,請參見建立DSW執行個體。推薦配置如下:
-
推薦執行個體規格:ecs.gn6v-c8g1.2xlarge
-
鏡像選擇:建議使用Python3.9及以上版本。本文選擇的官方鏡像為:tensorflow-pytorch-develop:2.14-pytorch2.1-gpu-py311-cu118-ubuntu22.04
-
模型選擇:responsible-ai-toolbox支援Sklearn架構的迴歸和二分類模型。
-
-
訓練資料集:推薦您使用自己的資料集;如果您需要使用樣本資料集,請按步驟三:準備資料集操作。
-
演算法模型:推薦您使用自己的演算法模型;如果您需要使用樣本演算法模型,請按步驟五:模型訓練操作。
步驟一:進入DSW Gallery
-
登入PAI控制台。
-
在頂部左上方根據實際情況選擇地區。
-
在左側導覽列選擇快速开始 > Notebook Gallery,搜尋“Responsible AI-錯誤分析”並單擊對應卡片上的在DSW中打开。
-
選擇DSW執行個體後,單擊打开Notebook,系統會開啟“Responsible AI-錯誤分析”Notebook案例。
步驟二:匯入依賴包
安裝responsible-ai-toolbox依賴包(raiwidgets),供後續評估使用。
!pip install raiwidgets==0.34.1
匯入Responsible AI和Sklearn依賴包,用於後續的訓練。
# 匯入Response AI相關依賴包
import zipfile
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
import pandas as pd
from lightgbm import LGBMClassifier
from raiutils.dataset import fetch_dataset
import sklearn
from packaging import version
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
步驟三:準備資料集
下載並解壓人口普查資料集,解壓後包含訓練資料adult-train.csv和測試資料adult-test.csv。
# 資料集檔案名稱
outdirname = 'responsibleai.12.28.21'
zipfilename = outdirname + '.zip'
# 下載資料集,並進行解壓
fetch_dataset('https://publictestdatasets.blob.core.windows.net/data/' + zipfilename, zipfilename)
with zipfile.ZipFile(zipfilename, 'r') as unzip:
unzip.extractall('.')
步驟四:資料預先處理
-
載入訓練資料adult-train.csv和測試資料adult-test.csv。
-
把訓練資料和測試資料分別拆分為特徵變數和目標變數。目標變數是指模型預測的真實結果,特徵變數是指每條執行個體資料中目標變數以外的變數。在本文樣本中,目標變數是
income,特徵變數是workclass、education、marital-status等。 -
將訓練資料轉換為NumPy資料格式,用於訓練。
# 載入訓練資料和測試資料
train_data = pd.read_csv('adult-train.csv', skipinitialspace=True)
test_data = pd.read_csv('adult-test.csv', skipinitialspace=True)
# 定義特徵變數和目標變數所在的列
target_feature = 'income'
categorical_features = ['workclass', 'education', 'marital-status',
'occupation', 'relationship', 'race', 'gender', 'native-country']
# 定義函數:用於拆分特徵變數和目標變數
def split_label(dataset, target_feature):
X = dataset.drop([target_feature], axis=1)
y = dataset[[target_feature]]
return X, y
# 拆分特徵變數和目標變數
X_train_original, y_train = split_label(train_data, target_feature)
X_test_original, y_test = split_label(test_data, target_feature)
# 轉換為numpy格式
y_train = y_train[target_feature].to_numpy()
y_test = y_test[target_feature].to_numpy()
# 定義測試樣本
test_data_sample = test_data.sample(n=500, random_state=5)
您也可以載入自己的資料集,CSV格式的資料集對應的指令如下:
import pandas as pd
# 載入自己的資料集,csv 格式資料集
# 使用pandas讀取CSV檔案
try:
data = pd.read_csv(filename)
except:
pass
步驟五:模型訓練
本文樣本中,基於Sklearn定義一個資料訓練流水線並訓練一個二分類模型。
# 根據scikit-learn的不同版本定義ohe_params參數
if version.parse(sklearn.__version__) < version.parse('1.2'):
ohe_params = {"sparse": False}
else:
ohe_params = {"sparse_output": False}
# 定義分類流水線,進行特徵轉換,輸入參數X表示訓練集的資料
def create_classification_pipeline(X):
pipe_cfg = {
'num_cols': X.dtypes[X.dtypes == 'int64'].index.values.tolist(),
'cat_cols': X.dtypes[X.dtypes == 'object'].index.values.tolist(),
}
num_pipe = Pipeline([
('num_imputer', SimpleImputer(strategy='median')),
('num_scaler', StandardScaler())
])
cat_pipe = Pipeline([
('cat_imputer', SimpleImputer(strategy='constant', fill_value='?')),
('cat_encoder', OneHotEncoder(handle_unknown='ignore', **ohe_params))
])
feat_pipe = ColumnTransformer([
('num_pipe', num_pipe, pipe_cfg['num_cols']),
('cat_pipe', cat_pipe, pipe_cfg['cat_cols'])
])
pipeline = Pipeline(steps=[('preprocessor', feat_pipe),
('model', LGBMClassifier(random_state=0))])
return pipeline
# 建立分類模型訓練流水線
pipeline = create_classification_pipeline(X_train_original)
# 模型訓練
model = pipeline.fit(X_train_original, y_train)
步驟六:添加Responsible AI組件
執行以下指令碼,為Responsible AI添加錯誤分析組件,並通過rai_insights計算。
# 匯入RAI儀錶盤組件
from raiwidgets import ResponsibleAIDashboard
from responsibleai import RAIInsights
# 定義RAIInsights對象
from responsibleai.feature_metadata import FeatureMetadata
feature_metadata = FeatureMetadata(categorical_features=categorical_features, dropped_features=[])
rai_insights = RAIInsights(model, train_data, test_data_sample, target_feature, 'classification',
feature_metadata=feature_metadata)
# 添加錯誤分析組件
rai_insights.error_analysis.add()
# RAI計算
rai_insights.compute()
步驟七:建立Responsible AI儀錶盤
-
通過不同的過濾條件,建立不同的資料分組,可以對過濾出的不同的資料分組進行錯誤分析,例如:
-
年紀 (age) 小於65歲且每周工作時間 (hours-per-week) 大於40小時。
-
婚姻狀態 (marital-status) 為"Never-married" 或者 "Divorced"。
-
資料分組索引 (Index) 小於20。
-
預測值(Predicted Y)大於50K。
-
實際值 (True Y) 大於50K。
-
引入ResponsibleAIDashboard儀錶盤,使用responsible-ai-toolbox分析模型。
from raiutils.cohort import Cohort, CohortFilter, CohortFilterMethods
import os
from urllib.parse import urlparse
# 年紀 (age) 小於65歲且每周工作時間 (hours-per-week) 大於40小時
cohort_filter_age = CohortFilter(
method=CohortFilterMethods.METHOD_LESS,
arg=[65],
column='age')
cohort_filter_hours_per_week = CohortFilter(
method=CohortFilterMethods.METHOD_GREATER,
arg=[40],
column='hours-per-week')
user_cohort_age_and_hours_per_week = Cohort(name='Cohort Age and Hours-Per-Week')
user_cohort_age_and_hours_per_week.add_cohort_filter(cohort_filter_age)
user_cohort_age_and_hours_per_week.add_cohort_filter(cohort_filter_hours_per_week)
# 婚姻狀態 (marital-status) 為"Never-married" 或者 "Divorced"
cohort_filter_marital_status = CohortFilter(
method=CohortFilterMethods.METHOD_INCLUDES,
arg=["Never-married", "Divorced"],
column='marital-status')
user_cohort_marital_status = Cohort(name='Cohort Marital-Status')
user_cohort_marital_status.add_cohort_filter(cohort_filter_marital_status)
# 資料分組索引 (Index) 小於20
cohort_filter_index = CohortFilter(
method=CohortFilterMethods.METHOD_LESS,
arg=[20],
column='Index')
user_cohort_index = Cohort(name='Cohort Index')
user_cohort_index.add_cohort_filter(cohort_filter_index)
# 預測值(Predicted Y)大於50K
cohort_filter_predicted_y = CohortFilter(
method=CohortFilterMethods.METHOD_INCLUDES,
arg=['>50K'],
column='Predicted Y')
user_cohort_predicted_y = Cohort(name='Cohort Predicted Y')
user_cohort_predicted_y.add_cohort_filter(cohort_filter_predicted_y)
# 實際值 (True Y) 大於50K
cohort_filter_true_y = CohortFilter(
method=CohortFilterMethods.METHOD_INCLUDES,
arg=['>50K'],
column='True Y')
user_cohort_true_y = Cohort(name='Cohort True Y')
user_cohort_true_y.add_cohort_filter(cohort_filter_true_y)
cohort_list = [user_cohort_age_and_hours_per_week,
user_cohort_marital_status,
user_cohort_index,
user_cohort_predicted_y,
user_cohort_true_y]
# 建立Responsible AI儀錶盤
metric_frame_tf = ResponsibleAIDashboard(rai_insights, cohort_list=cohort_list, feature_flights="dataBalanceExperience")
# 設定URL跳轉連結
metric_frame_tf.config['baseUrl'] = 'https://{}-proxy-{}.dsw-gateway-{}.data.aliyun.com'.format(
os.environ.get('JUPYTER_NAME').replace("dsw-",""),
urlparse(metric_frame_tf.config['baseUrl']).port,
os.environ.get('dsw_region') )
步驟八:訪問Responsible AI儀錶盤,查看錯誤分析
單擊URL,訪問Responsible AI儀錶盤。
[2024-05-29 11:04:57,458] WARNING in __init__: WebSocket transport not available. Install gevent-websocket for improved performance.
ResponsibleAI started at http://localhost:8704
查看錯誤分析:
樹形圖(Tree Map)
-
單擊Tree map,在Select metric中選擇Error rate,進行錯誤性分析。錯誤分析樹形視圖根據模型的所有特徵,以二叉樹方式按照特徵的不同數值進行拆分。例如,該樹形根節點下的二叉樹兩個分支分別表示:
-
marital-status == Married-civ-spouse(54/224)
-
marital-status != Married-civ-spouse(18/276)
-
-
本次樣本包含500個樣本,有72個預測錯誤,則錯誤率為72/500 = 14.4%。每個二叉樹的節點展示了滿足該分支條件的資料總量以及預測錯誤的數量和錯誤比例。
-
您需要重點關注紅色的節點,紅色越深,表明錯誤率(error rate)越高。
-
在本樣本中,單擊紅色最深的葉子節點,可以看出同時滿足以下條件的資料,模型預測錯誤比例高達43.40%。條件如下:
-
marital-status == Married-civ-spouse
-
fnlwgt <= 207583
-
hours-per-week > 40.5
-
熱度圖(Heat Map)
-
單擊Heat map,切換到熱度圖分析視圖,在Select metric中選擇Error rate,進行錯誤性分析。
-
(可選)配置參數:
-
Quantile binning:是一種將連續變數分成若干個具有相同資料點的區間的方法。
-
設定為OFF,表示關閉。採用預設均勻分段策略,每個區間的長度保持相同。
-
設定為ON,表示開啟。每個區間包含相同數量的資料點,使得資料在每個區間中均勻分布。
-
-
Binning threshold:表示將資料分割的區間個數,調整threshold可調整分割的區間數量(在本樣本中預設為8,表示將age和hours-per-week平均分割為8個區間)。
-
-
在熱度圖中,您可以選定2個輸入特徵進行資料交叉分析。本樣本中選定age、hours-per-week 進行熱度圖分析。
-
您需要重點關注紅色的節點,紅色越深,表明錯誤率(error rate)越高。
-
從分析結果看,兩個特徵在以下分布區間的錯誤率最高,高達 100%:
-
age[71.8,80.9]、hours-per-week[39.0,51.0]
-
age[44.4,53.5]、hours-per-week[75.0,87.0]
-
age[16.9,26.1]、hours-per-week[63.0,75.0]
-
...
-