반응형

 

Tokenization이란? 토큰화? 토크나이제이션이란?

 

Tokenization텍스트를 토큰이라고 불리우는 작은 단위로 분리하는 것을 말합니다.

 

자연어처리 영역에서 토크나이제이션이란 위과 같이 정의할 수 있습니다. 여기에서 텍스트(text)는 문서나 문장 등을 말합니다. 즉, 인터넷 뉴스 기사, 블로그 글, 또는 이메일이나 간단한 채팅 내용 등도 모두 텍스트 데이터 입니다. 텍스트에서 데이터 분석이나 모델 개발 등 특정 목적을 위해 수집된 텍스트 데이터를 코퍼스(Corpus)라고 말합니다. 말뭉치라고 하기도 합니다. 이러한 코퍼스를 데이터 전처리를 통해 Features를 만들게 됩니다. 그 첫 번째 작업이 말뭉치를 토큰이라고 불리우는 더 작은 단위로 나누는 토큰화입니다. 자연어 처리 과정중에서 토큰화의 위치를 설명하는 아래 그림에서 쉽게 이해하실 수 있으실 껍니다.  

자연어 처리 과정 중 토큰화(Tokenization)의 위치

즉, 텍스트를 잘게 나누는 것을 토큰화라고 할 수 있습니다. 이렇게 잘게 나누는 방법은(토큰은) 보통 3가지가 있습니다. 단어, 서브단어, 문자 입니다. 문장도 가끔 포함됩니다. 코퍼스를 텍스트의 일부라고 했으니 일반적인 경우는 여러 문장이 들어있는 문단 또는 문서가 코퍼스 입니다. 그래서 문단이나 문서는 문장으로 나눌 수 있고, 문장은 다시 단어로 나눌 수 있고, 단어는 문자로 나눌 수 있습니다. 필요에 따라서 이렇게 세분화 하는 것이 토큰화(토크나이제이션, Tokenization)입니다.  토큰화는 데이터 전처리의 한 단계입니다. 토큰화, 정제, 정규화, 불용어 처리, 인코딩 등 여러 단계를 거쳐 실제 모델의 입력 데이터로 사용되는 피처(Features)가 만들어지게 됩니다. 

 

왜 토큰화가 필요한가?

토큰화를 하는 이유는 자연어 처리에서 가장 일반적으로 전처리하는 방법중 하나이기 때문입니다. 가장 일반적인라는 말은 다시 말하면 많은 모델에서 이처럼 토큰화된 데이터를 필요로 한다는 의미 입니다. 실제로 자연어 처리 모델로 많이 사용되는 RNN, GRU, LSTM 등과 같은 신경망 모델들이 토큰화된 데이터를 이용해서 학습합니다.  

또다른 이유는 바로 단어 사전을 만들기 위해서 입니다. 코퍼스에서 나오는 데이터를 중복없이 만들어서 모델에서 활용할 일이 많은데 이럴때 바로 토큰화라는 작업을 거쳐서 나온 토큰을 가지고 사전을 만듭니다. 예를 들어 단어로 토큰화를 한다면 단어수가 토큰 수가 되겠네요. 이렇게 만든 사전을 통해 기본적인 토큰의 출현 횟수 라든가, 또는 이런 횟수를 이용한 다양한 분석 방법을 이용할 수 있겠습니다. Word Count(BoW: Bag of Words)TF-IDF 등이 그 예가 되겠습니다.

 

 

어떤 토큰화를 해야할까요? 

단어 토큰화(Word Tokenization)

가장 일반적인 토큰화 방법은 단어 토큰화 입니다. 특정 구분기호를 가지고 텍스트를 나누는 방법이지요. 영어의 경우 기본적으로는 공백을 구분자로 사용할 수 있습니다. 이러한 방법으로 토큰화하여 사용하는 모델중에 유명한 것이 Word2Vec 과 GloVe입니다. 한글의 경우 교착어라는 특징이 있어서 영어와 달리 구분자나 공백으로 단어 토큰화를 하면 성능이 좋지 않아서 잘 사용하지 않습니다. 한국어는 영어와 달리 조사가 큰 의미를 가지고 있습니다. 조사에 따라 문장내에서의 역할과 기능이 달라지기 때문에 매우 중요한 정보인데 (공백으로 나눈) 어절에서는 조사 정보를 정확히 사용하기 어렵습니다. 

단어 토큰화에는 몇가지 안좋은 점이 있습니다. 먼저 OOV 문제가 있습니다. OOV란 Out Of Vocabulary의 약자 입니다. 즉, 입력된 데이터가 이미 만들어져 있던 단어사전에 없는 경우 입니다. 단어 사전은 (토큰의 리스트는) 코퍼스 데이터에서 만들어 지기 때문에 모든 단어를 가지고 있지 않습니다. 그래서 훈련때 없던 단어가 모델 예측 시 입력으로 들어올 수 있습니다. 입력을 받아서 해당 단어/토큰을 찾아서 처리해야하는데 없는거죠. 이 문제의 간단한 해결책은 UNK(Unknown Tocken)을 만드는 것입니다. 훈련 데이터에서 많이 출현하지 않는 단어/토큰을 UNK로 사전에 등록하는 것이지요. OOV문제는 해결할 수 있지만 모든 OOV단어가 같은 (UNK)가 의미하는 표현 값을 갖게 된다는 문제점이 있습니다. 즉, OOV 단어가 많으면 모델이 잘 동작하지 않을 수도 있겠네요. 또 다른 단어 토큰화의 문제는 단어 사전이 클 수 있다는 점 입니다. 사전에 포함된 단어가 많을 수록 사전에서 단어를 찾고 표현을 찾는데 시간이 많이 걸리게 됩니다. 모델의 응답시간에 문제가 생길 수 있다는 의미이고 필요한 경우 고용량의 메모리가 있는 서버 컴퓨팅 자원이 필요하다는 의미 입니다. 이러한 OOV 문제를 해결하는 방법중 하나가 문자 토큰화 입니다.

 

문자 토큰화(Character Tokenization)

문자 토큰화는 코퍼스를 문자로 분리하는 것입니다. 영어 같은 경우는 알파벳 26개 로 하나씩 분리하는 것이고, 한글의 경우 자음과 모음으로 분리하는 것입니다. 예를 들면 영어의 경우 'Tokenization' 을 T-o-k-e-n-i-z-a-t-i-o-n 으로 분리하는 것 입니다. 한글의 경우에는 "토큰화"를 ㅌ-ㅗ-ㅋ-ㅡ-ㄴ-ㅎ-ㅗ-ㅏ 로 분리하는 것 입니다.  이렇게 하면 단어 토큰화에서 있었던 OOV 문제가 해결됩니다. 모든 텍스트를 분리하면 결국 하나하나의 문자로 분리되기 때문에 모든 문자(영어 26개, 한글 자음/모음)를 사전에 등록해 놓으면 OOV 문제는 해결 됩니다. 그리고 메모리 문제도 해결됩니다. 왜냐하면, 영어 26개 알파벳이나 한글 자음/모음과 각가의 표현에 필요한 정보만 메모리에 저장하면 되기 때문에 메모리 문제도 없어집니다.  그런데 문자 토큰화에도 단점이 있으니, 바로 한 건의 입력 내용이 길어진다는 것입니다. 바로 위의 예에서도 볼 수 있듯이 "토큰화"를 ㅌ-ㅗ-ㅋ-ㅡ-ㄴ-ㅎ-ㅗ-ㅏ로 입력해야 합니다. 하나의 단어 인데도 이렇게 표현이 길지는데 문장이면 더 길어지겠지요. 이렇게 됨으로써 결국 단어와 단어 사이의 거리가 더 멀어지게 됩니다. RNN, LSTM 등 신경망 모델은 하나의 문장/텍스트에 해당하는 토큰 리스트를 순차적으로 입력 받습니다. 그런데 하나의 입력 길이가 길어지면 모델이 단어간의 관계를 학습하는 것을 어렵게 만듭니다. 이러한 문제점은 새로운 토큰화 방법이 필요함을 알 수 있습니다.

 

