<jupyter_start><jupyter_text>Project 전처리<jupyter_code>import pandas as pd
import numpy as np
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.preprocessing.text import *
from tensorflow.keras.preprocessing.sequence import pad_sequences
from konlpy.tag import Okt
import pickle
pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_csv('/content/datasets/naver_news_titles_210616.csv', index_col=0)
print(df)
print(df.info())
# title의 중복확인
col_dup = df['title'].duplicated()
print(col_dup)
sum_dup = df.title.duplicated().sum()
print(sum_dup)
# title의 중복 제거
df = df.drop_duplicates(subset=['title'])
sum_sup = df.title.duplicated().sum()
print(sum_dup)
# 제거된 데이터의 인덱스 재지정
# drop = 기존 인덱스 삭제, False시 기존 인덱스가 새로운 열로 생성됨
df.reset_index(drop=True, inplace=True) 
X = df['title']
Y = df['category']
# Y(target)을- label로 변환
encoder = LabelEncoder()
labeled_Y = encoder.fit_transform(Y)
label = encoder.classes_
print(label)
# encoding mapping 정보를 저장
with open('/content/datasets/category_encoder.pickle', 'wb') as f:
  pickle.dump(encoder, f)
print(labeled_Y)
# label을 onehotencoding 으로 변환
onehot_Y = to_categorical(labeled_Y)
print(onehot_Y)
# Train data 전처리
# - 자연어 처리; 형태소 분석 kokoma, kotlan, Okt

# 형태소 분석 모듈 설치
# !pip install Okt - x
# !pip install konlp - for R
!pip install konlpy
from konlpy.tag import Okt
# 형태소 분리기 마다 성능차이가 있음, 적합한 형태소 분류기를 사용하도록 함
okt = Okt()
print(type(X))
okt_X = okt.morphs(X[0])
print(X[0])
print(okt_X)
# 하나의 문장을 형태소로 분할
for i in range(len(X)):
  X[i] = okt.morphs(X[i])
print(X)
# 접속사 조사 감탄사 등 문장분류에 도움이 되지 않는 단어들을 제거
# 불용어(stopwords) 제거 
# stopwords.csv 파일 upload
stopwords = pd.read_csv('/content/datasets/stopwords.csv')
print(stopwords)
words = []
for word in okt_X:
  if word not in list(stopwords['stopword']):
    words.append(word)
print(words)
print(len(okt_X))
print(len(words))
# 불용어 제거 후 형태소로 이루어진 문장으로 재조합
for i in range(len(X)) :
  result = []
  for j in range(len(X[i])):
    if len(X[i][j]) > 1:
      if X[i][j] not in list(stopwords['stopword']):
        result.append(X[i][j])
  X[i] = ' '.join(result)

print(X)

# 단어 tokenizing : 각 단어별로 숫자를 배정
token = Tokenizer()
token.fit_on_texts(X) # 형태소에 어떤 숫자를 배정할 것인지 배정
tokened_X = token.texts_to_sequences(X) # 토큰에 저장된 정보를 바탕으로 문장을 변환
print(tokened_X[0])

# tokenizing mapping 정보를 저장해서 차기 자료에도 동일하게 적용할 수 있도록 함
import pickle  # 데이터 형태 그대로 저장할 수 있도록함

with open('/content/datasets/news_token.pickle', 'wb') as f:
  pickle.dump(token, f)

# 형태소 개수 확인
wordsize = len(token.word_index) +1
print(token.word_index)

print(wordsize)  # index 0를 padding 으로 추가 예정
# 모델에 제공하는 데이터 길이를 맞춰주기 위한 작업 수행
# 모든 문장 중 가장 긴 문장 기준으로 맞춤
# 문장의 앞자리에 0을 추가함으로써 문장 앞부분의 영향을 미미하도록 유지

# 1. 가장 긴 문자의 길이 확인
max = 0
for i in range(len(tokened_X)):
  if max < len(tokened_X[i]):
    max = len(tokened_X[i])

print(max) # 16
# 앞쪽을 0으로 채움
X_pad = pad_sequences(tokened_X, max)
print(X_pad[:10])
# Train / test set split
X_train, X_test, Y_train, Y_test = train_test_split(X_pad, onehot_Y, test_size=0.1)
print(X_train.shape)
print(X_test.shape)
print(Y_train.shape)
print(Y_test.shape)
# train / test set을 저장
xy = X_train, X_test, Y_train, Y_test
np.save('/content/datasets/news_data_max_{}_size_{}'.format(max, wordsize), xy)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1272021498954912, 'fraction_numerical': 0.006867721707972529, 'mean_word_length': 4.897887323943662, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '492577', 'license': 'MIT', 'n_tokens_mistral': 1708, 'n_tokens_neox': 1933, 'n_words': 366, 'path': 'h_prj01_news_category_classfication_02_preprocessing.ipynb', 'repo_name': 'forhow/github-slideshow', 'size': '3349'}