[OpenAI 파이선 API 부트캠프] 메타코드M OpenAI를 활용한 파이썬 API 부트캠프 강의 후기 - Project 4 해외 뉴스 번역기

안상훈·2024년 10월 2일

메타코드M

목록 보기
19/27
post-thumbnail

도입

인공지능과 데이터 분야에 대한 관심이 점점 커지고 있는 요즘, 많은 사람이 실제로 어떻게 기술을 활용할 수 있을지 고민하고 있다. 이번 강의는 파이썬과 OpenAI API를 이용해 데이터를 다루고, 의미 있는 결과물을 도출하는 과정을 다룬다. 파이썬을 어느 정도 다룰 줄 안다면 누구나 따라 할 수 있는 실습 프로젝트들로 구성되어 있어, 학습자가 자신의 실력을 자연스럽게 발전시킬 수 있는 기회를 제공한다.

8개의 다양한 프로젝트를 통해, 자연어 처리부터 감정 분석, 데이터 시각화까지 다루며 현업에서 바로 적용할 수 있는 스킬들을 익힐 수 있다. 실제로 데이터 수집부터 분석, 그리고 모델 튜닝까지의 전체 과정을 경험하면서 AI와 데이터 사이언스의 기본기를 확실히 다질 수 있을 것이다.

지금 이 강의를 통해, 데이터의 세계에서 원하는 결과를 보다 쉽게 얻어보라. 어렵게 느껴질 수 있는 AI 기술이 실습과 프로젝트를 통해 친숙해질 것이다.

https://metacodes.co.kr/edu/read2.nx?M2_IDX=31635&EP_IDX=9859&EM_IDX=9683


1. 프로젝트 개요

이번 프로젝트를 해외의 뉴스를 OpenAI - Completion API를 활용하여 해외 뉴스를 한국어로 번역하는 프로그램의 개발이다.

참고로 OpenAI에서 제공하는 LLM은 범용성이 좋은 모델이지 번역서비스에 특화된 모델은 아니다.

따라서 번역이 이렇게 가능하다 이정도만 숙지하고
전문 번역 툴을 개발하고자 한다면 전용 모델을 사용하는 것이 훨씬 더 유리한 측면이 있다.

코드개발의 순서로는
1) 타겟 뉴스를 크롤링할지? 결정하는 유저 요청을 받으면
2) 이를 크롤링 - > 번역하여

마지막에 단순 번역과 / 번역의 요약본
두가지 결과물을 제공하는 API의 설계이다.


2. 코드실습

from dotenv import load_dotenv
from openai import OpenAI
import os

load_dotenv()  # .env 파일의 환경 변수를 불러옴
api_key = os.getenv('OPENAI_API_KEY')

# API 키가 정상적으로 불러와졌는지 확인
#print(f"API Key: {api_key}")

client = OpenAI()

2.1. URL이해하기

참고로 뉴스정보를 제공하는 웹사이트는 웹사이트의 구성 및 규격, 포멧이 모두 상이하게 다르기에
특정 뉴스 사이트의 데이터를 수집한다면 해당 뉴스 웹페이지의 구성을 어느정도 파악할 필요가 있다.

\rightarrow 즉 해당 웹페이지의 HTML코드 구성을 리뷰할 정도의 수준은 되어야 한다.

학습을 위한 사이트는 CNN 뉴스 웹페이지를 선정했으며

여기서 기사의 Headline와 기사의 Article이 HTML 코드에서 어느 부분에 속하는지 확인해야 한다.

이를 확인하는 방법은 chrome 웹 브라우저 기반 F12버튼을 누르면 HTML 코드를 확인할 수 있다.

현재 기사의 헤드라인 코드는

<h1 data-editable="headlineText"
    class="headline__text inline-placeholder vossi-headline-text" 
    id="maincontent">
      Shocking surveillance tape of Kentucky judge’s shooting played in court as sheriff’s murder case sent to grand jury
    </h1>

그리고 기사의 아티클 코드는

<div class="article__content" data-editable="content" itemprop="articleBody" data-reorderable="content">
                  
                  여기에 엄청 길게 기사가 있음

              </div>

이렇게 되어 있으니 해당부분을 일단 기억해둘 필요성이 있다.

일단 위에서 취할 내용은

헤드라인 : headline__text

기사 본문 : article__content

이 두 부분을 취해야 한다는 것을 알면 된다.


2.2 HTML 파싱

import requests
import bs4
# 기사 홈페이지를 req하여 정보를 취득
result =requests.get(url)
# 취득한 정보를 bs4 라이브러리로 파싱
soup = bs4.BeautifulSoup(result.text, 'lxml')
# 기사 헤드라인이 있는 부분(태그)
headline_tag = ".headline__text"
# 기사 본문이 있는 태그
article_tag = ".article__content"