서브 단어 토큰화(Subword Tokenization)

서브 단어 토큰화는 문자 토큰화의 확장 버전 입니다. n개의 문자(n-gram characters)를 가지고 나누는 방법입니다. 서브 워드를 만드는 알고리즘 중에서 가장 유명한 것이 BPE(Byte Pair Encoding)입니다. 앞서 이야기한 단어 토큰화는 영어에는 잘 동작하는 편이지만 한국어에서는 잘 안된다고 말씀드렸는데요. 한국어는 형태소 분절 기반의 서브 단어 토큰화가 좋은 성능을 보여서 많이 사용됩니다. 문장을 형태소로 나누어서 각 형태소 별로 인코딩을 하는 방법입니다. 

 

 

파이썬을 이용한 한글 토큰화

한글 텍스트 "나는 자연어처리와 파이썬을  정말 정말 좋아합니다." 라는 문장을 형태소 분석을 통해 토큰화를 해보겠습니다. 꼬꼬마 분석기를 이용했으며 코드와 설명은 아래와 같습니다.

# 필요한 페키지를 가져옵니다.
from konlpy.tag import Kkma
# 프로그램에서 사용하기 위한 인스턴스를 만듭니다.
kkma = Kkma()
# 텍스트 데이터를 설정 합니다.
sentence = "나는 자연어처리와 파이썬을 정말 정말 좋아합니다."
# 형태소분석 POS(Part Of Speech)를 실행합니다.
results_of_pos = kkma.pos(sentence)
# 결과를 출력해 봅니다.
print(results_of_pos)

출력 결과

[('나', 'NP'), ('는', 'JX'), ('자연어', 'NNG'), ('처리', 'NNG'), ('와', 'JKM'), ('파이', 'NNG'), ('썰', 'VV'), ('ㄴ', 'ETD'), ('을', 'NNG'), ('정말', 'MAG'), ('정말', 'MAG'), ('좋아하', 'VV'), ('ㅂ니다', 'EFN'), ('.', 'SF')]

리스트 안에 튜플의 형태로 정리되어 결과가 나옵니다. 튜플의 첫번째 내용은 텍스트 내용이고 두번째 내용은 품사의 종류입니다. 예를 들면 ('나', 'NP')는 문장내 '나'를 분리해 냈으며 품사는 'NP' 대명사로 판단했습니다.  꼬꼬마 형태소 분석기에 대한 품사 태그표는 여기를 참고해 주세요.

 

 

요약

이번에는 먼저 토큰화의 정의를 살펴보았습니다. 토큰화란 텍스트/코퍼스를 작은 단위의 토큰으로 나누는 방법이라고 정의 했습니다. 토큰화 방법에는 단어, 문자, 서브단어가 있고 각각의 장점/단점을 알아보았습니다. 마지막으로는 파이썬 언어를 이용하여 한글을 토큰화하는 사례를 살펴보았습니다. 토큰화를 거처 생성된 토큰 들은 정재, 정규화, 불용어 처리, 인코딩 등의 피처 엔지니어링(Feature Engineering) 단계를 거쳐서 모델의 인풋으로 사용될 피처(Features)로 만들어 집니다. 이러한 단계를 거쳐서 워드 클라우드, 자동 번역, 질의 응답(QnA) 등 다양한 자연어 처리 모델과 어플리케이션을 만들 수 있습니다.

 

 

반응형
반응형

내용

  • 정규식, 정규 표현식 이란 무엇일까요? : 정의와 개념을 이해합니다.
  • 패턴 정의 문법 : 정규식을 사용하기 위해 필요한 문법을 배웁니다.
  • 정규식 활용 방법 예시 (in Python 파이썬에서) : 실제 사용하는 예시를 배웁니다.
  • 정규식의 활용 : 어디에 쓰는지 알아봅니다.
  • 배운 내용 확인(연습문제)



정규식, 정규 표현식 이란 무엇일까요?

바로~~~

정규식은 특별한 문자열의 집합(패턴)을 표현하는 언어 입니다.


정규식은 패턴을 표현하기 위한 규칙을 정의 하는 방법으로 (특별한 의미로 인식되는) 메타문자와 (일반 문자) 정규문자를 이용해서 정의 할 수 있습니다.

 

개념

조금 더 확실하게 알아보겠습니다. 사실 개념은 간단합니다. 텍스트(문장, 문단 또는 문서)가 주어 졌을때 특정한 패턴을 찾으려면 찾고자 하는 동일한 문자를 모두 한번에 하나씩 입력하고 조회해서 찾아 볼 수 있습니다. 그러나 조건이 조금 복잡해지면 이렇게 하는 것은 불편하고 복잡할 때가 있습니다. 이럴때 특정한 표현 규칙이나 기호를 활용하여 다양한 규칙을 간단하게 정의할 수 있습니다. 이렇게 정의된 것이 바로 정규식입니다. 표현 규칙은 특별한 문자가 무엇을 의미하는지 정하고, 반복 횟수 표현은 어떻게 할 것인지 등을 정한 것입니다. 즉, 문법이지요. 아래에서 예를 들어보겠습니다.
다음과 같은 텍스트가 있습니다.

target = "나는 정규식을 잘 알고 잘 사용할 수 있습니다. 정규식은 재미있고 유용합니다. 정규식으로 쉽게 코딩 할 수 있습니다."

이것을 대상 텍스트, 즉, target 이라고 하겠습니다. target에서 '정규식'이라는 문자와 아무 문자 하나가 추가된 모든 단어를 찾고 싶습니다. 예를 들면 "정규식이", "정규식은", "정규식도" 등이 되겠네요. 이렇게 해서도 패턴을 정의할 수 있습니다.
이처럼 찾고자하는 것이 패턴인데, 예를들어 정의해보면

' 정규식가 ', ' 정규식기 ', ' 정규식구 ', ' 정규식에 ', ... 등이 가능합니다. (찾기 원하는 내용의 앞/뒤에 공백하나 ' '를 추가했습니다.)

'정규식' 뒤에 무슨 문자가 올지 모르기 때문에 모든 가능한 문자를 적어줘야 합니다. 정확히 일치하는 패턴을 정의하다보니 너무 많아서 무한대는 아니지만 너무 많은 것 같네요. 이렇게 생성 가능한 많은 문자 패턴들을 미리 만들어 놓고 하나하나 비교해가면서 target에 패턴이 있는지 없는지를 확인할 수 있습니다. 그런데 방금 보신것 처럼 '정규식'이라는 단어 뒤에 모든 하나의 문자를 허용하는 패턴을 정의하기 위해서 너무 많은 내용을 일일히 나열해야합니다. 정말 비효율적이고 힘든 일이 지요. 그래서 정규식이 필요합니다. 위에서 찾고자하는 엄청난 길이의 패턴을 정규식으로 표현하면 다음과 같이 매우 간단합니다.

"[\s]+정규식[\w]+[\s]+"

정말 간단해서 보기 좋지 않으신가요? 이해는 안되더라도 동일한 의미라면 정규식으로 표현된 내용이 훨씬 간단하다는 것을 알수 있습니다. '\s' 는 공백 한칸을 나타내는 특별한 문자(메타문자)이고요. '+'는 앞에 정의한 원자(정규문자나 메타문자)가 몇번 출현/반복하는지를 정하는 수량자(quantifier) 중에 하나입니다. 이것이 의미하는 것은 수량자 바로 앞 한 문자(이번 예에서는 \s 또는 \w)가 1회 이상 발생하는 것을 의미합니다. 조금 더 상세한 정의 방법은 뒤에 자세히 설명하겠습니다.

한번 더 예를 들어 보겠습니다. 이번에는 target2가 아래와 같은 텍스트라고 가정하겠습니다.

target2 = '이번 정규식은 쉽다. 정규식1번이 2번보다 좋은가? 정규식이라고 해서 모두 같은게 아닙니다. 이정규식 해석 방법은? 정규식9번을 해석하시오"

