이은지

dleunji.github.io

Word + Excel로 csv파일 전처리하기

오늘 전처리해볼 resume csv자료는 Kaggle에서 얻었으며, 이를 통해 Resume Generator를 만들었습니다. 주로 csv파일은 Python의 Pandas 함수를 활용하여 전처리를 하지만, 워드와 엑셀로도 간단한 전처리가 가능합니다! 

  1. Encoding
데이터 csv 파일을 Excel에서 바로 열었을 경우 다음과 같이 보입니다. 일부 텍스트가 인코딩 문제로 깨졌기 때문입니다. 파일을utf-8 옵션으로 열면 이 문제가 해결됩니다. 하지만 MacOS의 경우 파일을 열 때, 옵션을 부여할 수 없기에 빈 엑셀 창에서 [데이터] - [외부데이터 가져오기] - [텍스트에서]를 택하고, 해당 파일을 열 때 인코딩방식을 부여할 수 있습니다.
만약 여전히 인코딩 문제가 발생한다면 파일을 우클릭하여 Word 로 파일을 열고, utf-8 인코딩 방식으로 문서를 전환 후 저장하시길 바랍니다.

만약 Word를 사용하셨다면 종료하지 말아주세요! 다음 단계에서 더욱 섬세한 정제 작업이 기다리고 있습니다.

2. Cleaning Text
Word로 csv 파일을 열어서 인코딩 문제가 발생하는 문자 외에도 불필요한 문자를 제거합니다. 여기 를 참고하시면 Word를 활용하여 어떻게 전처리를 하는지 상세히 나와있습니다. 여기에서는 알파벳, 숫자, 쉼표, 일부 필요한 특수문자만을 남길 것입니다. 그 중 쉼표를 절대 놓쳐선 안됩니다. csv파일은 쉼표로 데이터가 분리되기 때문에 만약 쉼표가 사라진다면 csv파일을 쓸 수 없게 됩니다. 이 점에 유의하면 아래와 같이 정규표현식을 통해 전처리가 가능합니다.

제가 작성한 정규표현식은 [A-Za-z0-9\\,\\(\\)\\/\\.\\:\\-\\s\\#\\&]입니다. 대괄호[]를 통해 여러 개의 문자 중 하나만 매치되어도 그에 해당되는 것으로 판단지을 수 있습니다. 그러나 not을 의미하는 !을 사용함으로써 뒤의 내용에 해당되지 않는 문자들을 찾아내도록 합니다. 어려워보이지만 대괄호 안의 정규표현식 내용은 크게 A,B,C로 나뉩니다.
  • A : 공백 (띄어 쓰기)
  • B : 문자(대/소문자 영어, 숫자)
  • C : , ( ) / . : - # & 와 같은 특수문자
c.f. 특수문자 앞에 쓰인 /(backslash)는 escape character로, 별다른 뜻 없이 순수하게 해당 특수문자를 의미한다고 이해하시면 편합니다:)
e.g. C#, Python(Django, Flask...)
즉 A, B, C에 해당하는 문자들은 resume 작성에 필요한 문자들로, 이에 하나라도 해당되지 않는 문자들을 제거합니다.

3. Filtering
Excel로 파일을 열고 [데이터] - [필터] 기능을 활용하여 Category 에서 Developer 계열의 직업만을 추출합니다.


4. Wrap Up
필터링 이후 남은 Resume Column 값을 전체 선택(ctrl + a) 후 복사(ctrl+ c)하여, 하나의 텍스트로 만듭니다. 이 때 Word나 메모장을 이용해 개행문자를 제거함으로써 전처리된 텍스트를 활용하실 수 있습니다.


Like Comment

개발자를 위한 Résumé 생성기

1. Background

만약 취업이나 이직을 준비하고 계시다면 résumé 쓰기는 피할 수 없습니다. résumé에는 지금까지의 자신만의 이력과 성취에 대해서 단 한 장에 간결하게 설명해야 합니다. 지금까지 코드와 고군분투하며 살아왔지만, 막상 résumé를 쓰려면 무얼, 어떻게 쓸지 막막해지기 쉽습니다.
이처럼 코드 짜기보다 자신을 소개하는 글쓰기가 더 어려운 개발자들을 위해, Teachable NLP를 통해 résumé를 편리하게 생성하는 모델을 만들었습니다. 실제로 단 몇 분만에 제 résumé는 다음과 같이 완성되었습니다.
- Creating Web RESTful API
- Web Frontend with HTML, CSS
- Taking part in preprocessing steps of machine learning mainly missing value treatment, outlier detection, encoding, scaling, feature selection.
- Testing machine learn algorithms in python. optimizing of existing algorithms.
이러한 모델은 어떻게 만들 수 있었는지, 처음부터 자세히 설명드리겠습니다.

