텍스트 데이터를 딥러닝 모델에 넣을 수 있는 형식으로 변환
데이터 준비
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet as wn
import nltk
from nltk.corpus import stopwords
nltk.download("punkt")
nltk.download('wordnet')
nltk.download('stopwords')
def penn_to_wn(tag):
if tag.startswith("J"):
return wn.ADJ
elif tag.startswith("N"):
return wn.NOUN
elif tag.startswith("R"):
return wn.ADV
elif tag.startswith("V"):
return wn.VERB
def words_lemmatizer(pos_tagged_words):
lemmatizer = WordNetLemmatizer()
lemmatized_words = []
for word, tag in pos_tagged_words:
wn_tag = penn_to_wn(tag)
if wn_tag in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB):
stem = lemmatizer.lemmatize(word, wn_tag)
lemmatized_words.append(stem)
else:
lemmatized_words.append(word)
return lemmatized_words
def clean_by_freq(tokenized_words, cut_off_count):
vocab = Counter(tokenized_words)
# 빈도수가 cut_off_count 이하인 단어를 제거하는 코드를 작성해 주세요
uncommon_words = {key for key, value in vocab.items() if value <= cut_off_count}
cleaned_words = [word for word in tokenized_words if word not in uncommon_words]
return cleaned_words
def clean_by_len(tokenized_words, cut_off_length):
cleaned_words = []
for word in tokenized_words:
# 길이가 cut_off_length 이하인 단어 제거하는 코드를 작성해 주세요
if len(word) > cut_off_length:
cleaned_words.append(word)
return cleaned_words
def clean_by_freq(tokenized_words, cut_off_count):
vocab = Counter(tokenized_words)
# 빈도수가 cut_off_count 이하인 단어를 제거하는 코드를 작성해 주세요
uncommon_words = {key for key, value in vocab.items() if value <= cut_off_count}
cleaned_words = [word for word in tokenized_words if word not in uncommon_words]
return cleaned_words
def clean_by_len(tokenized_words, cut_off_length):
cleaned_words = []
for word in tokenized_words:
# 길이가 cut_off_length 이하인 단어 제거하는 코드를 작성해 주세요
if len(word) > cut_off_length:
cleaned_words.append(word)
return cleaned_words
def pos_tagger(tokenized_sents):
pos_tagged_words = []
for sentence in tokenized_sents:
# 단어 토큰화
tokenized_words = word_tokenize(sentence)
# 품사 태깅
pos_tagged = pos_tag(tokenized_words)
pos_tagged_words.extend(pos_tagged)
return pos_tagged_words
# 불용어 제거 함수
def clean_by_stopwords(tokenized_words, stop_words_set):
cleaned_words = []
for word in tokenized_words:
if word not in stop_words_set:
cleaned_words.append(word)
return cleaned_words
import pandas as pd
from nltk.tokenize import sent_tokenize
from nltk.tag import pos_tag
from nltk.corpus import stopwords
nltk.download("stopwords")
# 불용어 제거 함수
def clean_by_stopwords(tokenized_words, stop_words_set):
cleaned_words = []
for word in tokenized_words:
if word not in stop_words_set:
cleaned_words.append(word)
return cleaned_words
stopwords_set = set(stopwords.words("english"))
df = pd.read_csv("imdb.tsv", sep = '\t')
del df['Unnamed: 0']
df['review'] = df['review'].str.lower() # 소문자 처리
df["sent_tokens"] = df['review'].apply(sent_tokenize) # 문장 토큰화
df["pos_tagged_tokens"] = df['sent_tokens'].apply(pos_tagger) # 형태소
df["lemmatized_tokens"] = df['pos_tagged_tokens'].apply(words_lemmatizer)
df["cleaned_tokens"] = df['lemmatized_tokens'].apply(lambda x : clean_by_len(x, 2))
df['cleaned_tokens'].apply(lambda x : clean_by_stopwords(x, stopwords_set))
df
단어별로 라벨링
# 단어별로 라벨링
# 빈도가 많이 나온 단어부터 라벨링(중요)
from collections import Counter
words = []
for i in df['cleaned_tokens']:
words += i
vocab = Counter(words) # 빈도수 계산
vocab = vocab.most_common() # 빈도 높은 순서대로 정렬
word_to_idx = {}
for word, freq in vocab:
word_to_idx[word] = len(word_to_idx) + 1
word_to_idx
# 단어 토큰들을 숫자 인덱스로 변환하는 함수
def idx_encoder(tokens, word_to_idx):
idx_box = []
for i in tokens:
idx_box.append(word_to_idx[i])
return idx_box
df['integer_encoded'] = df['cleaned_tokens'].apply(lambda x : idx_encoder(x, word_to_idx))
df
각 문장의 길이를 고정된 길이로 맞추기 (짧은 시퀀스는 0으로 패딩)
max_len = 0
for i in df['integer_encoded']:
if len(i) >= max_len:
max_len = len(i)
max_len
for tokens in df['integer_encoded']:
while len(tokens) < max_len:
tokens.append(0)
for i in df['integer_encoded']:
print(len(i))
감성분석
wordnet(감성사전) : 단어랑 의미
SentiWordNet : 감성 분석을 위한 감정 점수(긍정, 부정, 중립)를 제공
# 감성분석
# wordnet(감성사전) : 단어랑 의미
from nltk.corpus import wordnet as wn
word = wn.synsets('lead') # 동의어 집합(synonym set)을 반환
word
wn.synset('lead.n.01').definition() # 명사 첫번째 의미에 대한 정의 -> 납으로 쓰임
from nltk.corpus import sentiwordnet as swn
nltk.download('sentiwordnet')
a = list(swn.senti_synsets('happy'))[0]
a.pos_score() - a.neg_score()
→ "happy"라는 단어가 긍정적인 감정을 더 많이 가지고 있음
NLTK의 wordnet과 sentiwordnet을 사용하여
"hard"의 형용사(ADJ)와 부사(ADV) 형태에 대한 감성 점수를 비교
from nltk.corpus import wordnet as wn
from nltk.corpus import sentiwordnet as swn
import nltk
# 단어 'hard'의 형용사와 부사에 대한 SentiWordNet 객체 생성
a = wn.synsets('hard', wn.ADJ)[0]
b = wn.synsets('hard', wn.ADV)[0]
# SentiWordNet 객체 생성
a2 = swn.senti_synset(a.name())
b2 = swn.senti_synset(b.name())
# 감성 점수 출력
print("형용사 'hard'의 감성 점수:", a2)
print("부사 'hard'의 감성 점수:", b2)
pos_tagged_words = df['pos_tagged_tokens'][0] # (단어, 품사 태그)의 튜플 리스트 가져오
score = 0
for word, tag in pos_tagged_words:
tag = penn_to_wn(tag) # Penn Treebank 품사 태그를 WordNet 품사 태그로 변환
if tag not in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB): # 유효한 품사(명사, 형용사, 부사, 동사)인 확인
continue
if not wn.synsets(word, tag): # 해당 단어와 품사에 대한 synset(의미 집합)이 존재하는지 확인
continue
else:
synsets = wn.synsets(word, tag)
synset = synsets[0] # 첫 번째 synset을 선택하여 감성 점수를 가져오
senti = swn.senti_synset(synset.name())
senti2 = senti.pos_score() - senti.neg_score()
score += senti2
print(score)
- 주어진 단어 목록에서 각 단어에 대해 유효한 품사인지 확인하고, WordNet에서 해당 단어의 의미 집합 찾기
- 각 단어의 감성 점수를 계산하여 총 점수에 누적
- 최종적으로 감성 점수를 출력
df에 감성점수 열 추가하기
# df에 감성점수 열 추가하기!
def check_senti_score(tokens):
pos_tagged_words = tokens
score = 0
for word, tag in pos_tagged_words:
tag = penn_to_wn(tag)
if tag not in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB):
continue
if not wn.synsets(word, tag):
continue
else:
synsets = wn.synsets(word, tag)
synset = synsets[0]
senti = swn.senti_synset(synset.name())
senti2 = senti.pos_score() - senti.neg_score()
score += senti2
return score
df['Senti Score'] = df['pos_tagged_tokens'].apply(check_senti_score)
df
VADER 감정 분석기
감정 분석기를 사용하여 세 가지 문장에 대한 감정 점수를 계산
from nltk.sentiment.vader import SentimentIntensityAnalyzer
nltk.download('vader_lexicon')
analyzer = SentimentIntensityAnalyzer()
text1 = 'This is a great movie!'
text2 = 'This is a terrible movie!'
text3 = 'This movie was just okay'
print(analyzer.polarity_scores(text1))
print(analyzer.polarity_scores(text2))
print(analyzer.polarity_scores(text3))
def vader_sentiment(text):
analyzer = SentimentIntensityAnalyzer()
score = analyzer.polarity_scores(text)['compound']
return score
df['Vader Score'] = df['review'].apply(vader_sentiment)
df
한국어 감성분석
# 한국어 감성분석 (군산대학)
knu = pd.read_csv('knu_sentiment_lexicon.csv')
knu_dic = dict(zip(knu['word'], knu['polarity']))
text = '이 제품 정말 좋아요'
def sentiment_analysis(text):
score = 0
for key, value in knu_dic.items():
if key in text:
score += value * text.count(key)
return score
sentiment_analysis(text)
OpenAI
# Python + ChatGPT
# 1. 저렴하다
# 2. 공식사이트보다 더 높은 버전 사용 가능
#!pip install openai
from openai import OpenAI
openai = OpenAI(api_key = 'sk-g27B9BcTnEABs_w0-T5RPTXOAEzOxEUD-uMOmUP3CST3BlbkFJXFIK4FwCziu0DmNEOUpgPJjDJPobLv2eSLV3HlyYsA')
box = [{"role" : "system", "content" : "너는 포켓몬마스터야."},
{"role" : "user", "content" : "제일 약한 포켓몬이 누구야?"}]
while True:
a = input("입력 : ")
if a == "종료":
break
box.append({"role" : "user", "content" : a})
model = openai.chat.completions.create(
model = "chatgpt-4o-latest",
messages = box
)
result = model.choices[0].message.content
box.append({"role" : "assistant", "content" : result})
print(result)
그림 그리기
model = openai.images.generate(
model = 'dall-e-3',
prompt = "베트남으로 여행간 여행객이 지쳐서 쉬고있는 모습을 일본 애니매이션 스타일로 여자 캐릭터를 귀엽게 그려줘.",
size = "1024x1024",
n = 1
)
주어진 이미지 변형, 확장
model = openai.images.create_variation(
model = 'dall-e-2',
image = open("피카소.png", 'rb'),
n = 1,
size = "1024x1024"
)
'파이썬 & 머신러닝과 딥러닝' 카테고리의 다른 글
금융 데이터 전처리 (주식 데이터월별, 분기별, 주별 데이터 집계, 거래량 변화 탐지, 모멘텀 전략 및 수익률 계산, 볼린저 밴드) (1) | 2024.10.21 |
---|---|
Okt 형태소 분석기(빈도기반), 워드클라우드, 상대빈도분석(오즈비 분석), TF-IDF 분석 (1) | 2024.10.14 |
자연어 처리 - 소문자 변환, 토큰화, 빈도 분석 (7) | 2024.10.10 |
영화 추천 시스템, 동적 크롤링 (3) | 2024.10.02 |
시계열, RNN, Seq2Seq, 어텐션, ARIMA, CNN (0) | 2024.09.09 |