[R&E 개발 일지] 유튜브 정치 편향 진단 및 필터버블 분석 시스템(BiasAnalyzer) 연구 회고

김(태윤)신(승훈)조(준희) 팀

[R&E 개발 일지] 유튜브 정치 편향 진단 및 필터버블 분석 시스템(BiasAnalyzer) 연구 회고

R&E 하느라 고생 좀 했는데, 이제야 회고를 써보네요!!!!!

아직 끝난 것도 아니라서 좀 애매하긴 하지만.... 그래도 여기까지 온 과정을 한번 쭉 정리해보려고 합니다~

1. 주제 정하다가 반년 다 감

처음엔 진짜 이것저것 다 해보려고 했어요

상호대차 경로 최적화, 조류 충돌 방지, 모기 트래커.... 뭔가 사회 문제 해결하는 거 멋있어 보이잖아요?

근데 찾아보니까 죄다 선행 연구가 이미 있더라구요 ㅠㅠ

그래서 맥락적 혐오랑 돌려까기 탐지 쪽으로 한번 틀었다가, 최종적으로는 유튜브 피드의 정치적 확증 편향을 진단하는 시스템으로 정착했습니다

근데 여기서 또 "본인이 원해서 보는 필터버블을 굳이 막아야 하냐?"라는 피드백이 들어왔어요

이건 편향 맹점 효과랑 비판적 정보 수용 본성 관련 연구들 들고 와서 어떻게든 방어했습니다 ㅎㅎ

크롤링은 생각보다 골치가 아팠는데, 유튜브 알고리즘이 계정에 종속되다 보니 그냥 긁으면 시청 이력이 반영이 안 되더라구요

그래서 크롬 프로필을 통째로 복사해서 시청 이력을 유지하는 파이프라인을 만들었습니다

영상 제목이랑 상위 댓글 5개를 모으고, GPT-3.5/4o API로 실버 라벨링을 시켜봤는데...

단순한 감정 표현은 잘 잡는데 돌려까기나 풍자 같은 맥락적 모순은 영 못 잡더라구요

결국 손으로 600개 라벨링해서 KoBERT를 학습시켰는데,

중립 데이터가 너무 많아서 모델이 전부 다 '중립'이라고만 대답하는 모드 붕괴가 터졌습니다

첫 모델부터 이러니까 좀 막막했어요.....

유튜브

2. 그럼 관심사 분류부터 제대로 하자

                  [YouTube Crawled Data]
                            │
               [Category Dict Filtering]
                            │
      [1단계: KoELECTRA 주제 분류 (14-Class, 92% Acc)]
                            │
      [2단계: BiasAnalyzer 정치 편향 진단 파이프라인]

유튜브가 자체적으로 붙여주는 카테고리를 믿었다가 크게 데였는데요,

정치 영상이 교육으로 분류되어 있는 걸 보고 그냥 직접 만들기로 했습니다

14개 대표 카테고리별로 검색어 매핑 딕셔너리를 구축했고, 다중 검색어를 묶어서 요청하는 방식으로 일일 10,000 토큰 쿼터 한계도 어떻게든 우회했어요

이렇게 해서 수천 건 정도 모았습니다

모델은 토크나이저 연동이 자꾸 말썽이던 KoBERT를 버리고 KLUE-BERT랑 KoELECTRA를 비교해봤는데,

KoELECTRA 파인튜닝이 검증 정확도 92%, 독립 테스트 88%로 제일 좋아서 얘를 1단계 관심사 분류기로 확정했습니다

3. 과적합과의 싸움

여기가 제일 삽질이 많았던 구간이에요

  • UMAP으로 2차원 클러스터링 지도 만들어보려다가 노이즈랑 이상값 때문에 폭망
  • 로컬 LLM으로 합성 데이터 만들어보려다가 "데이터에 원래 있던 편향이 그대로 전파되는 거 아니냐"는 지적 듣고 무산
  • 영상 제목에서 채널명 키워드를 열심히 지웠더니 문맥 특징까지 같이 날아가서 정확도가 50~60%대로 추락 ㅋㅋㅋㅋ

전처리도 과유불급이라는 걸 몸으로 배웠습니다....

그러다 근본 원인을 찾았는데요, 댓글을 최대 100개까지 늘리는 데 성공한 게 오히려 독이었어요