2. Acquiring Dataset

모델 학습에 필요한 데이터는 Kaggle에서 구할 수 있었습니다. 해당 파일은 .csv의 형태로 직업 분류와 그에 따른 resume의 형태로 이루어졌습니다. 




3. Preprocessing Text

이 파일은 csv 형식이었기에 엑셀로 전처리가 가능하였습니다. No-code 방식이 궁금하시다면 여기를 참고해주세요:) 저는 코드로 전처리 작업을 해보기 위해 파이썬의 대표적인 패키지 중 하나인 Pandas 를 활용하여 Jupyter notebook에서 이를 진행하였습니다.

우선 파일을 읽고, 해당 내용을 DataFrame으로 만든 후 데이터의 기본적인 사항들을 점검하였습니다.
가장 먼저 개발자를 위한 resume인 만큼, 개발자 관련 resume가 충분히 존재하는지부터 살폈습니다. 이후 resume column에서 null값의 유무를 확인하였습니다. 만약 데이터를 처리할 때, null값이 있다면 전처리하기 전에 제거하기 위함입니다. 다행히 해당 데이터에는 두 컬럼값 모두 non null이었습니다.
import pandas as pd
import numpy as np
# Read File
data = pd.read_csv('/opt/notebooks/UpdatedResumeDataSet.csv')

# Check categories
print(data['Category'].unique())

"""
['Data Science' 'HR' 'Advocate' 'Arts' 'Web Designing'
 'Mechanical Engineer' 'Sales' 'Health and fitness' 'Civil Engineer'
 'Java Developer' 'Business Analyst' 'SAP Developer' 'Automation Testing'
 'Electrical Engineering' 'Operations Manager' 'Python Developer'
 'DevOps Engineer' 'Network Security Engineer' 'PMO' 'Database' 'Hadoop'
 'ETL Developer' 'DotNet Developer' 'Blockchain' 'Testing']
"""
# Check the numbers of data
print(data['Category'].value_counts())

"""
Java Developer               84
Testing                      70
DevOps Engineer              55
Python Developer             48
Web Designing                45
HR                           44
...
"""
# Count null value
data['Resume'].isna().sum()
"""
0
"""
이를 기반으로 크게 2가지로 전처리 작업을 하였습니다.
A) 특수문자를 비롯한 불필요한 문자를 제거하고,
B) 개발자에 해당하는 내용만 추출하여
원하는 resume for developers 모델의 text를 준비했습니다.

A) Remove Unnecessary Words

보통 데이터 정제 시 숫자와 불용어(stopwords)(의미가 없는 단어 토큰)를 제거하거나 지나치게 길이가 짧은 단어를 제거합니다. 하지만 여기서는 이러한 정제 과정을 생략하였습니다. 숫자와 불용어를 제거한 데이터를 기반으로 글을 작성하자 기존 resume의 형식이 모두 사라져 문장 생성 시 가독성이 지나치게 떨어지는 현상이 발생했기 때문입니다. 예를 들어 HTML Experience - Less than 3 months 라는 문장을 정제할 시에, 추후 문장이 생성될 때 html experience less than months라는 문장이 튀어나와 사용자들의 문장 인식을 어렵게 만들었습니다.
또한 resume에 존재할 수많은 개발 용어 (nltk, api ...)들이 축약어임을 고려한다면 단순히 단어 길이만으로 단어를 정제하기에는 무리가 있었습니다.
결과적으로 다음과 같이 전처리를 진행하였습니다. 
그 예시로 첫 번째 resume를 보겠습니다. 항목을 나타내는 *를 제거하고, 인코딩에러가 발생하는 단어를 삭제해야했습니다. 괄호와 쉼표도 생략할까 고민하였지만, 괄호를 통해 해당 프로그래밍 언어의 라이브러리, 패키지, 프레임워크라는 의미를 퇴색시킬 우려가 있어 정제하지 않았습니다.
오히려 숫자, -, (,), , 와 같은 기호들을 통해 사용자에게 resume의 format을 안내해줄 수 있다고 생각하였습니다.
"Skills * Programming Languages: Python (pandas, numpy, scipy, scikit-learn, matplotlib), Sql, Java, JavaScript/JQuery. * Machine learning: Regression, SVM, Na횄짱ve Bayes, KNN, Random Forest, Decision Trees, Boosting techniques, Cluster Analysis, Word Embedding, Sentiment Analysis, Natural Language processing, Dimensionality reduction, Topic Modelling (LDA, NMF), PCA & Neural Nets. * Database Visualizations: Mysql, SqlServer, Cassandra, Hbase, ElasticSearch D3.js, DC.js, Plotly, kibana, matplotlib, ggplot, Tableau. * Others: Regular Expression, HTML, CSS, Angular 6, Logstash, Kafka, Python Flask, Git, Docker, computer vision - Open CV and understanding of Deep learning.Education Details 

