Data analysis

텍스트 하이라이트 기능을 통해 XAI 맛보기

jhpaik 2023. 10. 20. 22:29

XAI 란?

Explainable AI의 줄임말로 단어 그대로 인공지능의 블랙박스를 설명가능한 인공지능을 의미한다.
DARPA(방위 고등 연구 계획국)의 인공지능 관련 프로젝트로 연구가 활발하게 이루어지면서 XAI 연구가 발전되어왔다. 예를 들어 XAI가 타깃 미사일 요격 연구에 쓰이는 사례를 보면 타깃을 조준하는 미사일이 타깃을 조준하는 데 있어서 근거가 정립되지 않으면 인공지능만을 믿고 요격하다가 오판이 생기는 경우 대참사가 일어날 수 있다. 이러한 사례를 보면 왜 국방관련 연구기관에서 XAI가 부상하게 되었는지 알 수 있다.

XAI를 활용하는 과정은 아래와 같이 이루어진다.

 

  1. 머신러닝 모델 생성
  2. 설명 가능한 모델 결합
  3. 모델 결과 해석 인터페이스 연결
  4. 모델 문제점 발견 및 개선
  5. 모델 테스트 평가 파이프라인 구축

 

기존 인공지능 기법 vs XAI 기법

기존 인공지능 기법과 XAI기법의 직관적인 차이는 아래의 그림으로 설명할 수 있다.

XAI 기법

XAI 기법중 몇 가지의 사례를 살펴보자

 

피처 중요도(Feature Importance)

피처 중요도는 모델의 피처 중 어느 피처가 가장 중요한지 나타내는 기법이다.

 

부분 의존성 플롯(PDP, Partial Dependence Plots)

피처의 수치를 선형적으로 변형하면서 알고리즘 해석능력이 얼마나 증가하고 감소하지는 관찰하는 방식이다. PDP 기법을 통해 피처의 값이 변할 때 모델이 미치는 영향을 가시적으로 확인할 수 있다.

위 그래프와 같이 PDP로 나타낸 포도당 내성 테스트에 따른 모델 영향력이 표현된다. 위의 plot에서 포도당 내성 테스트의 결과가 100mg 이상 수치를 보일 때 당뇨병 진단 영향력이 커지는 것을 확인 할 수 있다.

 

글로벌 대리 분석

글로벌 대리 분석은 전체 학습 데이터를 통해 블랙박스 함수 f를 따라하는 모델 g를 통해 g를 해석가능토록 튜닝하는 방법이다. 글로벌 대리 분석 과정은 아래와 같이 이루어진다.

  1. 데이터 집합 X 선택
  2. X에 대해 모델 f 예측 결과 구함
  3. xai 모델 선택(g라고 칭함, 해당 모델은 설명가능해야 함)
  4. 데이터 집합 X로 모델 g학습
  5. 데이터 X에 대해 모델 f가 예측한 결과와 모델 g 예측 결과를 비교하면서 유사결과를 내도록 튜닝
  6. 모델 g를 결과 해석

 

로컬 대리 분석(LIME, Local Interpertable Model-agnostic Explanations)

데이터 하나에 대해 블랙박스가 해석하는 과정을 분석하는 기법 라임 LIME(Local Interpertable Model-agnostic Explanations)로 알려져 있다.

아래의 내용은 수신된 특정 메일내용에 대해서 어떤 부서로 전달되어야 하는지에 대한 분류설명을 LIME에서 시각화 기능(텍스트 하이라이트)을 제공한 예시다.

LIME 실습

텍스트 데이터에 LIME 적용

실습데이터를 통해 LIME을 적용해보자 예를 들어 현재 언론사 A로부터 제보메일이 쏟아지고 있다.
쏟아지는 제보메일에 대해서 제보메일에 관련된 부서로 분류하는 필요성이 대두되었다.

 

먼저 LIME을 설치해보자

!pip install lime

 

뉴스데이터셋을 불러와서 train, test를 분리하고 각 클래스 이름을 추출한다.

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
newsgroups_test = fetch_20newsgroups(subset='test')

# 클래스 이름 줄이기
class_names = [x.split('.')[-1] if 'misc' not in x else '.'.join(x.split('.')[-2:])
for x in newsgroups_train.target_names]

print(class_names)
['atheism', 'graphics', 'ms-windows.misc', 'hardware', 'hardware', 'x', 'misc.forsale', 'autos', 'motorcycles', 'baseball', 'hockey', 'crypt', 'electronics', 'med', 'space', 'christian', 'guns', 'mideast', 'politics.misc', 'religion.misc']

 

확인결과, 변수명이 동일한 부분이 있어서 rename하였다.