자, 이제 '정규식' 뒤에 숫자1부터 9중에 하나가 들어가고 앞에 하나 이상의 공백이 있는 패턴을 찾고 싶다고 생각해보겠습니다. 찾고 싶은 패턴들을 그냥 모두 나열해보면 다음과 같습니다.

패턴 = " 정규식1", " 정규식2", " 정규식3", " 정규식4", " 정규식5", " 정규식6", " 정규식7", " 정규식8", " 정규식9"

이것을 정규식으로 표현해보면

"[\s]+정규식\d"

입니다. 정말 간단하게 표현되는 것을 확인할 수 있습니다. 여기서 '\d'는 숫자 한자리를 의미합니다.

위의 예시가 정확하게 이해되지 않으시더라도 적어도 한가지는 이해하셨을 것 같습니다. 즉, 복잡하고 다양한 패턴을 정의하는데 정규식을 쓰면 쉽게 할 수 있다는 것을 아셨을 것 같습니다. 정규식 문법을 하나씩 배워나가면 이해가 쉬워 지실껍니다. 자 그럼 어떻게 정규식 패턴을 정의할 수 있는지 자세한 문법을 알아보겠습니다.




패턴 정의 문법

정규식은 어째건 간에 텍스트 즉, 문자열(문장 또는 문서)에서 찾고자 하는 문자나 패턴을 정의하는 것입니다. 그래서 결론적으로 정규식도 문자나 문자열입니다. 그래서 쌍따옴표("") 사이에 찾고자하는 문자나 패턴을 정의합니다. 정규식은 정규문자와 메타문자로 구성됩니다. 정규문자는 일반적으로 쓰는 문자를 말합니다. 영어의 알파벳이나 한글의 자음/모음, 또는 숫자 같은 것이 되겠습니다. 메타문자는 특별한 의미를 부여한 문자를 말합니다.

메타 문자(Meta Character)

메타 문자는 특수한 의미를 지니는 문자를 말합니다. 즉, '이 문자는 이런 의미이다'라고 미리 정한 것이지요. 다시 말하면, 정규식을 사용할 때의 문법이라고 할 수 있습니다. 그래서 잘 알아두어야 정규식을 정확하게 쓸수 있습니다. 자, 그럼 정규식에는 어떤 메타문자와 문법이 있는지 알아보겠습니다.

메타 문자 기능 설명/의미 예시 예시설명
[ ] 문자 클래스
(집합)
가능한 문자들의 집합을 의미합니다. []안에 있는 한글자 한글자가 찾고자하는 한글자가 될 수 있는 것 입니다. []안에는 결국 문자 하나의 가능한 조건/집합을 정의하게 됩니다. "[a-m]" a부터 m중에 하나의 문자
\ 백슬래쉬 바로 뒤에 오는 한 문자와 합쳐서 특수기호로 사용됩니다. "\d" 숫자를 나타내는 특수 문자로 숫자 1자리의 모든 수를 의미합니다.
. 문자 새줄 문자(개행문자, \n)를 제외한 모든 하나의 문자. "he..o" he 다음에 새줄 문자(\n)를 제외한 어떤 문자든 2개가 있고 그뒤에 o가 있는 패턴을 의미합니다.
^ 처음 ^ 다음의 내용으로 시작 "^hello" 시작이 hello인 패턴을 의미합니다.
$ $ 전의 내용으로 끝 "planet$" planet 으로 끝나는 패턴을 의미
* 0회 이상 반복
(수량자)
* 직전의 정규문자/메타문자가 0회 이상 반복 "he.*o" .이 0회 이상 반복, 즉 heo, helo, hello, hellllo 모두 패턴 매칭됨
+ 1회 이상 반복
(수량자)
+ 직전의 정규문자/메타문자가 1회 이상 반복 "he.+o" .이 1회 이상 반복, 즉 helo, hello, hellllo 들이 패턴 매칭됨
? 0 또는 1회
(수량자)
? 직전의 정규문자/메타문자가 0 또는 1회 반복 "he.?o" .이 0 또는 1회 발생, 즉 heo, helo 들이 패턴 매칭됨(hello는 안됨)
{n, m} 지정횟수 반복
(수량자)
{} 직전의 문자가 n회 이상 m회 이하 반복 "he.{2}o" .이 2회 발생, 즉 hello 만 패턴 매칭됨(heo, helo, helllo는 안됨)
¦ 선택 ¦ 전에 문자 또는 후에 문자 "true¦false" "true" 또는 "false"의 패턴을 의미
() 그룹 그룹으로 묶기, 여러 식을 하나로 묶을 수 있음 "a(b¦d)c" "abc¦adc"와 같은 의미

수량자와 선택, 그룹을 제외한 메타 문자는 결국 하나의 문자 조건을 나타냅니다.
모든 수량자는 {n, m} 방식으로 바꾸어서 정의할 수도 있습니다.(비추합니다. 왜냐하면 *, +, ?를 사용하는 것이 더 직관적이기 때문입니다.)

특수 기호(Special Character)

하나의 특수 기호를 이용해서 문자, 숫자, 또는 공백을 각각 대신할 수 있습니다. 그리고 문자열의 시작이나 끝, 그리고 단어의 시작이나 끝 등 출현 위치에 대한 규칙을 정할 수 있습니다. (처음 정규식을 접하시는 분은 굵은 글씨로 된 \d, \s, \w만 아셔도 충분합니다.)

특수 기호 의미 예시
\A 명시된 문자로 문장이 시작하는 경우 일치하는 것을 반환 "\AThe"
\b 명시된 문자가 단어의 시작이나 끝에 위치하는 경우 일치하는 것을 반환
(문자열 시작전에 "r"을 추가함으로써 내용이 "raw string"으로 받아 들여지게 합니다.)
r"\bain"
r"ain\b"
\B 명시된 문자가 단어의 끝이나 시작이 아닌 위치에서 발견되는 경우에 반환 r"\Bain"
r"ain\B"
\d 숫자와 매칭되는 문자(숫자)를 반환합니다. (0부터 9까지의 숫자) "\d"
\D 숫자가 아닌 문자 찾기 "\D"
\s 공백 문자와 일치되는 문자 찾기 "\s"
\S 공백 문자가 아닌 문자 찾기 "\S"
\w 모든 문자에 포함되는 문자 찾기(문자는 a 부터 Z까지,한글의 경우 '가'부터 '힣'까지, 숫자는 0부터 9까지, 그리고 underscore _ 기호도 매칭됨) "\w"
\W 문자에 포함되지 않는 문자 찾기(\w가 아닌 문자) "\W"
\Z 문자열의 끝에 정의한 문자가 있는지 문자 찾기 "Spain\Z"

 

집합(Sets)

문자 클래스 안에 들어가는 내용을 Sets이라고 합니다. 각 예시와 설명을 살펴 보시지요.

Set 예시 설명
[arn] a, r, 또는 n과 매칭되는 문자를 찾습니다.
[a-n] a 부터 n 사이의 모든 소문자 알파벳과 매칭되는 문자를 찾습니다.
[^arn] a, r, 또는 n이 아닌 모든 문자와 매칭되는 문자를 찾습니다.
[0123] 0, 1, 2, 또는 3 인 숫자와 매칭되는 숫자를 찾습니다.
[0-9] 0부터 9까지의 모든 숫자와 매칭되는 숫자를 찾습니다.
[0-5][0-9] 0부터 5사이의 모든 숫자로 시작하는 첫번째 자리숫자와 0부터 9사이의 모든 숫자로 시작하는 두번째 자리 숫자를 (2자리 숫자와) 매칭되는 숫자를 찾습니다. 즉, 00 부터 59 사이의 숫자를 찾습니다.
[a-zA-Z] a부터 z까지의 모든 소문자 알파벳 또는 A부터 Z까지의 모든 알파벳과 매칭되는 문자를 찾습니다. 즉, 모든 알파벳을 찾습니다.
[+] 문자 클래스 [] 안에 있는 특수문자는 모두 그냥 그대로 매칭하는 것을 찾습니다. 즉, +, *, ., |, (), $,{} 이러한 기호가 문자클래스 []안에서 사용되면 같은 모양의 기호가 target 문자열에 있는지 없는지를 찾습니다.