Data Science Assurance Associate 

Data Science Assurance Associate - Ernst & Young LLP
Skill Details 
JAVASCRIPT- Experience - 24 months
jQuery- Experience - 24 months
Python- Experience - 24 monthsCompany Details 
.
.
.
MULTIPLE DATA SCIENCE AND ANALYTIC PROJECTS (USA CLIENTS)
TEXT ANALYTICS - MOTOR VEHICLE CUSTOMER REVIEW DATA * Received customer feedback survey data for past one year. Performed sentiment (Positive, Negative & Neutral) and time series analysis on customer comments across all 4 categories.
* Created heat map of terms by survey category based on frequency of words * Extracted Positive and Negative words across all the Survey categories and plotted Word cloud.
* Created customized tableau dashboards for effective reporting and visualizations.
CHATBOT * Developed a user friendly chatbot for one of our Products which handle simple questions about hours of operation, reservation options and so on.
* This chat bot serves entire product related questions. Giving overview of tool via QA platform and also give recommendation responses so that user question to build chain of relevant answer.
* This too has intelligence to build the pipeline of questions as per user requirement and asks the relevant /recommended questions.
.
.
.
창짖 FAP is a Fraud Analytics and investigative platform with inbuilt case manager and suite of Analytics for various ERP systems.
* It can be used by clients to interrogate their Accounting systems for identifying the anomalies which can be indicators of fraud by running advanced analytics
Tools & Technologies: HTML, JavaScript, SqlServer, JQuery, CSS, Bootstrap, Node.js, D3.js, DC.js"

이러한 전처리를 위한 코드는 다음과 같습니다.
import re
import string

def clean_text(text):
    text = text.lower()
    #remove any numeric characters
    #text = ''.join([word for word in text if not word.isdigit()])
    #remove *(asterisk)
    text = re.sub('\\*','',text)
    #replace consecutive non-ASCII characters with a space
    text = re.sub(r'[^\\x00-\\x7f]',r' ',text)
    #extra whitespace removal
    text = re.sub('\\s+', ' ',text)
    return text

data['cleaned_text'] = data['Resume'].apply(lambda x : clean_text(x))
re 라는 패키지로 정규표현식(regex, regular exprerssion)을 통해 정교하게 텍스트를 정제하였습니다. 복잡하지만 하나하나 뜯어보면 쉽게 이해하실 수 있습니다. 여기에 쓰인 정규표현식을 바탕으로 간략히 주요 특수문자만 소개해드리겠습니다.


이렇게 전처리 후 DataFrame의 apply함수를 활용하여 DataFrame에 새로운 column인 cleaned_text으로 정제된 데이터를 DataFrame에 추가하였습니다. 그 결과를 출력해보니 데이터가 한결 깔끔해졌습니다.


B) Extract Resume Only For Developer

전체 데이터에는 Developer외에도 HR, Arts, Mechanical Engineer 등 다양한 직군이 있습니다. 그 중에서 Developer에 해당하는 직군의 resume만 필터링하였습니다. 그 후 resume를 추출하여 텍스트 파일로 저장하였습니다.
cleaned_data = data.loc[data.Category.isin([
    'Java Developer','Testing', 'DevOps Engineer', 'Python Developer',
    'Hadoop','ETL Developer','Blockchain','Data Science','Database',
    'DotNet Developer','Network Security Engineer','SAP Developer'])]

# Make the resume as one text
result = ""
for idx, row in cleaned_data.iterrows():
    result = result + row['cleaned_text'] + " "

# Save the text to a file
f = open("/opt/notebooks/developer.txt","w")
f.write(result)
f.close()

4. Teachable NLP

Teachable-NLP는 코드를 따로 작성할 필요없이 하나의 텍스트 파일만으로 GPT-2을 튜닝할 수 있는 프로그램입니다. 전처리된 데이터를 Teachable NLP에 입력함으로써 finetuning된 GPT-2 모델이 생성됩니다. 저는 resume 데이터가 충분하지 않은 점을 감안하여 모델 사이즈를 medium으로, epoch를 3으로 처리하였습니다.
이후 트레이닝이 끝나면 모델이 생성되고, TabTab에서 해당 모델을 테스트하며 자유롭게 resume를 쓰실 수 있습니다.