# 중복된 변수명 rename
class_names[3] = 'pc.hardware'
class_names[4] = 'mac.hardware'

print(class_names)
['atheism', 'graphics', 'ms-windows.misc', 'pc.hardware', 'mac.hardware', 'x', 'misc.forsale', 'autos', 'motorcycles', 'baseball', 'hockey', 'crypt', 'electronics', 'med', 'space', 'christian', 'guns', 'mideast', 'politics.misc', 'religion.misc']

 

뉴스 제보 메일의 카테고리 분류 모델 생성 및 측정을 진행해보자

import sklearn
import sklearn.metrics
from sklearn.naive_bayes import MultinomialNB

# TF-IDF를 통해 문서를 숫자 벡터로 변환
vectorizer = sklearn.feature_extraction.text.TfidfVectorizer(lowercase=False)
train_vectors = vectorizer.fit_transform(newsgroups_train.data)
test_vectors = vectorizer.transform(newsgroups_test.data)

# learning

nb = MultinomialNB(alpha=.01)
# MultinomialNB(다항분포 나이브베이즈)를 통해 벡터 입력값에 대해 해당 문서가 특정 카테고리에 속할 확률 계산

nb.fit(train_vectors, newsgroups_train.target)

# testing
pred = nb.predict(test_vectors)
sklearn.metrics.f1_score(newsgroups_test.target, pred, average='weighted')
0.8350184193998174

 

어떤 제보가 들어왔을 때 약 83.5%의 성능으로 뉴스카테고리를 분류하는 모델이 생성되었다.

이제 XAI를 적용해보자 파이프라인 기능을 통해 vectorizer와 카테고리 분류를 한꺼번에 수행해보자

from sklearn.pipeline import make_pipeline

pipe = make_pipeline(vectorizer, nb)
predict_classes = pipe.predict_proba([newsgroups_test.data[0]]).round(3)[0]

print(predict_classes)
[0.001 0.01  0.003 0.047 0.006 0.002 0.003 0.521 0.022 0.008 0.0250.
 0.331 0.003 0.006 0.    0.003 0.    0.001 0.009]

 

가독성을 높이는 방향으로 수정해서 출력해보자

rank = sorted(range(len(predict_classes)), key=lambda i: predict_classes[i], reverse=True)
for rank_index in rank:
    print('[{:>5}] \t{:<3}\tclass ({:.1%})'.format(rank.index(rank_index) + 1, rank_index, predict_classes[rank_index]))
[    1] 	7  	class (52.1%)
[    2] 	12 	class (33.1%)
[    3] 	3  	class (4.7%)
[    4] 	10 	class (2.5%)
[    5] 	8  	class (2.2%)
[    6] 	1  	class (1.0%)
[    7] 	19 	class (0.9%)
[    8] 	9  	class (0.8%)
[    9] 	4  	class (0.6%)
[   10] 	14 	class (0.6%)
[   11] 	2  	class (0.3%)
[   12] 	6  	class (0.3%)
[   13] 	13 	class (0.3%)
[   14] 	16 	class (0.3%)
[   15] 	5  	class (0.2%)
[   16] 	0  	class (0.1%)
[   17] 	18 	class (0.1%)
[   18] 	11 	class (0.0%)
[   19] 	15 	class (0.0%)
[   20] 	17 	class (0.0%)

 

데이터 index 0번은 8번째 카테고리일 확률이 가장 높은 것을 확인할 수 있다.
Ex. [ 1] 7 class (52.1%) -> 순위, 메일 카테고리 순서, 그 카테고리에 기사가 속할 가능성

텍스트 분류기 LIME을 실습하기 위해 텍스트 설명체를 생성하자

from lime.lime_text import LimeTextExplainer

explainer = LimeTextExplainer(class_names=class_names)

# explain_instance 메서드에 필요한 최소한 파라미터

exp = explainer.explain_instance(newsgroups_test.data[0], # 해석할 데이터
                                 pipe.predict_proba, # 모델
                                 top_labels=1) # 분류 가능성이 높은 클래스를 순서대로 몇 개 보여줄지 결정

 

explainer가 0번 테스트 데이터를 해석한 결과를 출력해보자

exp.show_in_notebook(text=newsgroups_test.data[0])

 

해석결과, 해당 제보는 테스트데이터가 자동차(autos) 카테고리에 속할 확률이 가장 높고
자동차 카테고리에 속하는 근거로 88-89, SE 등이 있다고 텍스트 하이라이트를 통해 파악할 수 있다.

 

Reference.

  • XAI 설명 가능한 인공지능, 인공지능을 해부하다 - 안재현
  • 유튜브 - 이유를 설명해주는 딥러닝, XAI (Explainable AI)