마지막에 설명한 것처럼 Sets를 정의할 때 사용되는 특수 기호 들은 앞에서 설명한 매타 문자의 정의와 다른 의미 입니다. 그냥 특수문자 그대로를 패턴으로 찾습니다. 따라서 혼동되지 않게 주의 하셔야 합니다. 특히 세번째에 설명한 '^'의 경우 문자 클래스 안에서는 부정의 의미를 갖지만 밖에서는 문자의 시작을 나타냅니다.

 

 

정규식 활용 방법 예시 (in Python 파이썬에서)

첫번째 예시를 프로그래밍 언어인 파이썬을 이용해서 코딩해본 내용입니다.

1번라인은 python에서 정규식 사용을 쉽게 해주는 re 모듈을 임포트해서 가져옵니다. 3번라인에서 대상이 되는 텍스트를 설정합니다. 5번에서는 re모듈에 compile 함수를 이용해서 정규식을 정의합니다. 7번라인에서는 정의한 정규식을 이용해서 대상 텍스트에서 정규식에 해당하는 패턴을 찾아서 matches라는 변수에 전달해 줍니다. 9번부터 10번라인에서는 매칭된 내용을 출력하는 명령어 내용입니다.
상기 내용을 test.py로 저장하고 실행하면 아래와 같은 결과가 나옵니다.

$ python testtest.py
<_sre.SRE_Match object; span=(2, 8), match=' 정규식을 '>
<_sre.SRE_Match object; span=(26, 32), match=' 정규식은 '>
<_sre.SRE_Match object; span=(43, 50), match=' 정규식으로 '>
$


두번째 예시를 코딩해본 내용입니다.

상기 내용을 test2.py로 저장하고 실행하면 아래와 같은 결과가 나옵니다.

$ python test2.py
<_sre.SRE_Match object; span=(11, 16), match=' 정규식1'>
<_sre.SRE_Match object; span=(64, 69), match=' 정규식9'>
$


보신 것처럼 파이썬의 re 모듈을 이용하여 쉽게 정규식을 사용할 수 있습니다. re는 Regular Expression의 약자이며 파이썬 라이브러리의 이름 입니다. re 모듈에서는 이 밖에도 여러가지 함수를 제공합니다.

 

finditer 함수

위의 예시에서는 매칭되는 내용을 오브젝트로 받을 수 있는 finditer 함수를 이용했습니다. 이렇게 얻은 오브젝트는 여러 정보가 있습니다. 출력한 내용을 보면 매칭되는 오브젝트임을 표시하고(sre.SRE_Match object), span 에서 매칭되는 범위를 표시해 주며(span=(11, 16)), 매칭되는 내용을 보여 줍니다(match=' 정규식1'). 여러개가 매칭되면 여러개의 객체가 반환 됩니다.

 

findall 함수

findall 함수는 패턴이 매칭된 내용을 리스트로 만들어서 반환 합니다. 예를 들어 두번째 예시를 findall 함수로 변경시 반환 값은 리스트(['정규식1', '정규식9'])가 되서 출력되는 내용이 아래와 같이 됩니다.

$ python test2.py
정규식1
정규식9
$

 

sub 함수

sub 함수는 매칭된 내용을 다른 내용으로 대체가 필요할 때 사용하는 함수 입니다. 두 번째 예에서 발견된 내용(정규식1, 정규식9)을 '정규식100'으로 바꾸도록 코드를 수정하고 실행해보겠습니다.

$ python test2.py
이번 정규식은 쉽다.정규식100번이 2번보다 좋은가? 정규식이라고 해서 모두 같은게 아닙니다. 이정규식 해석 방법은?정규식100번을 해석하시오

정규식의 제일 앞에 공백(\s)이 있어서 공백을 포함한 내용(' 정규식1')이 sub 에서 정의한 "정규식100"으로 대체 된 것을 보실 수 있습니다.

search 함수

search 함수는 텍스트 내에 정규식에 해당하는 패턴이 존재하는 경우 첫번째 내용을 오브젝트로 반환 합니다. 그래서 여러가 매칭되더라도 제일 첫번째 내용만 반환합니다. 매칭되는 것이 없을 경우 None을 반환합니다.

$ python test2.py
<_sre.SRE_Match object; span=(11, 16), match=' 정규식1'>
$

 

 

 

 

정규식의 활용

정규식은 어디에 쓸까요? 결국 정규식이 문자열의 패턴을 정의하기 때문에 이러한 정의가 필요한 경우를 생각해면 됩니다. 일반적으로 접하게되는 활용은, Text 내용 중에 특정한 패턴이 있는지를 찾아내는 Text검색에 사용될 수 있습니다. 이메일, 워드 문서, ppt문서, PDF문서 등 많은 문서 형태에서 검색이 필요합니다. 이러한 검색을 위한 패턴 정의 및 실행에 사용할 수 있습니다. 그리고 각종 컴퓨터 프로그램에서도 텍스트 내용에 대한 유효성 체크 또는 검색과 변경 등의 작업을 위해 많이 사용됩니다. 이처럼 활용할 경우가 많으니 개발자인 경우 정확히 알아두면 많은 도움이 될 것입니다. 이처럼 활용처가 많기 때문에 많은 프로그래밍 언어에서 쉽게 코딩 할 수 있도록 정규식 라이브러리를 제공합니다. 파이썬에서는 위에서 보신 re 모듈이 되겠습니다.


배운 내용 확인(연습문제)

배운 내용 확인을 위해 정규식을 하나 만들어 보시지요. 웹 페이지에서 휴대폰 전화번호를 입력받는 기능이 있다고 가정하시죠. 이때 입력받은 내용이 휴대폰 전화번호에 맞는 내용인지 아닌지를 검증하기 위해 정규식을 만들어 보시지요. 즉, 정규식을 만드는 이유는 사용자가 이상한 값이나 문자를 입력하지 않았는지 확인하기 위해서 입니다. 그래서 우리가 만든 정규식을 가지고 일치하는 패턴을 찾게되면 사용자가 정확하게 입력했다고 할 수 있습니다. 휴대폰 전화번호의 구조는 다들 아시겠지만 다음과 같습니다. 숫자 3자리로 시작하고, 그 다음 대시('-')가 나오고, 그다음 숫자 3자리 또는 4자리가 나오고, 그다음 대시('-')가 나오고, 마지막으로 숫자 4자리가 나오는 패턴 입니다. 이 조건을 정규식 문법으로 옮겨보겠습니다.
숫자 3자리로 시작하고, --> \d\d\d 또는 \d{3}
그 다음 대시('-')가 나오고, --> '-'
그 다음 숫자 3자리 또는 4자리가 나오고, --> ([\d]{3}|[\d]{4}]) 또는 \d{3,4}
그 다음 대시('-')가 나오고, --> '-'
마지막으로 숫자 4자리가 --> \d\d\d\d 또는 \d{4}
모두를 합쳐보면 아래와 같습니다.

"^\d{3}-\d{3,4}-\d{4}$"



요약

이상으로 정규식에 대해서 알아보았습니다. 정규식에 대한 정의와 개념, 문법에 대해서 알아보았으며, 파이썬 언어에서 실제로 구현하는 방법에 대해서 알아보았습니다. 정규식의 활용 내용에 대해서도 알아보았고 마지막으로 연습문제까지 풀어보았습니다.


질문 댓글은 언제나 환영이며 구독, 좋아요를 눌러 주시면 다음 글을 더 편하게 보실 수 있습니다.

감사합니다.

w3c schools의 내용을 참고했습니다.

반응형
반응형

Lecture 10 - Decision Trees and Ensemble Methods | Stanford CS229: Machine Learning (Autumn 2018)

 

주요 내용

  • Decision trees 의사결정 나무
  • Ensemble Methods 앙상블 방법
  • Bagging 배깅
  • Random Forests 랜덤 포레스트
  • Boosting 부스팅
 


Decision Trees 의사결정 나무