5개의 후보 문장 중 가장 적절한 어휘와 표현을 고르며 보다 편리하게 résumé를 작성하고, 여러분의 résumé를 포럼에서 마음껏 자랑해주세요:)


Like Comment

워드에서 No-code로 데이터 전처리하기

주로 Preprocessing이라고 하면 복잡한 코드로만 구현 가능할 것 같지만 우리가 평소 자주쓰는 워드로도 가능합니다.


  1. 텍스트 원본을 워드에 복사-붙여넣기
저는 예시로 칸트의 '순수이성비판' 텍스트를 처리해보고자 합니다. 이 때 드래그 필요 없이 ctrl+A로 텍스트파일을 전체 선택한 후 복사(ctrl+C)하여 워드로 붙여넣기(ctrl+V) 합니다.
2. 불필요한 구간 삭제
원서 중에서 불필요한 출판 관련 텍스트, 목차 등의 내용 제거를 위해 대략적으로 첫 번째 PREFACE 이전과, End 이후 구간을 수동적으로 드래그하여 제거하였습니다. 불필요한 구간을 나누는 기준은 텍스트마다 다르므로 텍스트를 skimming한 후 자체 판단하였습니다.

PREFACE TO THE SECOND EDITION 1787 Whether the treatment of that portion of our knowledge which lies within the province of pure reason advances with that undeviating

End of the Project Gutenberg EBook of The Critique of Pure Reason, by Immanuel Kant *** END OF THIS PROJECT GUTENBERG EBOOK THE CRITIQUE OF PURE REASON *** ***** This file should be named 4280-0.txt or 4280-0.zip ***** This and all associated files of various formats will be found in: https://www.gutenberg.org/4/2/8/4280/

3. 문자 바꾸기
워드에 내장된 바꾸기 기능을 통해서 불필요한 문자들을 삭제하였습니다.
워드 우상단에 위치한 돋보기 버튼을 누른 후 [바꾸기...]를 선택합니다.


그리고 [고급찾기 및 바꾸기]를 통해 문자를 바꿀 수 있습니다.

아래와 같은 창이 뜬 후, [바꾸기]탭을 통해 문자들을 바꿀 수 있고, 아래의 화살표를 통해 와일드 카드와 같은 세부적인 조건까지 덧붙일 수 있습니다.

문자 삭제를 하기 위해서는 삭제하고 싶은 내용을 찾을 내용에, 그리고 바꿀 내용빈 칸으로 두고 모두 바꾸기를 실행하시면 됩니다.


---------------------------------------------------------------------------------

아래의 내용들을 고려한다면 더욱 섬세한 전처리가 가능합니다.

A. Wild Card
💡와일드카드란? 문자를 텍스트를 검색하거나 비교 조건으로 사용할 때 정확히 일치하는 값이 아닌 유사값을 찾을 때 사용한다.

만약 로마자로 시작하는 헤딩이 모두 한 줄로 되어있었다면 VIII. *라는 와일드카드를 사용하여 충분히 헤딩을 깔끔하게 제거할 수 있었지만, 일부 헤딩인 두줄로 되어있기에 헤딩의 두 번째 줄은 처리가 어려웠습니다. 저는 이 점을 감안하여 헤딩 중에서 기호 부분만을 제거하였습니다. 일부 자주 쓰이는 와일드 카드만 아래 표에 서술하였습니다. 더 자세한 사항은 여기를 참고해주세요.

B. Escape Character
예를 들어 만약 괄호를 지우기 위해 찾을 문자에 단순히 "(" 혹은 ")"를 입력하면
[찾을 내용]에서 지정한 패턴 일치 조건이 잘못되었습니다.
라는 경고문과 함께 인식되지 않습니다.
이러한 경우 앞에 \(backslash)를 붙여 단순한 괄호를 찾을 수 있습니다.

C. Criteria
예를 들어, I. TRANSCENDENTAL DOCTRINE OF ELEMENTS. 라는 헤딩을 제거할 때
로마자(I. II. ...)로 시작함과 동시에 문자열이 모두 대문자로 이루어졌다 → 헤딩이다
이라는 가정을 세움으로써 전처리를 효과적으로 하실 수 있습니다.

