Responsible AI對人工智能模型(AI模型)開發者和企業管理者十分重要,Responsible AI貫穿在AI模型的開發、訓練、微調、評估、部署等環節,是保障AI模型安全、穩定、公平、符合社會道德的重要方法。PAI已支持用戶在DSW中集成Responsible AI的相關工具對產出的AI模型進行公平性分析、錯誤分析及可解釋性分析。
原理介紹
錯誤分析作為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控制臺。
在頂部左上角根據實際情況選擇地域。
在左側導航欄選擇大數據與AI體驗 > DSW Gallery,搜索“Responsible AI-錯誤分析”并單擊對應卡片上的在阿里云DSW打開。
選擇AI工作空間和DSW實例,單擊確定,系統會打開“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儀表盤。
查看錯誤分析:
樹形圖(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]
...