시간(월)과 위도를 가지고 스키를 타기 좋은지 아닌지를 구분하는 분류기를 만든다고 생각해 봅시다. 데이터를 통해 가능한 지역과 시간에 +를 표시하고 불가능한 지역과 시간에 -를 표시하면 아래와 같습니다.



Greedy top-down recursive partitioning
모든 케이스들을 측정한다는 측면에서 Greedy하다고 할 수 있고, 전체 데이터를 가지고 분류해나가기 때문에 top-down 이라고 말할 수 있습니다. 그리고 데이터를 분류하고 나서 분류된 한 부분을 가지고 다시 분류하기 때문에 recursive 하다고 말할 수 있습니다.
첫번째는 위도가 30도 인지를 가지고 분류할 수 있습니다. 그래서 위도가 30보다 큰 지역과 작은 지역으로 나누어 집니다. 이어서 두번째로는 시간(월)을 가지고 분류할 수 있습니다. 3월보다 작은 달인지 아니닌지로 구분합니다. 이렇게 나누어진 그림이 아래와 같습니다.


이러한 방법으로 계속 분류를 하면 아래와 같이 분류할 수 있습니다.




아래는 p(positive, +) 지역(Region Rp)을 찾는 것을 함수 Sp로 만들었을때의 공식입니다. 입력 변수로 j는 피처를 나타내고 t는 임계값을 의미합니다. Rp는 Region parent 즉, 상위/부모의 지역을 말합니다. 아래 공식을 설명해보면 j 에 해당하는 Xj 값이 임계값 t 보다 작을 때는 첫번째 지역 R1에 할당하고, 크거나 같을 경우 두번째 지역 R2에 할당합니다.


그럼 분류 후 얼마나 틀렸는지를 계산하는 로스는 어떻게 계산할 까요?

그런데 잘못 분류한 로스 계산에 문제가 있습니다. 아래 두 그림에서 처럼 실제로 다르게 분류를 했음에도 불구하고 로스는 오른쪽에 보이듯이 좌우 모두 100 입니다. 심지어 부모 노드의 로스 L(Rp)도 100으로 같습니다.


그래서, 이런 문제를 해결하기 위해 단순 로스가 아닌 크로스 엔트로피 로스(Cross-entropy loss)를 사용하게 됩니다.


크로스 엔트로피 로스는 L(R1)과 L(R2)의 평균에 해당하는 지점에서 곡선과 직각이되는 점-L(Rp)와의 차이(Gain)를 계산하는 것 입니다. 아래에서 Change in loss로 적혀 있는 부분이 Gain입니다. 즉, 부모 노드에서 발생한 로스 보다 자식 노드 2개에서 발생한 로스의 평균이 더 적게 되는 경우 입니다.

이것은 Gini 값이라고 해서 아래와 같이 정의된 값도 많이 쓰입니다.



아래는 잘 못 분류된 경우를 설명하는 그림입니다. 부모 노드의 로스(L(Rp))가 결국 자식 노드 2개의 평균과 같은 것이 되버리기 때문에 자식 도드에서는 의미 없는 분류를 한 것과 같습니다.



Regression Trees
이번에는 Regression Trees에 대해서 알아보도록 하겠습니다. Decision Trees의 예로 사용했던 스키 예를 이용하겠습니다. 다만 적합한지 아닌지 + - 로 구분했던 것을 적설량으로 구분하는 예를 들어보겠습니다. Decision Tree에서와 같이 위도와 시간 월에 따른 위치에 적설량을 숫자로 표시합니다. 그리고 이것을 잘 분류하게 됬을 경우 아래처럼 구분하는 선들이 그려지게 됩니다.


지역 Rm에 해당하는 예측값 y^m을 수식으로 나타내면 아래와 같습니다. 이것은 지역 Rm에 있는 모든 수의 합을 숫자 갯수로 나누어서 계산하는 값으로 결국 지역의 평균 값이 됩니다.


로스는 스퀘어드는 MSE(Mean Squared Error)와 같이 각 예측 값에서 평균값(y^m)을 뺀값의 제곱을 누적하여 전체 갯수로 나누어서 구합니다.


Categorical Vars 를 가지고도 모델을 만들 수 있습니다. 그러나 9개의 카테고리가 있다고 만 가정해도 2^9만큼의 분리가능한 것들이 생겨서 너무 복잡하고 비효율적입니다.

왼쪽에 North, Equator, South로 카테고리를 분류 할 수 있습니다. 이는 특히 이진트리(Binary trees)의 경우도 적용할 수 있습니다. 각 분류의 갯수 별로 소팅한뒤에 숫자에 따라 분류해 나갈 수 잇습니다.



Regularization of Decisioon Trees
트리 모델을 모든 훈련데이터에 훈련 시키면 결국 모든 훈련케이스를 만족시키는 트리를 만들게 되어 결국 최종 결과가 하나씩 연결되는 Overfitting이 발생하게됩니다. 이를 방지하기위해 정규화가 필요한데 여기에 사용되는 다양한 휴리스틱 정규화 방법에 대해서 알아보면 아래와 같습니다. 최소 리프 사이즈를 제한 하거나, 트리의 깊이를 제한 하거나, 노드들의 최대 수를 정해 놓거나, 최소로 줄어드는 로스를 정해 놓거나, 검증 데이터에서 잘못 분류된 가지를 제거하는 등이 있습니다. 특히, min decrease in loss의 경우 부모노드 보다 자식노드가 최소 어느정도는 더 분류를 잘해야 하는 지를 정하는 방법으로, 데이터 피처의 중요도-잘 분류하는 데이터 피처에 따라서 위에서 아래로 정리되게 만드는 방법입니다.


Runtime
n은 예제수, f는 피처수, d를 나무의 깊이라고 하면, 테스트 시간은 O(d)가 되고 이때 깊이 d는 log2n 보다 작습니다. 여기서 log2n이 의미하는 것은 말 그대로 훈련 예제수에 로그를 취한 값 입니다. 다시 말하면 전체 예제수로 훈련해서 만들어진 훈련된 트리를 이용해서 테스트를 하게 되기 때문에 훈련에서 만들어진 트리의 깊이에 따라 속도가 달라지게되고 이 깊이는 훈련을 통해 잘 분리되도록 하는 이진트리(하위노드가 2개인 트리)를 만들었다고 할경우 결국 훈련데이터의 예제수에 로그를 취한 값이 보다 작아지게 됩니다. 리프 노드에 하나의 예제가 달린다고 최학의 경우를 가정한 것이 log2n입니다. 아무튼 너무 당연한 이야기 인데요 트리의 예측 속도는 트리의 깊이 만큼 비교해야하기 때문에 O(d)입니다.


그럼 훈련 시간은 어떻게 될까요? 각 포인트는 O(n) 속도의 노드에 속한 한 부분이고, 각 노드에서 포인트의 비용은 O(f)입니다. 이 말은 피처 f가 위도, 시간-월 이렇게 2개있을 경우 O(2) 만큼의 시간이 걸린다는 말입니다. 깊이 마다, 각 노드에서 피처마다 처리하는 시간이 필요하고 이런 계산을 예제수 만큼해야하니 모두 곱한 O(nfd)가 훈련 시간이 됩니다.



Downsides
이제 의사결정트리의 단점을 알아볼까요? 선형회귀로 간단히 분류가 가능한 +와 - 데이터 들이 있습니다. 그런데 이것을 의사결정나무 Decision Trees로 분류하게 되면 많은 분류 기준이 필요하여 복잡한 트리가 만들어 질 수 있습니다. 속도도 느려지고 잘 분류가 안되는 경우도 생길 수 있습니다.


요약- 장점/단점
의사결정나무의 장점과 단점은 아래와 같습니다. 장점으로는 먼저 설명하기 쉽습니다. 모르는 사람에게도 예를 들면 10개 질문을 통해서 분류한다고 설명할 수 있습니다. 모델을 해석하기 쉽고, 범주형 변수(Categorical Vars)에 유용하며, 속도가 빠릅니다. 단점으로는 분산이 큰 모델로 훈련 데이터에 오버피팅 되기 쉽습니다. 변수 사이에 상호작용이 작은 경우에 분석에 약하고(반대로 상호작용이 큰 경우에는 강합니다), 그리고 예측 정확도가 낮습니다.