D. Order ✨✨
제거하고 싶은 문자들에 패턴이 있을 시에 순서를 고려해야합니다. 특히 헤딩과 같은 정형화된 내용일수록 주의를 기울여야합니다. 그렇지 않으면 깔끔히 제거하기 어려워집니다.
우선 대략적인 제거 대상이 되는 헤딩들은 다음과 같습니다.

I. TRANSCENDENTAL DOCTRINE OF ELEMENTS.
II. In confirmation of this theory of the ideality of FIRST PART. TRANSCENDENTAL ÆSTHETIC.
SECTION II. Of Time.
§ I. Introductory.
1. Time is not an...
2. Time is a necessary representation...
(a) Time is not something which subsists...
(b) Time is nothing else than the form...

예를 들어 로마자를 제거하고자 할 때, 단순히 I. II. ..순서대로 제거하면 다음과 같은 문제가 발생합니다.
I. 를 제거하면 전체 글에 적용이 되므로 II. 의 경우 I. 사라지고 I 만 남습니다.
② 남은 I 를 제거하기 위해 I하면 단순한 주격 대명사인 I도(e.g. I thought) 제거됩니다.

이러한 상황을 방지하기 위해서
[I가 마지막에 오는 경우] VIII. → VII. → VI. → III. → II. → I.
[V가 마지막에 오는 경우] IIIV. → IIV. → IV. → V.
순으로 삭제하면 됩니다.

E. Remove Symbols
개행문자(엔터), 탭을 비롯한 특수문자는 모델에서 문장을 생성하는 데 방해가 되는 주요 요인 중 하나입니다. 이러한 특수문자 또한 바꾸기 기능으로 처리가 가능합니다.
예를 들어 개행문자를 제거할 경우에는 찾을 문자^p 를 입력하면 됩니다. 이외에도 다양한 특수문자를 [바꾸기] 기능을 통해 검색하거나 바꾸기에 활용할 수 있습니다.
이를 위해 모든 경우의 수를 외울 필요는 없습니다. 하단의 [기타] 콤보 상자에서 찾고 싶은 기호를 선택하면 자동으로 찾을 내용에 해당 특수 문자에 해당되는 값이 입력되니까요!



Wrap up

일부 한계가 존재할 수 있으나 코드 없이 무척 섬세하게 처리가 되었습니다. 코드를 작성하는 것이 부담스러운 분들께 유용한 방법인 것 같습니다. 이렇게 간단히 텍스트를 처리한 후, 텍스트 파일 형식(.txt)로 만들어 Teachable-NLP 의 Data 부분에 입력한다면 여러분만의 모델을 간단하게 만들 수 있습니다.


















Like Comment

'오만과 편견'을 다시 쓰다.

[스포주의]
가장 오랫동안 사랑받는 연애소설인 '오만과 편견(Pride & Prejudice)'은 18~19세기 영국을 바탕으로 펼쳐지는 로맨스 소설입니다. 여주인공인 Elizabeth는 Darcy와의 첫 만남에서 그가 오만하다고 느꼈고, 점차 편견이 굳어져 엇갈리게 된다. 그러나 무수한 사건들을 거치며 Darcy는 그의 오만을 내려놓고, Elizabeth는 오해를 풀며 마침내 두 사람은 사랑에 빠집니다.
만약 사건의 결과가 달라진다면 그 두 사람의 사랑은 이루어졌을까요?

If

  • 만약 두 사람이 첫 만남에 오해하지 않았더라면
  • Darcy를 험담하는 Wickham을 믿지 않았다면
  • Darcy가 Elizabeth에게 편지를 보내지 않았더라면
  • Wickham과 Elizabeth의 여동생 Lydia가 야반도주를 하지 않았다면
  • ...
이를 알아보기 위해 Teachable-NLP로 GPT-2에 오만과 편견을 학습하여 Model을 Finetuning하였습니다. 그리고 Finetuned Model과 연동된 TabTab의 자동완성 기능을 이용해 모델을 바로 써볼 수 있습니다. 여기서 마음껏 각색해보세요!
A. Acquiring the Data
'오만과 편견'의 원문은  Project Gutenburg 에서 무료로 구하였습니다. 그리고 고전 소설로 이미 저작권이 만료되어 데이터 학습 및 각색에 문제가 없음을 확인하였습니다.

