본문 바로가기
project/개인공부

2022년도 Melon가사 분석을 통한 감정분류

by 왕방개 2024. 4. 1.

1.Openai api 사용방법

1)개요

 

Openai 의 API 는 거의 모든 작업에 적용 가능.

다양한 기능과 가격대의 다양한 모델을 제공할 뿐만 아니라 맞춤형 모델을 미세조정할 수 있는 기능도 제공함.

 

2)사용 가능한 모델

3)API Document

https://platform.openai.com/docs/introduction

=>자주 바뀌고 최근 Document에 대한 설명이 잘 되있지 않아서 어려움을 겪음

 

4)API 활용법

 

=>API key 생성

※API key 한번 생성되고 다시 나오질 않음.따로 작성해놔야함

 

=>설치

pip install openai

 

=>사용

import openai

openai.api_key = "각자 API key 값" # API Key
completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "hello to my friends"}]
)

print(completion)

content 부분에 물어보고싶은 말을 작성해서 물어보면 됨

 

2.멜론 2022년도 가사 크롤링

1)selenium에서 Chrome Web driver를 활용해서 Driver 연결

# selenium 4
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))

 

2) 가사 가져오는 함수 제작 =>find_elements 활용해서 제작

#가사 가져오기
def craw_lyrics():
    try:
        artist = driver.find_elements(By.CLASS_NAME, 'artist')
        song_name = driver.find_elements(By.CLASS_NAME, 'song_name')
        lyric = driver.find_elements(By.CLASS_NAME, 'lyric')
        driver.implicitly_wait(60)

        lyrics = lyric[0].text.split('\n')

        artists.append(artist[0].text)
        song_names.append(song_name[0].text)
        ly.append(lyrics)
    except:
        return

 

가사를 가져오기 전에 멜론 시대별 코너에서 시대별 코너에 있는 번호를 가져와야함

https://www.melon.com/chart/age/index.htm?chartType=YE&chartGenre=KPOP&chartDate=2022

 

Melon

음악이 필요한 순간, 멜론

www.melon.com

여기 가면 2022년도 가장 인기가 많았던 가요들이 존재.

https://www.melon.com/song/detail.htm?songId=34847378 멜론은 songId 별로 노래가 저장되있음을 확인할 수 있었음. 따라서 songID 를 우선적으로 list 로 반환한뒤 각 url 별로  제목, 가수, 가사를 가져오기로 함.

 

3)스크롤하면서 list 을 가져오고 각 곡정보 url 에 들어가 artist, song_name, lyric을 csv 파일로 저장

# 2022년 돌아다니면서 스크롤
for year in range(2022, 2023):
    
    driver.get('https://www.melon.com/chart/age/index.htm?chartType=YE&chartGenre=KPOP&chartDate={y}'.format(y=year))
    song_num = []
    artists = []
    song_names = []
    ly = []

    lst50 = driver.find_elements(By.CSS_SELECTOR, "#lst50 > td:nth-child(5) > div > button")
    
    for i in lst50:
        song_num.append(i.get_attribute('data-song-no'))


    for i in song_num:
        driver.get('https://www.melon.com/song/detail.htm?songId={song_num}'.format(song_num=i))
        craw_lyrics()

    df = pd.DataFrame(artists, columns=['artist'])
    df['song_name'] = song_names
    df['lyric'] = ly

    df.to_csv("song{y}.csv".format(y=year), index=False, encoding='utf-8')

이런식으로 저장해놓음

 

 

3.OpenAI API을 활용한 멜론 가사 감정 분류

 

1)csv 파일 불러오기

import pandas as pd

song=pd.read_csv('./song2022.csv')
print(song['lyric'][0])

 

2)첫번째 아이브 LoveDive 감정 분류

lyrics=song['lyric'][0]
openai.api_key = "APIKEY" # API Key
completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "{}가사가 이건데 어떤 감정인지 알려줘".format(lyrics)}],
   
)
print(completion)

content값이 유니코드로 반환되서 다시 content 결과창 확인

content = completion.choices[0].message['content']
print(content)

 

이런식으로 진행나오는것을 확인할 수 있었음.

하지만 이렇게 나오면 감정을 정리하기 어려워보여서 다르게 질문을 해봄.

 

=>최종 50개에 대한 각 가사를 5개 단어로 요약

import openai

openai.api_key = "API Key"  # API Key

content = []

for i in range(0, 50):
    lyrics = song['lyric'][i]
    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "{}가사가 이건데 어떤 감정인지 5단어로 감정표현해줘".format(lyrics)}],
    )
    emotion = completion.choices[0].message['content']
    content.append(emotion)

print(content)

 

=>이를 원래 song에 추가해서 csv 파일로 저장

#데이터프레임 변환
df_emotions = pd.DataFrame(content)

# 데이터프레임 병합
df_combined = pd.concat([song, df_emotions], axis=1)

# 이를 csv 파일로 다시 저장
df_combined.to_csv('combined_data.csv', index=False)

=>어떤 단어가 가장 많이 등장했는지 확인해보기

from collections import Counter

song=pd.read_csv('./combined_data.csv')

# 감정들 단어를 한 줄로 변환
all_emotions = ' '.join(song['0'])

# 감정 토큰화
tokens = all_emotions.split()

# 각 토큰의 Counter
token_counts = Counter(tokens)

# token에서 가장 많이 등장한 순으로 정리
most_common_tokens = token_counts.most_common()

print(most_common_tokens)