Ensemble Methods 앙상블 방법

여기서 독립 가정을 제거하면 전체 모집단의 평균(X-bar)에 대한 분산은 아래와 같이 계산할 수 있습니다. 공식을 풀어서 이해해 보면 p 에 의해 연관된 x 샘플이 많을 수록 분산은 커지고 데이터수(n) 이 클수록 분산이 작아지게 됩니다.


이처럼 정확도를 높이기 위한 방법중 하나가 앙상블 ensemble이며 앙상블에는 다양한 방법이 있습니다.
다른 알고리즘을 쓸수 있고, 다른 훈련 데이터 셋을 사용할 수도 있습니다. 베깅과 부스팅이라는 기법도 있습니다. 베깅의 대표적인 예는 랜덤포레스트이고 부스팅의 대표적인 예는 에이다부스트(Adaboost)와 xGboost 입니다.





Bagging 배깅

베깅에 대해서 알아보면 다음과 같습니다. 배깅은 부트스트랩 에그리게이션(Bootstrap Aggregation)의 축약어 입니다. 실제 모집단 P에서 샘플 S를 뽑아서 훈련 셋을 사용합니다. 이때 우리는 샘플이 모집단과 같다고 가정하고 모델을 만듭니다. 여기에 부트스트랩이라는 기술을 추가하는데 이것은 샘플에서 다시 샘플을 추출하여 Z라는 샘플을 만들고 이것을 훈련에 이용하는 것을 말합니다.

이렇게 생성된 여러 개의 샘플 z를 가지고 모델 G를 여러번 훈련할 수 있고 그 결과를 평균할 수 있습니다. 이 부분이 바로 에그리게이션 Aggregation 파트에 해당하는 내용입니다. 즉, 여러 샘플 데이터 셋을 가지고 훈련한 모델의 여러 결과들을 합치는 부분입니다.

이 기술을 적용하면 바이어스와 베리언스(오차와 분산, Bias-Variance)에 변화를 주게 됩니다. 앞서 분산에 대한 공식을 정리한 것이 있는데 이것을 부스팅에 적용하면 아래와 같습니다. 즉, Var(x-)의 내용중 분모를 M (샘플z 수)로 바꾸어 준것 밖에 없습니다. 부스팅을 적용하면 공식에 있는 p를 줄입니다. 그리고 데이터가 많을 수록 분산을 줄입니다. 반면 오차는 살짝 올라 갈 수 있습니다.

의사결정트리는 높은 분산에 낮은 바이어스를 가지고 있기 때문에 배깅과 매우 잘 맞습니다. 배깅이 분산을 낮추어 주기 때문입니다.




Random Forests 랜덤 포레스트




Boosting 부스팅

 

부스팅은 배깅과 다르게 바이어스를 줄이는 효과가 있습니다. 변수 사이의 상효작용에 강합니다. 이 기술은 반복적인 모델 훈련을 합니다. x1, x2 피처를 가지고 분류 모델을 만든 다고 가정해 보시죠. 아래 왼쪽과 같이 분류모델을 만들어 분류를 할 수 있는데 빨간색 박스 처럼 오분류하는 경우가 발생합니다. 이러한 경우 다음 훈련에서 해당 예제 샘플의 가중치를 높혀서 훈련하면 오른쪽의 그림처럼 큰 +와 -를 만들수 있고 이들을 고려한 분류모델을 만들면 그림과 같이 위/아래로 나누는 분류선(모델)을 만들 수 있습니다. 이런 식으로 반복해 나가면서 모델을 학습하는 방법이 부스팅 입니다.

 
에이다부스트 Adaboost 는 아래와 같은 공식으로 표현될 수 있는데 위에서 말한 것과 같이 이전 훈련에서의 결과를 이용해서 재 설정된 가중치 값을 이용해서 훈련합니다.





아래는 강의 링크 입니다.
https://www.youtube.com/watch?v=wr9gUr-eWdA&list=PLoROMvodv4rMiGQp3WXShtMGgzqpfVfbU&index=10

 
반응형
반응형

이전 포스팅에서 파이썬 직원은 주방장이라고 말했습니다. 여러가지 재료로 다양하고 맛있는 음식과 요리를 만드는 파이썬 주방장님에 대해서 좀더 자세히 살펴 보겠습니다.

Python (파이썬) : 주방장

  • 정의
  • 프로그램 설치
  • 기본 구조 및 문법
  • 샘플 코딩 해보기
  • 요약

 

정의

지난 포스팅의 식당 예시에서 파이썬을 정의한 내용은 아래와 같습니다.

  • 파이썬은 주방장입니다. 파이썬은 네덜란드 출신입니다. 이 주방장은 항상 오픈된 주방에서만 일을 하기 때문에 주방장이 요리하는 순서나 내용을 다른 사람들이 쉽게 알 수 있습니다.
  • 이 주방장은 어느 오픈 주방에서든지 요리를 잘합니다. 가끔 미리 준비된 재료(데이터)를 사용해서 주문이 들어오면 그때 그때 조리를 하기도 합니다.
  • 또 급할때는 밀키트 처럼 미리 만들어 놓은 재료(오브젝트)를 기반으로 추가/변경하여 요리하기도 합니다.
  • 이 주방장은 요리 중간에 들어간 재료를 확인하지 않아서 가끔 주요 재료가 빠진 식사가 잘 못나올 수 있기 때문에 조리 전에 주문에 맞게 재료가 맞게 들어가 있는지 확인해 줘야 합니다.


이것을 웹 어플리케이션 관점에서 다시 자세히 설명 드리겠습니다.

  • 파이썬은 서버 프로그래밍에 사용되는 프로그램입니다. 물론 (자바 스크립트 처럼)클라이언트 프로그램도 가능합니다. 작성한 프로그램 내용을 사람이 이해하기 쉽습니다. 파이썬은 고수준 언어이니까요.
  • 파이썬은 플랫폼에 독립적인 프로그래밍 언어입니다. 즉, 윈도우즈OS나 맥OS, 리눅스OS 등 OS에서 사용할 수 있습니다.
  • 여러가지 데이터 형태를 다룰 수 있으며 인터프리터 방식의 프로그래밍 언어입니다. 인터프리터 방식이란 프로그램을 실행할 때 소스코드를 읽고 해석해서 실행하는 방식을 말합니다. 이와 반대되는 방식으로 컴파일러 방식이라는 것이 있는데 이것은 소스코드를 미리 읽고 해석해서 기계어로 만들어 놓는 방식을 말합니다. 실행은 소스코드가 아니라 미리 만들어 놓은 기계어를 실행시킵니다. 각 방식마다 장단점이 있습니다.
  • 객체 지향 프로그래밍입니다. 객체 지향 프로그래밍이란 프로그램을 객체의 모음으로 보는 것 입니다. 객체(Object)란 클래스(Class)의 한 예입니다. 클래스는 속성과 기능을 가지는 하나의 묶음을 말합니다. 간단하게 자동차라는 클래스는 차체, 바퀴, 엔진, 시트, 핸들 등의 속성과 가속, 감속, 오른쪽 전환, 왼쪽 전환 등의 기능으로 정의해서 구성 할 수 있습니다. 이렇게 만들어진 클래스의 하나 예를 들면 벤츠가 되겠습니다. 이 벤츠가 객체 입니다. 객체는 클래스와 동일한 속성/기능을 갖습니다. 또한 프로그램 실행 시 객체의 실제 사용을 위해서 인스턴스(Instance)가 만들어집니다. 자동차의 예에서는 벤츠의 특정 모델 1대를 의미합니다.
  • 위에서 말한 것 처럼 인터프리터 방식이기 때문에 실행전에 소스 코드에 문제가 없는지 잘 확인해 줘야 합니다. 잘 못된 내용이 있으면 오류가 나고 실행되지 않습니다.

 