B. Preprocessing the data
데이터 전처리 과정에서 1) 각 챕터의 헤딩과 2) 개행 문자를 제거하였습니다.
대신 소설임을 감안하여 쌍따옴표("")는 그대로 남겨두었습니다.
file_name = "Pride and Prejudice.txt"
f = open(file_name,"rt",encoding='utf-8')
file = f.readlines()
f.close()
sentences = []
start = 0
for line in file:
		# 1,2,3권 시작할 때 시작하는 문구로 데이터 유효성 판별
    if line == ("PRIDE & PREJUDICE.\\n"):
        start = 1
        continue
    elif start == 0:
        continue
		# CHAPTER 헤딩 제외
    elif line.startswith("CHAPTER"):
        continue
		# 개행 문자 제거
    elif line == "\\n":
        continue
		# CHAPTER 종료 알림
    elif line.startswith("END OF"):
        start = 0
        continue
		# 1,2,3권으로 시작될 때 
    elif line == "CHAPTER I.":
        start = 1
        continue
		# 데이터의 마지막 알림
    elif line == "       *       *       *       *       *":
        break
    line = line.replace("_", "")
    line = line.replace("--", " ")
		# 불필요한 공백 제거
    line = line.strip()
		# 개행문자 제거 후 단어 구분 
    line = line + " "
    sentences.append(line)
training_data = ''.join(sentences)
training_file = open('preprocess_pp.txt',"w")
training_file.write(training_data)
training_file.close()

C. Teachable NLP
Teachable-NLP에서 전처리 과정을 마친 데이터를 넣고 Model size는 Small 로, epoch는 5로 설정한 뒤 GPT-2 모델을 Finetuning 하였습니다. 트레이닝 과정이 종료되면, Test your model 을 클릭합니다. 클릭하면 열리는 TabTab 화면 에서 '오만과 편견'을 각색해보실 수 있습니다.

저는 Elizabeth는 Darcy와 춤춘 후 바로 사랑에 빠진 스토리로 전개해보았습니다.


과연 그 로맨스는 성공할 수 있을지, 오만과 편견을 마음껏 각색해주세요!
Like Comment

칸트가 철학 레포트 여러분 대신 써드립니다.

Teachable-NLP는 코드를 따로 작성할 필요없이 하나의 텍스트 파일만으로 GPT-2을 튜닝할 수 있는 프로그램입니다.
이를 활용하여 철학과 학부 시절 자주하던 상상을 실현하고자 칸트의 '순수이성비판'을 활용하여 칸트식의 문장을 생성할 수 있는 모델을 생성하기를 마음 먹었습니다. 단순히 문장을 생성하는 것보다는 스토리라인을 덧붙여 마치 칸트가 대필작가(Ghostwriter)가 되어 학생들 대신 글을 써주는 방식으로 프로그램, Ghostwriter Kant를 구상하였습니다.


  1. Acquiring the data
칸트의 가장 대표적인 저서 중 '순수이성비판(The Critique of Pure Reason) 은 Project Gutenberg에서 무료로 txt 형식으로 구할 수 있었습니다. 원문은 독일어로 작성되었으나, 원활한 학습과 생성된 글의 활용성을 고려하여 영어 번역본을 데이터로 선정하였습니다. 그리고 이는 고전 도서로, Public Domain License 상태였습니다. 이로써 학습에 활용하여도 저작권적인 문제가 발생하지 않음을 확인하였습니다.


2. Preprocessing the data
[혹시 No-code로 데이터를 전처리하기는
여기에 안내되어있습니다.]
해당 데이터를 바로 사용하기에는 아래와 같은 불필요한 헤딩과 도식들이 섞여 있었습니다.
SECOND, INTRODUCTION, I.과 같은 헤딩들은 글의 구조를 명료하게 하나, 칸트의 내용과 무관하였습니다. 이는 문장 생성 시 문맥을 해치기 때문에 헤딩을 제거하였습니다.
SECOND DIVISION—TRANSCENDENTAL LOGIC

TRANSCENDENTAL DIALECTIC.
INTRODUCTION.

I. Of Transcendental Illusory Appearance

We termed dialectic in general a logic of appearance. This does not
signify a doctrine of probability; for probability is truth, only
cognized upon insufficient grounds, and though the information it gives
us is imperfect, it is not therefore deceitful. Hence it must not be
separated

또한 칸트의 인식론을 설명하는 도식은 불규칙한 공백과 함께 단순한 낱말의 열거로 인식되기 때문에 학습에 지장을 줄 것이라 예상하였습니다. 이러한 불필요한 도식들을 제거하기 위해서 공백으로 시작하는 문장을 모두 제거하기로 결정하였습니다. 텍스트 파일에서 유효한 문장은 공백이 아닌 문자로 시작함을 확인하였기에 가능한 처리였습니다.
											NOTHING
                        AS

                        1
                Empty Conception
                 without object,
                  _ens rationis_
           2                               3
     Empty object of               Empty intuition
      a conception,                without object,
     _nihil privativum              ens imaginarium_
                        4
                   Empty object
                 without conception,
                  _nihil negativum_