위와 같이 request, bs4라이브러리를 활용하여 웹페이지 크롤링을 완료한 뒤에는

해당 정보를 OpenAI - API에 넘겨서 기사 번역 Task를 수행하면 된다.


2.3 뉴스 번역하기

url, 태그정보를 딕셔너리로 한번에 정리하기

target_trans_url = {
    'target_url' : url,
    'headline_tag' : headline_tag,
    'article_tag' : article_tag
}
# 기사번역을 위한 시스템 프롬포트 설정
def system_prompt():
    return '''헤드라인과 기사를 한국어로 번역
    헤드라인은 전문 번역,
    기사는 번역 후 요약 수행,'''

다음으로 user_prompt를 작성하기 전 데이터 전처리 함수도 함께 설계하여 이를 callback함수로 넘겨줄 수 있도록 코드를 작성한다.

def data_preprocess(target_dict):
    try:
        url, head_tag, art_tag = target_dict.values()
    except KeyError:
        print('데이터 입력 구조가 잘못됨')

    # 웹사이트 크롤링
    result = requests.get(url)
    soup = bs4.BeautifulSoup(result.text, 'lxml')

    # 기사 헤드라인 가져오기
    headline = ''
    for item in soup.select(head_tag):
        headline += item.getText()
    
    article = ''
    for item in soup.select(art_tag):
        article += item.getText()
        
    return headline, article

format_template = '''
### 기사 헤드라인 : [...] ### \n\n
### 기사 2문단 요약 ###
~~~ ~~~ \n\n
### 기사 3줄 요약###
~~ ~~ ~~
'''
def user_prompt(target_dict, format_template):
    headline, article = data_preprocess(target_dict)

    return f'''번역 전 불필요한 html코드는 모두 제거한다.
    헤드라인 : {headline}은 전문을 번역한다.
    기사 : {article}는 번역 후 두문단 요약, 3줄 요약 두가지를 수행한다.
    두문단 요약은 총 600자를 적절한 2개의 문단으로 나누어 요약한다.
    3줄 요약은 3개의 문장으로 기사를 요약한다.
    출력 형식은 {format_template}를 따른다.'''

마지막으로 설계한 system_prompt, user_prompt를 바탕으로 기사번역 및 기사요약을 수행하도록 API를 구동하자

response = client.chat.completions.create(
    model = "gpt-4-turbo",
    messages=[
        {"role": "system", "content": system_prompt()},
        {"role": "user", "content": 
            user_prompt(target_trans_url, format_template)},
    ],
    max_tokens = 1000
)


2.4 데이터 후처리

마지막으로 format_templete를 통하여 번역 및 요약되는 기사의 형식을 지정했으니

이를 활용하여 데이터 후처리를 수행한다

import re
import kss

p1 = re.compile(r'\n{2,}')
p2 = re.compile(r'\[(.*?)\]')
p3 = re.compile(r'^#{2,}.*#{2,}\n')


def parser_text(response):
    raw_taxt = response.choices[0].message.content

    tr_news = {}

    data = p1.split(raw_taxt)
    # 헤드라인의 번역된 데이터 추출
    tr_news['헤드라인'] = p2.findall(data[0])
    data[1] = p3.sub("", data[1])

    def split_by_length(text, length=30):
        return [text[i:i+length] for i in range(0, len(text), length)]

    temp = []
    for i in range(1, 3):
        temp.append(split_by_length(data[i]))
    tr_news['두문단 요약'] = temp

    data[3] = p3.sub("", data[3])
    tokenized_sent_kss = kss.split_sentences(data[3])
    tr_news['3줄 요약'] = tokenized_sent_kss
    return tr_news

후처리된 기사의 번역 및 요약정보는 딕셔너리 형태로 파싱이 수행되니 이를 확인해보자

result = parser_text(response)

for idx, vel in result.items():
    if idx == '헤드라인':
        print(idx, vel)
    elif idx == '두문단 요약':
        print(idx, end='\n')
        for i in vel:
            print()
            for j in i:
                print(j)
    
    elif idx == '3줄 요약':
        print(idx, end='\n')
        for i in vel:
            print(i)

결과물을 확인한다면 기사 헤드라인 / 기사본문의 두문단 및 3줄요약 결과를 알아보기 쉬우면서도
향후 후처리가 용이하게끔 수행을 완료했다.


감사의 글

본 포스트는 메타코드 서포터즈로서 작성하였습니다

profile
자율차 공부중

0개의 댓글