프로그램 설치

      • 이전에 배웠던 자바 스크립트는 웹 브라우저 엔진에 의해서 해석되고 실행되기 때문에 별도의 실행 프로그램이 필요 없었습니다. 그러나 웹 어플리케이션에서 파이썬을 서버 프로그래밍 언어로 사용하기 위해서는 플랫폼에 맞는 파이썬 프로그램을 설치해 줘야 합니다. 서버라고 해서 특별한 것은 아니고 일반 PC나 노트북 보다 성능이 좋은 비싼 컴퓨터라고 생각하시면 됩니다.
      • 우리는 프로그래밍(코딩)을 배우려고하는 것이기 때문에 서버에 설치하지 않고 PC나 노트북에 파이썬 프로그램을 설치해서 사용하겠습니다. 플랫폼에 독립적이니까 이런게 좋네요.  
      • 온라인 파이썬 사용 : 프로그램 다운로드나 설치 없이도 파이썬을 맛볼 수 있습니다. 기능이 제한적이어서 계속적인 프로그래밍 공부를 하실 분은 사용을 권장하지 않고요. 말 그대로 맛보기로 파이썬이 어떤 방식으로 프로그래밍 하는 지를 알고 싶으신 분이라면 온라인 파이썬 사용도 가능합니다. 다음의 링크를 클릭하시면 웹 부라우저에서 파이썬 프로그래밍이 가능합니다. https://crumb.sh/
      • 프로그램 다운로드 / 설치 : 계속적인 파이썬 코딩을 공부하실 분들은 로컬 PC/노트북에 파이썬 프로그램 설치를 권장 드립니다.  https://www.python.org/downloads/ 에 접속해서 PC/노트북의 운영체제(OS)에 맞는 프로그램을 다운 받아서 설치하면 됩니다.  작성일 기준의 많이 쓸것 같은 OS에 맞는 버전의 다운로드를 연결해 놓았습니다. 맥용은 여기, 윈도우즈용은 여기를 클릭해서 다운 로드 받으세요.
      •  

 

  • 다운 받아서 설치하고 나면 윈도우즈는 cmd 창이나 powershell을 실행시켜서 파이썬 프로그램을 실행 시킬 수 있습니다. 맥 OS에서는 터미널을 실행 시켜서 파이썬 프로그램을 실행 시킬 수 있습니다. 프로그램이 설치된 폴더중에 python.exe 파일이 있는 디렉토리로 이동해서 python을 입력하면 파이썬 프로그램이 실행됩니다.(매번 이동해서 실행시키기 번거롭기 때문에 PATH라는 것을 설정해주면 어느 디렉토리에서든지 실행 시킬 수 있습니다.) 아래는 터미널에서 python을 실행시킨 모습입니다. 그리고 print 명령어로 "Hello Python"을 출력해봅니다. 끝으로 exit()를 입력해서 python 프로그램을 종료 합니다.
$ python
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello Python")
Hello Python
>>> exit()
$

 

이렇게 해서 파이썬 프로그램을 설치하고 실행 및 종료해 보았습니다.
이처럼 파이썬을 실행시키고 한줄 한줄 명령어 코드를 입력해서 실행할 수도 있고 별도의 text 파일로 전체 내용을 미리 코딩해 놓고 한번에 실행 할 수도 있습니다. 이때 파일명은 .py 확장자(파일명 뒤에 붙이는 이름)를 사용합니다. 실행은 python "파일명"을 입력하면 됩니다. 아래에서는 첫번째 줄에서 print 내용을 hello.py라는 파일로 만들었고, 둘째 줄에서 그 파일을 파이썬으로 실행시켰습니다. 마지막줄은 실행 결과 출력된 내용입니다.

$ echo "print('Hello Python')" > hello.py
$ python hello.py
Hello Python

 

기본 구조 및 문법

자, 이제 부터는 간단한 기본 구조와 문법에 대해서 알아보겠습니다. 우리의 목표는 파이썬이 대략 어떤 것인지 이해하는 것이므로 자세한 내용은 생략하겠습니다.

  • 주석 처리 방법 : '#"을 이용한 주석 처리. 하나의 줄(라인)에서 '#' 뒤에 오는 내용은 주석처리되어 실행되지 않습니다.
# 이 내용은 주석 처리가 되어 실행에 영향을 미치지 않습니다.
  • 파이썬은 고수준 언어 이기 때문에 변수의 사용이 가능합니다. 음.... 고수준 언어 코딩의 개요는 이렇습니다. 입력 받은 데이터와 계산에 필요한 데이터를 모두 메모리에 옮겨 놓고, 필요한 계산/연산을 진행한뒤, 결과를 반환/출력하는 것입니다. 대부분은 계산/연산 부분이 반복적인 계산이 필요한 작업입니다. 반복적인 작업을 빠르게 처리하기 때문에 컴퓨터를 이용하는 것입니다. 그래서 입/출력, 할당방법, 처리방법을 기본적으로 알고 있으면 됩니다. (추가 내용: 넘어가셔도 됩니다. 변수 할당전에 알아야 할 것이 있습니다. 바로 데이터 유형(type)인데요. 고수준 언어의 경우 추상화를 하다보니 데이터의 유형을 정해주면 메모리를 더 효율적으로 사용할 수 있습니다. 이게 왜 중요하냐하면 데이터 종류에 따라서 저장에 필요한 메모리 용량이 다르기 때문입니다. 즉, 메모리를 효율적으로 사용할 수 있기 때문입니다. 물론 최근의 프로그램은 유형을 정하지 않는 프로그래밍 언어도 있습니다. 파이썬도 자바 스크립트도 미리 데이터 타입을 정할 필요가 없습니다.)
  • 메모리에 어떤 값/데이터를 저장하는 명령어가 할당 명령어 입니다. 즉, abc = 1 이란 명령어는 1을 abc 라는 변수에 할당하라는 명령입니다. 즉, "="을 이용하여 오른 쪽의 값을 왼쪽의 변수(메모리)에 복사해 놓습니다.
  • 입력/출력 방법 : input(), print()
>>> a = input(" 내용을 입력하세요... : ") # input 함수를 이용해서 문자열을 출력하고 키보드로부터 입력을 기다립니다. 그리고 입력 받은 값을 a 변수에 할당 합니다.
내용을 입력하세요... : 123
>>> print(a) # a 변수에 저장된 내용 즉, 입력 받은 내용을 화면에 출력합니다. input으로 입력받은 내용은 문자열로 저장됩니다.
"123"
  • 다양한 유형의 데이터 처리가 가능합니다. 정수, 실수, 문자열, 리스트 등.  
    • abc 라는 변수를 만들고 여기에 정수를 할당하면 정수 변수, 실수를 할당하면 실수 변수가 됩니다. 
    • 문자열이란 스트링을 말합니다 쌍따옴표(") 또는 홀따옴표(')로 둘러싸인 내용이 스트링입니다. 문자열은 상수 즉, 변하지 않는 값입니다. 문자열도 변수에 할당 할 수 있습니다. 
    • 문자열을 숫자로 바꿀수 있고(int("문자열")), 숫자를 문자열로 바꿀 수(str(숫자)) 있습니다.
>>> a = "문자열 할당"
>>> a
'문자열 할당'
>>> num = 1
>>> print(num)
1
>>> num_str = str(num)
>>> print(num_str)
1
>>> type(num) # type함수로 데이터 유형을 알 수 있습니다.
<class 'int'>
>>> type(num_str)
<class 'str'>
  • 리스트는 여러개의 값을 가질 수 있는 하나의 변수 이름입니다. 열린 꺽쇠 괄호(대괄호) '['로 시작해서 닫힌 꺽쇠 괄호 ']'로 끝나며 포함되는 값의 구분은 ','로 합니다. abc 변수에 a, 1, b, 2가 들어있는 리스트를 할당하는 명령은 아래와 같습니다. 여기서 리스트는 여러 유형의 데이터 타입을 섞어서 포함 할 수 있다는 것을 알 수 있습니다. a는 실수 변수, b는 문자열 변수로 첫째줄에서 할당문으로 값을 정해 주었습니다.
>>> a=1.; b="취미코딩"
>>> abc = [a, 1, b, 2]
>>> abc
[1.0, 1, '취미코딩', 2]
  • 연산자
    • 사칙연산, 수학 함수, 할당문 - 정수/실수에 대한 사칙연산(+,-,*,/)이 가능합니다. a = 1 + 2
    • 그리고 자바 스크립트 예시에서 봤던 스트링의 더하기 연산이 파이썬에서도 가능합니다. add_string = "스트링" + "더하기"
    • 숫자 사이의 연산은 유형이 달라도 계산됩니다. 정수와 실수간의 계산결과는 실수 입니다. 그러나 숫자와 문자열과는 계산되지 않습니다.
    • 내장 함수와 외부 패키지를 이용하면 거의 모든 연산을 할 수 있습니다.
    • 할당자와 함께 사용해서 결과 값을 다른/같은 변수에 저장할 수 있습니다. a = a + 1   이 명령어의 의미는 a의 값에 1을 더한 값을 다시 a에 할당하라는 의미 입니다.
>>> a = 1 + 2
>>> print(a)
3
>>> add_string = "스트링" + "더하기"
>>> print(add_string)
'스트링더하기'
>>> b = 1 + 2.
>>> print(b)
3.0
>>> a = a + 1
>>> a
4
  • 흐름 제어문 : 조건문, 반복문, 제어문 등이 있습니다.
    • 파이썬은 들여쓰기가 중요합니다. 프로그램을 덩어리로 구분할 필요가 있는데 별도의 구분기호 없이 들여쓰기로 구분하기 때문입니다.  동일한 들여쓰기 간격으로 시작한 줄들을 같은 덩어리로 인식 합니다.
    • 조건문 : 아래와 같은 문법 규칙으로 적용합니다.
if 조건 :
    참일 경우 실행할 명령어
else:
    거짓일 경우 실행할 명령어
  • 반복문 : for 문
문법)
for 변수명 in 반복생성구분:
    명령어