간단한 텍스트 처리였기에 Python 코드로 전처리 작업하였습니다.
PREFACE 이전의 텍스트 전반부는 출판 관련 내용과 차례에 해당하여 처리하지 않고, 텍스트 파일을 줄마다 확인한 후(readlines) PREFACE부터 필요한 부분만 추출하였습니다. 특히 문장의 도입부를 천천히 살피며 어떠한 패턴으로 헤딩과 공백이 있는지부터 살폈습니다.

그 결과, Section, Chaper, Introduction 혹은 주로 대문자로 이루어진 단어, 논리학 용어, 로마자 등이 처리되어야 했습니다. 만약 괄호와 같은 부가적인 내용을 제외하고 활용할 수 있는 문장들은 substring을 통해 최대한 문장 자원을 버리지 않고, 문맥을 유지하려 노력하였습니다.
file_name = "The Critique of Pure Reason.txt"
f = open(file_name, "rt", encoding='utf-8')
file = f.readlines()
f.close()
sentences = []
start = 0
for line in file: 
  if line.startswith('PREFACE'): 
	# PREFACE부터 데이터 가능성을 고려하였습니다.
	# 변수 start는 이를 위한 flag 역할을 수행하였습니다. 
    start = 1
    continue
  elif start != 1:
    continue
  elif line.startswith('End'):
	# PREFACE와 반대로 END로 문장이 시작할 시에 뒤의 부수적인 문장은 고려하지 않기 위해
	# break를 통해 for loop를 나옵니다.
    break
  elif line.startswith(' '):
	# 앞서 말씀드린 도식 외에도 주석 또한 공백으로 시작되어, 이 경우 모두 제거하였습니다.
    continue
	# 헤딩 제거
  elif line.startswith('Section'):
    continue
  elif line.startswith('Chapter'):
    continue
  elif line.startswith('Introduction'):
    continue
  elif line.startswith('FIRST') or line.startswith('SECOND') or line.startswith(
      'THIRD'):
    continue
  elif line.startswith('PROOF') or line.startswith('ANTITHESIS'):
    continue
  elif line.startswith('OBSERVATION'):
    continue
  elif line.startswith('ON THE THESIS'):
    continue
  elif line.startswith('I.') or line.startswith('II.') 
		or line.startswith('III.') or line.startswith('IV.') 
		or line.startswith('V.') or line.startswith('VI.'):
		# 제목에서 기호만 제외한 후 유효한 제목만 남겼습니다.
    line = line[line.find('.') + 2:]
  elif line.startswith('-'):
    continue
  elif line.startswith('§'):
    continue
	# 개행 문자 제거
  elif line == "\\n":
    continue
  elif line.startswith('('):
    line = line[4:]
  sentences.append(line)

그 결과 간결한 문장들로 이루어진 1.2MB의 데이터로 정리되었습니다. 일부 독일어로 된 고유명사와 콜론(:)과 같은 문장들도 있었지만, 이러한 문들을 제거할 시에 문맥이 지나치게 흐려져, 얼마 안되는 소수의 문장임을 감안하고 데이터로 활용하였습니다.
다음은 전처리가 이루어진 데이터의 도입부분입니다.
Human reason, in one sphere of its cognition, is called upon to
consider questions, which it cannot decline, as they are presented by
its own nature, but which it cannot answer, as they transcend every
faculty of the mind.
It falls into this difficulty without any fault of its own. It begins
with principles, which cannot be dispensed with in the field of
experience, and the truth and sufficiency of which are, at the same
time, insured by experience. With these principles it rises, in
obedience to the laws of its own nature, ...

3. Training with Teachable-NLP
Teachable-NLP에 위 데이터를 업로드하여 튜닝하였습니다. 이미 이전에 개인적으로 Finetuning할 시에 모델이 커질수록 글이 생성되는 데 시간이 오래 소요되는 점을 알고 있었기에, 빠른 글 생성을 위해 GPT-2 Small 모델을 활용하였습니다.
대신 정확도가 높기를 희망하여 epoch를 5로 설정하고 학습을 진행하였습니다.

