대리 분석-LIME
https://book.naver.com/bookdb/book_detail.nhn?bid=16299590
전체적인 프로세스는 다음의 책을 참고했다.
XAI 설명 가능한 인공지능, 인공지능을 해부하다
XAI(EXPLAINABLE ARTIFICIAL INTELLIGENCE)는 인공지능의 판단 이유를 설명하는 연구 분야로, 인공지능 기술이 확대되면서 그 필요성이 함께 증가하고 있습니다. 이것은 알고리즘의 설계자조차 인공지능의
book.naver.com
전처리는 아래의 글을 참조했다.
6) 네이버 영화 리뷰 감성 분류하기(Naver Movie Review Sentiment Analysis)
이번 챕터에서는 영어 데이터가 아닌 한국어/한글 데이터에 대해서 텍스트 분류를 수행해보겠습니다. 방법 자체는 영어 데이터에 대한 텍스트 분류와 크게 달라지지는 않았습니다. ...
wikidocs.net
대리 분석
인공 지능 모델이 너무 복잡해서 분석이 불가능할 때 유사한 기능을 흉내내는 인공지능 모델 여러개를 만들어서 본래 모델을 분석하는 기법.
장점: Model-agnostic: 모델에 대한 지식 없이도 학습할 수 있음
글로벌 대리 분석
전체 train 데이터를 이용해 (블랙박스 모델인) f 를 따라 g 를 만들고 g 를 해석 가능하도록 변조 . 이때 g는 설명 가능한 모델이어야 한다.
로컬 대리 분석
데이터 하나에 대해 블랙박스가 해석하는 과정을 분석하는 기법
LIME(Local Interpretable Model - agnostic Explanation)
:모델이 현재 데이터의 어떤 영역을 집중해서 분석했고, 어떤 영역을 분류 근거로 사용했는지 알려주는 XAI 기법
실습:
백의진님(Quarter, 29.9세)이 주신 버즈 train data와 test data를 사용했다.
train data 와 test 데이터
def true_y(self, x):
if x == 0:
return '거래판매'
elif x == 1:
return '렌탈'
elif x == 2:
return '부동산'
elif x == 3:
return '수리'
elif x == 4:
return '이벤트'
elif x == 5:
return '인사글'
elif x == 6:
return '종교'
elif x == 7:
return '주식'
else:
return '체험단'
라벨이 의미하는 것
전처리는 최대한 간단하게 하겠다.
#한글만 남기고 제거
jytrain['document'] = jytrain['document'].str.replace("[^ㄱ-ㅎㅏ-ㅣ가-힣 ]","")
jytest['document'] = jytest['document'].str.replace("[^ㄱ-ㅎㅏ-ㅣ가-힣 ]","")
okt 로 토큰화 하고 불용어를 제거한다.
#토큰화
stopwords = ['의','가','이','은','들','는','좀','잘','걍','과','도','를','으로','자','에','와','한','하다']
#train_data에 형태소 분석기를 사용하여 토큰화를 하면서 불용어를 제거하여 X_train에 저장
okt = Okt()
X_train = []
for sentence in tqdm(jytrain['document']):
if len(sentence.split(' '))>=100 :#속도상 100글자 이하만 쓰도록 함
pass
else:
tokenized_sentence = okt.morphs(sentence, stem=True) # 토큰화
stopwords_removed_sentence = [word for word in tokenized_sentence if not word in stopwords] # 불용어 제거
X_train.append(stopwords_removed_sentence)
test data도 이렇게 해준다.
TF-IDF 를 사용해서 문서를 숫자 벡터로 변환한다.
너무힘들다..벼락치기중...
import sklearn.feature_extraction
import sklearn.metrics
from sklearn.naive_bayes import MultinomialNB
#TF-IDF를 사용해서 문서를 숫자 벡터로 변환하는 전처리 과정
vectorizer=sklearn.feature_extraction.text.TfidfVectorizer(preprocessor=' '.join,lowercase=False)
train_vectors=vectorizer.fit_transform(X_train)
test_vectors=vectorizer.transform(X_test)
#학습하기
nb=MultinomialNB(alpha=.01)
nb.fit(train_vectors,jytrain.iloc[:2220,2])
#테스트하기
pred=nb.predict(test_vectors)
sklearn.metrics.f1_score(jytest.iloc[:,2],pred,average='weighted')
0.8304224400125914
약 83%의 성능을 내는 버즈 카테고리를 분류하는 모델을 만들었다!
XAI 적용하기
파이프라인 기능을 사용해보자. (가독성 높은 코드를 위해)
#파이프라인 기술을 사용해 테스트 데이터 인덱스 0번에 데이터 벡터라이저와 카테고리 분류를 한꺼번에 수행
from sklearn.pipeline import make_pipeline
pipe=make_pipeline(vectorizer,nb)
predict_classes=pipe.predict_proba([X_test[0]]).round(3)[0]
predict_classes
predict_classes
Out[15]: array([0. , 0.861, 0.037, 0.016, 0. , 0.025, 0. , 0.06 , 0. ])
2번째 카테고리에 속할 확률이 가장 높다.(86%)
이제 LIME을 사용해서 버즈 분류기 모델을 설명해 보자.
#LIME 텍스트 설명체를 선언하는 코드
from lime.lime_text import LimeTextExplainer
explainer=LimeTextExplainer()
0번 데이터에 LIME을 적용해 보자!
exp=explainer.explain_instance(str(X_test[0]),pipe.predict_proba,top_labels=1)
exp.available_labels()
[0]
거래 판매 게시물이라고 한다.. 너무 불안하다.
exp=explainer.explain_instance(jytest['document'].iloc[44],pipe.predict_proba,top_labels=2)
exp.available_labels()
[0,7]
44번 글을 확인해본다.
계속 상위 주제에 0이 떠서 꼼수로 탑레벨을 2로 지정했다. 엉엉....
7: 주식이다.
뒷걸음질 치다 맞은 격으로 맞았다.
그럼 이제 Lime의 하이라이트 기능을 알아보자.
exp.save_to_file("../test44.html")
이건 어디 보여줄 수 가 없는 수준이다...
어쨌든 처음 해본 것에 의의를 두자.ㅎㅎ
눈물이 앞을 가린다.... 어쨌든 4시간만 한거니까!(자기합리화)