예시) 문자열 문자 반복
for i in "Hello":
    print(i)
H
e
l
l
o

예시) 리스트 내부 반복
a_list = [1,2,3]
for i in a:
    print(i)
1
2
3

예시) 특정 횟수 반복 : range(시작숫자, 끝숫자, 증가숫자) - 시작 숫자부터 한번씩 반복하면서 증가숫자 만큼 증가 시키고 끝숫자가되면 종료
for i in range(0, 3, 1):
    print(i)
0
1
2

  • 반복문 : while 문
문법) 표현식이 참값일 동안 while 내 명령문을 반복합니다.
while 표현식 :
    명령문
예)
i = 1
while i <= 3:
    print(i)
i = i + 1
1
2
3
  • 제어문: for문이나 while문에서 break 명령어를 만나면 반복하던 루프를 벗어 납니다.
>>> i = 1
>>> while i <= 3:
...         print(i)
...         i = i + 1
...         break
...
1
>>>
  • 함수 : 반복 사용되는 처리에 대한 정의 후 반복/재사용 할 수 있도록 함수를 만들 수 있습니다. 여기에서는 매개변수(파라메터)로 받은 값에 10을 곱하는 함수를 multi_10 이라는 이름으로 만들어 보겠습니다.
# 문법)
# def 함수이름(매개변수): # 매개변수가 여러개일 경우 ','로 분리합니다.
# 명령어 # 여러 명령어도 사용가능 합니다.
# return 변수/상수/객체 # 함수의 처리결과를 돌려 줍니다.
>>> def multi_10(parameter1):
...         a = parameter1 * 10
...         return a
...
>>> return_from_function = multi_10(7)
>>> print(return_from_function)
70
>>>

이상으로 아주 간단하게 필수적인 파이썬 문법에 대해서 알아 보았습니다.

 

 

샘플 코딩 해보기 - 파이썬 코딩

이제 어떻게 작성하는 지를 알았으니 아래와 같은 요건을 만족 시키는 파이썬 프로그램을 한번 코딩해 보겠습니다. 코딩은 앞서 개발했던 자바 스크립트, HTML과 같이 택스트로 작성하면 됩니다. 그래서 특별한 작성 프로그램이 필요하지 않습니다. 메모장 같은 모든 텍스트 작성 프로그램으로 작성이 가능합니다. 메모장을 열어서 위에서 배운 문법에 따라 파이썬 프로그램이 포함된 파일을 작성해 보시지요. 메모장이 없으시면 간단한 무료 텍스트 작성기를 다운 받아 사용할 수 있습니다. 여기 링크를 통해 운영체재에 맞는 sublime text라는 택스트 작성기를 다운 받아 사용하실 수 있습니다.

요건

다음의 요건 내용에 맞는 파이썬 코딩을 해보겠습니다. 파일이름을 04_square_python.py 라고 저장해주세요.

  • 정사각형 한쪽 선의 길이를 입력 받아서 사각형의 넓이를 반환해주는 파이썬 프로그램을 작성해 봅시다.
  • 길이를 입력을 받기 위해 input 함수를 사용합니다.
  • 사각 형의 넓이는 가로 곱하기 세로로 계산하는데 정사각형이므로 가로와 세로의 길이가 같습니다. 따라서 입력받은 하나의 값과 같은 값을 곱하면 됩니다.
  • 계산된 넓이 값을 화면에 출력 합니다.
  • 함수로 만들어서 재사용 할 수 있도록 합니다. 함수명은 nemo_space로 작성 합니다.

 

취미 코딩 내용

한번 직접해 보셨나요?! 아래는 위의 요건에 맞게 파이썬으로 코딩한 내용입니다.

04_square_python.py 파일 내용)
def nemo_space ():
length_of_square = input("정사각형의 한쪽 선의 길이를 입력하세요 : ")
length_int = int(length_of_square)
space_of_square = length_int * length_int
return space_of_square

print(nemo_space())

파일 실행 및 결과
$ python 04_square_python.py
정사각형의 한쪽 선의 길이를 입력하세요 : 3
9

 

 

 

요약

포스팅에서는 정말 아주 단순한 요건을 구현해 봤지만 실제로는 추가적인 문법내용도 많고 엄청나게 많은 일을 할 수 있습니다. 웹 어플리케이션 서비스에서 필요한 서버 어플리케이션 기능의 개발을 위해 파이썬을 이용해서 웹 브라우저의 요청 내용에 따라 복잡한 계산을 수행하는 프로그램을 개발 할 수 있습니다. 파이썬은 고수준의 프로그래밍 언어이기 때문에 이해하기 쉽게 많은 일들을 할 수 있습니다. 특히 다른 많은 사람들이 만들어 놓은 복잡한 계산이 필요한 함수나 기능을 쉽게 이용할 수 있는 장점이 있습니다. 데이터 베이스와 연동한다든가, 인공지능/머신러닝 패키지를 사용할 수도 있습니다.

이번 시간에는 Python에 대해서 조금 더 구체적으로 알아 보았습니다. 기본적인 문법을 배웠고 간단한 요건을 충족시키는 Python 프로그램을 만들어 보았습니다.
지난 포스팅을 포함하여 웹 어플리케이션에 사용되는 언어에 대해서 간단히 알아보았습니다. 코딩을 배우는 목적이 무엇이냐에 따라서 배우고자 하는 프로그래밍 언어가 달라질 수 있겠습니다.
웹 브라우저에 보여지고 동작하는 것을 만드는 것이 재미 있다면 프론트엔트 개발자가 사용하는 언어를 배우는 것이 좋겠고, 복잡한 로직과 다양한 계산을 하고 싶다면 벡엔드 개발자가 사용하는 파이썬이나 자바 같은 언어를 배우시면 좋을 것 같습니다.

이러한 기본적인 지식을 가지고 먼저 재미있을 것 같은 코딩 언어를 선택하시고 조금 깊이 공부해 보시면 좋을 것 같습니다. 그러면 점차 이해가 넗어지고 다양한 기능을 개발할 수 있게 될 것 입니다.

질문 댓글은 언제나 환영이며 구독, 좋아요를 눌러 주시면 다음 글을 더 편하게 보실 수 있습니다.

감사합니다.




반응형

+ Recent posts