4. Generate Text from Ghostwriter
만약 prefix가 'The demon'으로 주어졌다면, 아래와 같이 'The demon'으로 시작하는 문장들이 출력됩니다. 사용자가 생성되는 글의 Length를 자율적으로 선택하는 방향도 고려하였지만, 안정적인 서버와 로딩 속도를 고려하여 Length는 고정하였습니다.


5. Re-preprocessing
2번에서 전처리를 하였음에도 불구하고 미처 발견하지 못한 인덱스(ex.1. , Remark, -)와 일부 특수문자들이 나타났습니다.
**Remark II.** Now with this view all empirical use of our faculty of
cognition in the determination of time is in perfect accordance.

**—**Ovid, Metamorphoses. **xiii**

The one relates to the objects of the pure understanding, and is
intended to demonstrate and to render comprehensible the objective
validity of its **_à priori_ conceptions**;

**1.** Mathematical judgements are always synthetical. Hitherto this fact,
though incontestably true and very important in its consequences,

세부적으로 다시 전처리를 거쳐 해당 문자들을 제거하였습니다.
추가된 코드는 다음과 같습니다.
# 이전에 놓친 인덱스
elif line.startswith('Introductory'):
    continue
elif line.startswith('The remark:'):
    continue
elif line.startswith('Remark'):
		continue
# 주석을 위한 대괄호 내용 삭제
if line.find('[') > -1:
      if line.find(']') > -1:
        left = line.find('[')
        right = line.find(']')
        new = line[:left-1] + line[right+1:]
        line = new
.
.
.
# 문장 중간에 등장하는 인덱스와 기호 삭제
line = line.replace('§','')
line = line.replace('_', '')
line = line.replace(';', '. ')
line = line.replace('(a)', '')
line = line.replace('(b)', '')
line = line.replace('(c)', '')
line = line.replace('(1)', '')
line = line.replace('(2)', '')
line = line.replace('(3)', '')
line = line.replace('(4)', '')
line = line.replace('1.', '')
line = line.replace('2.', '')
line = line.replace('3.', '')
line = line.replace('4.', '')
line = line.replace('5.', '')

최종적인 전처리 코드와 데이터는 아래에 첨부하였습니다.

preprocess_kant.py
2.23 KB

preprocess2.txt
1.15 MB

Q. 전처리 과정 중 맞닥뜨리는 문제
  • 소괄호 처리: 일상적인 대화를 위한 챗봇에서는 괄호를 전처리해야하나, 칸트에 관한 에세이를 작성하는 것이므로 괄호가 큰 문제가 되지 않을 것으로 판단하였습니다. 그래서 문맥을 살리고자 소괄호는 별도 처리하지 않았습니다.
  • 문자를 코드로 처리하였음에도 여전히 남아있는 경우: 눈으로 보기에 동일한 문자로 보이나 코드 상으로 다른 문자인 경우가 있습니다. 이런 경우 함수 내에 문자를 키보드 입력하기보다는 복사-붙여넣기 형식으로 적용해보면 해결됩니다.

5. More Efficient
위와 같은 전처리를 거치며 보다 효율적이고, 정확한 문장을 생성하는 모델로 튜닝할 수 있었습니다. 주어진 키워드를 중심으로 '순수이성비판'을 바탕으로 한 글이 생성되어 칸트에 관한 에세이를 써야한다는 부담감을 덜 수 있습니다.

6. Finally
이러한 과정을 거쳐 마침내 Ghostwriter Kant는 여기에서 만나보실 수 있습니다.대신 이 프로그램에서는 length = 200으로 고정되고, 글이 한 번에 출력되어 글의 방향을 입맛대로 설정할 수 없다는 단점이 있습니다.
만약 글의 방향을 세심하게 다듬고 싶으시다면, 튜닝한 모델과 자동으로 연동된 TabTab에서 글을 작성해 보세요! TabTab에서는 짧은 문장마다 출력할 수 있으며, 5개의 후보 문장 중에 원하는 문장을 선택할 수 있으므로 글의 방향을 설정하실 수 있습니다.

7. Wrap up
이제 더 이상 머리를 쥐어짜며 칸트 에세이를 쓰실 필요가 없습니다! 칸트가 여러분 대신 기꺼이 글을 작성해줄 거니까요. 혹여 그가 오랜 기간 무덤에서 지내면서 그의 이론을 잊었을 거라는 우려는 하실 필요 없습니다. 그는 '순수이성비판'을 철저히 복습했으니까요.
여러분도 Teachable NLP로 어려운 과목에 대한 레포트를 대신 작성해주는 모델을 쉽게 만들어, API로 글을 생성하실 수 있습니다.
Like Comment