제목이랑 댓글의 텍스트 길이 불균형이 심해지니까 모델이 제목의 핵심 맥락을 잃어버리고 댓글의 지엽적인 노이즈만 통째로 외워버리더라구요

그래서 구조를 이렇게 갈아엎었습니다:

  • 점진적 동결 해제: 백본을 초기엔 얼려두고 상단 레이어부터 낮은 학습률($5 \times 10^{-6}$)로 하나씩 풀어서 사전 학습 능력을 지켰어요
  • 4-Way Cross-Attention: Title Self, Comment Self, Title→Comment, Comment→Title 어텐션을 병렬로 붙여서 3072차원 벡터로 만들었고, 길이 불균형 문제를 정면 돌파했습니다
  • 데이터 증강: Mecab으로 고유명사를 보호한 다음 MLM 치환이랑 역번역을 돌려서 1만 개짜리 데이터셋을 만들었어요

결과는... 원본 데이터 5,000개도 안 되는 환경에서 최종 테스트 정확도 78%!!

1,150만 개 데이터로 학습한 선행 연구 PoLYTC가 75%인데 그걸 넘겼습니다

이거 나왔을 때 좀 뿌듯하더라구요 ㅎㅎ

4. 대시보드랑 전람회

React로 대시보드도 붙였습니다

섀넌 엔트로피 기반 관심사 다양성 지수랑, 시간에 따라 편향이 어떻게 움직이는지 보여주는 Bias Drift Chart가 메인이구요

Canvas API로 마우스 따라 반응하는 신경망 애니메이션이랑 PDF 보고서 추출 기능도 넣었어요

이런 건 사실 성능이랑 상관없는데 있으면 좀 그럴싸해 보이잖아요...

5. [진행 중] 실전에 넣어보니 터진 문제

정확도 78~79% 찍고 끝난 줄 알았는데 아니었습니다

실제 필드 데이터랑 실시간 유튜브 피드에 붙여봤더니,

명백한 보수/진보 데이터의 1/3 정도를 반대 성향으로 예측하는 심각한 성능 튀임 현상이 나왔어요 ㅠㅠ

원인은 키워드 쏠림

모델이 정치인 이름이나 정당명 같은 고유명사에 어텐션을 과하게 몰아주고 있었어요

그러니까 뒤에 오는 서술어가 비판인지 조롱인지 옹호인지는 아예 안 읽고, 이름만 보고 "아 이건 이쪽" 하고 단정지어 버리는 거였죠

그래서 Multi-Task Dual-Head로 개편 중

진보/보수/중립 3진 분류기 하나로는 대상과 태도가 섞인 맥락을 못 푼다고 판단해서,

라벨을 아예 [target, attitude] 형태로 바꾸고 각각 0~2 정수를 주는 멀티태스크 구조로 뜯어고치고 있습니다

               [Title / Comment Inputs]
                          │
            [KcELECTRA + Cross-Attention]
                          │
               [3072-dim Joint Vector]
                          │
             ┌────────────┴────────────┐
             ▼                         ▼
   [Target Head Layer]       [Attitude Head Layer]
   Linear(3072, 512)         Linear(3072, 512)
   ReLU + Dropout            ReLU + Dropout
   Linear(512, 3)            Linear(512, 3)
             │                         │
             ▼                         ▼
   Target Logits (3-class)    Attitude Logits (3-class)
  1. 독립 헤드 분리: 3072차원 융합 벡터까지는 그대로 두고, 맨 위에서 어떤 대상을 말하는지 판단하는 Target Head랑 그 대상을 어떤 태도로 대하는지 판단하는 Attitude Head로 갈라서 두 과제를 병렬로 학습시킵니다
  2. 후처리 추론 조합: 나온 두 값을 조합해서 보수 대상을 부정적으로 말하면 진보 성향, 보수 대상을 긍정적으로 말하면 보수 성향으로 최종 판정하는 방식이에요. 이러면 고유명사 때문에 생기는 오진을 구조적으로 막을 수 있을 것 같습니다

아직 작업 중이라 결과가 어떻게 나올지는 모르겠네요...

잘 되면 그때 또 글로 남겨보겠습니다!

그럼 오늘은 여기까지~