반응형

요즘 딥러닝 프로그램을 돌리는 컴퓨터가 있는 사무실에 계속 있기 어려운 환경에 있습니다. 그래서, 외부에서 컴퓨터를 온오프할 수 있도록 공유기 원격접속과 컴퓨터 WOL 기능을 켜두었습니다.

그리고 가장 많이 사용하고 있는 jupyter notebook을 원격지에서 사용할 수 있도록 세팅하였습니다.

1. 방화벽 해제 : 먼저 우분투 포트 방화벽 해제 및 공유기 포트포워드 설정을 합니다.
>> sudo ufw allow 8888(jupyter notebook의 기본포트로 원하시는 포트로 변경 가능)

2. jupyter notebook 암호 설정
로컬에서만 사용할 경우에는 보통 암호 설정 없이, 토큰을 이용해 접근했었습니다. 그렇지만 원격 접속은 보안을 위해 암호를 설정하는 것이 더 편하고 좋습니다. 
jupyter 서버 기본 설정을 위한 jupyter_notebook_config.py을 만들고, 패스워드를 설정합니다.
>> jupyter notebook --generate-config
Writing default config to: /{MyPath}/.jupyter/jupyter_notebook_config.py

>> jupyter notebook password
Enter password : ****
Verify password : ****
[NotebookPasswordApp] Wrote hashed password to /{Mypath}/.jupyter/jupyter_notebook_config.json

반응형

3. jupyter notebook 설정 파일 수정
nano ~/.jupyter/jupyter_notebook_config.py
수정할 코드를 ctrl+w(검색)를 사용해 찾은 후, 수정합니다.

c.NotebookApp.allow_origin = '*'  # 외부 접속을 허용합니다.
c.NotebookApp.notebook_dir = '작업 절대경로' # 작업경로를 설정합니다.
c.NotebookApp.ip = '*' # 외부 접속 포트 전체 오픈. 보안을 위해 특정 IP만 열어두셔도 됩니다.
c.NotebookApp.port = '8888' # 외부접속 사용 포트를 설정합니다.
c.NotebookApp.password = '<해시화된 패스워드 입력>' # 암호설정시 만들어진 jupyter_notebook_config.json을 nano등으로 열면 해시화된 패스워드를 확인할 수 있습니다.
c.NotebookApp.password_required = True # 비밀번호를 요구하도록 합니다.
c.NotebookApp.open_browser = False # 서버 pc에서 자동으로 브라우저가 열리지 않도록 합니다.

4. 서버 실행
>> jupyter notebook
이제 외부에서 접속하시면 됩니다. 공유기에서 ddns를 설정한 경우, ddns:포트번호(여기선 8888)을 주소창에 입력하면 접속할 수 있습니다. 
그 다음 설정한 비밀번호를 입력하면 로그인이 됩니다.

반응형
반응형

최근 AI비서, ARS 등 언어 처리에 대한 분야에서 많이 사용되는 딥러닝 아키텍처인 Transformer에 대해 공부중이다.
공부한 내용을 정리하면 좀 더 기억이 잘 되기에 기록을 남겨본다.

RNN과 LSTM 네트워크는 다음 단어 예측, 기계 번역, 텍스트 생성 등의 태스크에서 사용되어 왔었다.
하지만 트랜스포머가 발표된 후에는 트랜스포머에게 자리를 내주었다고 할 수 있다.
트랜스포머가 출연하면서 자연어 처리 분야가 획기적으로 발전하고, 이를 기반으로 한 BERT, GPT-3, T5 등과 같은 아키텍처가 나오게 되었다.

트랜스포머는 RNN에서 사용한 순환 방식을 사용하지 않는다.
대신 셀프 어텐션(self-attention)이라는 특수한 형태의 어텐션을 사용한다. 
트랜스포머는 인코더-디코더로 구성된 모델이다.
인코더에 원문을 입력하면 인코더는 원문의 표현 방법을 학습시키고 그 결과를 디코더로 보낸다.
디코더는 인코더에서 학습한 표현 결과를 가지고 사용자가 원하는 문장을 생성한다.

트랜스포머 인코더 디코더 기본 구조도

인코더와 디코더의 구체적인 이해는 다음에 하기로 한다.

대신 Transformer를 기반으로 한 BERT의 특징에 대해 정리해 본다.

BERT(Bidirectional Encoder Representation from Transformer)는 구글에서 2018년 발표한 최신 임베딩 모델이다. 대량의 영어 데이터로 학습된 사전학습 언어 모델로 질문에 대한 대답, 텍스트 생성, 문장 분류 등과 같은 태스크에사 가장 좋은 성능을 도출해 자연어 처리 분야에 크게 기여해 왔다. 

반응형

BERT의 특징

  • Masked Language Model(MLM) : 어떤 문장의 특정 부분을 Masking처리하여 모델이 Masking 처리된 부분을 예측하도록 학습시키는 방식
  • Next Sentence Prediction(NSP) : 두 문장이 이어지는 문장인지 아닌지 맞히도록 학습
  • 자기지도 학습 : 학습 Label을 사람이 직접 만들지 않고 스스로 만든 데이터를 학습함으로써 언어의 기본 소양을 쌓음. 이처럼 스스로 정답이 있는 학습 데이터를 만들어 학습하는 방식을 자기지도학습(Self-supervised Learning)이라고 하고 이러한 방식으로 만들어진 언어 모델을 사전학습 모델(Pre-trained Language Model)이라고 한다.
  • 전이학습(Transfer Learning) : 사전학습 모델을 기반으로 특정 태스크를 위해 한번 더 학습하는 방식을 전이학습이라고 하고, 이 학습 단계를 파인튜닝(Fine tuning)단계라고 한다. 파인튜닝이란 사전학습 모델을 기반으로 특정 태스크를 위해 딥러닝 모델을 미세하게 조정하는 학습 과정을 말한다.

태스크 활용 사례 : 사전학습 모델은 모델 자체로 특정 기능을 수행할 수 없다. 하지만 파인 튜닝을 통해 여러 다양한 태스크에 활용이 가능하다. 

Case 1. 기계독해(MRC, Machine Reading Comprehension) 
 
Case 2. 텍스트 분류(Text Classification)
 
Case 3. 문장 유사도 분석(STS, Semantic Textual Similarity)
 
Case 4. 문서 요약 모델(Text Summarization)
 

* RNN(Recurrent Neural Networks) 순환신경망 : 긴 문장의 의미를 파악하고 해당 문장이 의미하는 것이 무엇인지 예측하기 위한 방법으로 쉽게 말해 '여러개의 단어를 입력받게 되었을 때 앞에 입력받은 단어(토큰)을 잠시 기억하고 있다가 이 단어가 얼마나 중요하지 분석해 가중치를 담아 다음 단계로 넘기는 구조로 되어 있다.

* LSTM(Long Short Term Memory)  장단기 메모리 : RNN 기법의 하나로 기존 RNN의 문제인 기울기 소멸 문제(vanishing gradient problem)를 방지하기 위해 개발되었다.

 
반응형
반응형

머신러닝을 접하면서 마주하게 될 용어들을 정리해 보도록 한다. 

1. 자연어 처리(Natural Language Processing, NLP) : 자연어 처리(NLP)는 인간이 대화하는 말의 형태를 기계가 배우는 머신러닝 방법을 말한다. 지금까지 기본적으로 NLP로 진행해 왔던 분류는 다음과 같다.
- 텍스트 분류 및 순위(Text classification and ranking) : 스팸이나 정크 메일을 필터링 해서 분류하는 것이 대표적이다.
- 감성 분석(Sentiment analysis) : 이 분석은 머신이 제공하는 피드백에 대한 감성적 반응을 예측한다. 고객 관계와 만족도가 팩터가 된다.
- 문서 요약(Document summarization) : 복합적이고 복잡한 긴 글을 짧고 압축된 정의를 사용해 제시하는 방법이다. 궁극적인 목적은 이해하기 쉽게 만드는데 있다.
- 개체 이름 인식(Named-Entity Recognition, NER) : 이것은 비구조화된 언어들 세트에서 구조화되고 인식가능한 데이터를 찾아내는 것이다. 이 머신러닝 프로세스는 대화 중 문맥에 맞게 적용하거나 가장 적합한 반응을 이끌어내는데, 가장 적합한 키워드를 알아내는 것을 배운다. 
- 음성 인식(Speech recognition) : 음성 인식은 아마존 알렉사, 구글 어시스턴트 등에서 쉽게 볼 수 있는 메커니즘이다. 이 메커니즘의 기본은 사람의 음성으로부터 오디오 신호를 인식하여 활자와 결합하는 것을 배우는 것이다.  
- 기계 번역(Machine translation) : 기록된 특정 나라 언어를 다른 나라의 언어로 변환하는 자동화된 시스템을 말한다. 

반응형

2. 데이터셋(Dataset) : 머신러닝의 실행 가능성과 진행을 테스트하기 위해 사용할 수 있는 변수들의 집합이라고 할 수 있다. 데이터는 머신러닝을 진행하기 위한 필수 요소이다. 
- 트레이닝 데이터(Training data) : 이름에서 알 수 있듯이, 트레이닝 데이터는 추론을 통한 모델 학습을 통해 패턴을 예측하기 위해 사용된다. 트레이닝 데이터의 영향력이 매우 크기 때문에, 다른 요소에 비해 매우 중요한 요소라 할 수 있다. 
- 검증 데이터(Validation data) : 트레이닝된 모델의 하이퍼 파라미터를 미세 조정하는데 사용하는 데이터이다. 이를 통해 최종 완성된 모델이 만들어진다.
- 테스트 데이터(Test data) : 모델 학습이 완성되었다고 생각되면, 테스트 데이터를 통해 완성된 모델이 실제 제대로 동작하는지 확인한다. 

3. 컴퓨터 비전(Computer Vision, CV) : 이미지와 영상 데이터에 대한 고급 분석을 제공하는 툴이라고 할 수 있다. 
- 이미지 분류(Image classification) : 다양한 이미지와 그림 표현을 인식하고 학습하도록 한다. 이 모델은 색상 변경과 같은 작은 변화가 있는 동일한 이미지를 인식하여 동일한 이미지로 유지한다.
- 객체 인식(Object detection) : 이미지 분류와 달리, 전체 뷰에서 객체 이미지를 인식하는데 사용되는 모델이다. 이 모델은 대용량 데이터 셋에 객체 식별을 적용할 수 있고, 패턴 인식이 가능하도록 해준다.
- 이미지 분할(Image segmentation) : 이 모델은 과거에 처리한 픽셀과 특정 이미지 또는 영상 픽셀을 연결하는 것이다. 
- 특징 인식(Saliency detection) : 이미지 또는 영상 속에서 시각적으로 가장 중요한 물체가 어디에 있는지 얼마나 중요한지 찾아내기 위한 모델이다. 
* Object detection은 영상 속 존재하는 모든 물체들의 위치를 box형태로 찾아내고 각각의 종류를 분류하는 것이고, Object segmenatation은 영상을 같은 종류 물체끼리 분할하여 픽셀 단위로 표시하는 것이다. Saliency detection은 이미지 내에서 중요하다고 생각되는 물체를 검출해내는 방법과 사람의 시선이 어디에 가장 오래 머물지 예측하는 방법으로 나뉜다.

  

반응형
반응형

요즘 부업 또는 본업으로 온라인 유통업을 하는 분들이 많이 늘고 있다.

나도 몇개 제품을 가지고 판매를 시작했는데, 처음에는 광고를 달지 않고 판매를 하려고 했다.

그런데, 정말 노출이 안되는 걸 알게 되었다.

그래서, 네이버 광고에 가입해서 광고를 시작하게 되었다.

네이버 광고 시스템이 첫눈에 확 들어오는 구조가 아니라서, 좀 복잡했다.

일단 만들어서 올려보는게 상책인 거 같아서, 만들어 올려보았다.

 

첫 주문이 발생했다. 일주일에 약 3~5개 주문이 들어왔다. 기분이 좋았다. 

그런데, 2주 정도 지나자 주문이 안들어오는 것이다. 광고 노출도 안되고 있었다. 

원인이 뭘까 찾아보니, 유료로 네이버 광고를 도와주는 시스템들이 눈에 들어왔다.

광고소재별 약 5~10분 주기로 그 소재(키워드) 광고 순위를 확인한 후 광고금액을 자동 증감하는 구조로 되어 있었다.

아, 이래서 내 광고는 노출이 안되었던 거구나.

난 목표순위와 상관없이 언제나 최소 고정금액이었으니, 당연히 노출이 안되었던 것이다.

많은 사람들이 네이버 광고를 도와주는 유료 시스템을 사용하고 있다면, 그 사람들께 노출될 수 밖에 없겠구나...

그런데, 이 유료 시스템이 네이버에서 제공하고 있는 네이버 광고 API를 사용하고 있는 것이다.

그렇다면, 파이썬으로 직접 필요한 부분을 만들어서 사용하면 어떨까 하는 생각이 들었다.

네이버 검색 광고 API

http://naver.github.io/searchad-apidoc/#/guides

 

searchad-apidoc

 

naver.github.io

구성은 AdExtension(확장소재), Adgroup(광고그룹), Ad(광고), Campaign(캠페인), BusinessChannel(비즈니스채널), AdKeyword(광고키워드), LabelRef(라벨 참조), Label(라벨), ManagedKeyword(관리하고 있는 키워드), Target(목표), IpExclusion(차단된 IP), Bizmoney(비즈머니), ManagedCustomerLink(관리하고 있는 고객링크), StatReport(상태보고서), Stat(상태), MasterReport(마스터보고서), RelKwdStat(연관 키워드 정보보기), Estimate(평가)

한 눈에 안들어오는 구성이다. 

전체 구성을 대략적으로 파악하기 위해서 '네이버 검색 광고 API'를 실제 네이버 광고 시스템과 매칭해 보면서 익혀 보는 것이 좋다.

일단, 가장 쉬운 것부터 하기로 했으니, 소스 분석은 나중에 심도있게 쪼개보기로 하자.

지금은 파이썬에서 쉽게 사용할 수 있도록 네이버 검색 광고 API에 접근할 수 있는 라이브러리를 활용해 보도록 하겠다.

깃헙에 올라와 있는 powernad로 쉽게 접근해 보도록 하자.

https://github.com/devkingsejong/python-PowerNad

 

devkingsejong/python-PowerNad

Naver search Ad Lib for Python. Contribute to devkingsejong/python-PowerNad development by creating an account on GitHub.

github.com

  • 먼저 라이브러리를 인스톨한다.

>> pip install powernad

또는 git clone https://github.com/devkingsejong/python-PowerNad.git

  • 그 다음에 라이브러리를 읽어들인다.

>>> from powernad.API.Campaign import *

  • 네이버 광고에서 제공하는 관련 API 정보를 세팅한다.

BASE_URL = 'https://api.naver.com'
API_KEY = '000000000000000000000000000000000000000000000000000000000000000000'
SECRET_KEY = '00000000000000000000000000000000000000000000000000'
CUSTOMER_ID = '0000000'   

  • 캠페인 초기화

>>> c = Campaign(BASE_URL, API_KEY, SECRET_KEY, CUSTOMER_ID)

  • 캠페인 리스트 불러오기

>>> c.get_campaign_list()

  • 연관 키워드 정보 보기

>>> from powernad.API.RelKwdStat import *

  • RelKwdStat 초기화

>>> rel = RelKwdStat(BASE_URL, API_KEY, SECRET_KEY, CUSTOMER_ID)

  • '샴푸' 키워드로 검색해 보기

# 위 결과값은 키워드, 월간검색수(PC, 모바일), 월평균클릭수(PC, 모바일), 월평균클릭률(PC, 모바일), 경쟁정도를 말한다. [0]을 다른 값으로 변경해서 연간키워드에 대한 정보도 습득할 수 있다.

오늘은 여기까지 해보자. 

5월 중에 위 알고리즘에 따라 광고키워드 순위에 따른 광고금액 변경을 할 수 있는 방법을 올려보도록 하겠다.

각자 위 라이브러리를 활용해서, 네이버 광고 API를 잘 이용할 수 있는 노하우를 갖게 되었으면 좋겠다.

반응형
반응형

git 기본 명령어(로컬)

git(깃)은 파이썬으로 작업하는 사람들이 협업하는데 있어 필수적이라고 생각한다. 명령어 사용에 익숙해질 수 있도록 기본 명령어를 정리해 봐야겠다.

- git init : 기존 디렉토리(폴더)를 git repository(저장소)로 초기화하여 만들기

- git add 파일이름 : git에 새로운 파일을 추가하여 git이 추적할 수 있게 하기

- git commit -m "<메시지>" : 변경된 파일을 저장소에 제출하기

- git status : 현재 저장소 상태를 출력하기

 

git branch(독립적인 공간을 따로 만들기)

- git branch 이름 : '이름'의 브랜치를 만들기

- git checkout 브랜치이름 : 현재 작업중인 '브랜치이름'으로 작업 공간을 변경하기

- git merge 브랜치이름 : 현재 작업중인 브랜치(보통 master)에 '브랜치이름'을 끌어와 병합하기

 

Github(원격 저장소 대표) 기본

대표적인 Git 기반의 원격 저장소로, 전세계에서 진행되는 오픈소스 프로젝트가 가장 많이 모여 있는 곳임. 

GitHub의 각 프로젝트 메인화면의 기본적인 기능은 다음과 같다.

- 포크(Fork) : 다른 사람의 저장소를 복사하기

- 풀 리퀘스트(Pull Request) : 포크한 저장소를 수정해 다시 원본 저장소에 병합해달라는 요청하는 것

- 이슈(Issues) : 저장소 안에서 사용자들 사이의 문제를 논의하는 기능

- 위키(Wiki) : 저장소와 관련된 체계적인 기록을 남기는 기능

 공개(public) 원격 저장소와 비공개(private) 원격 저장소로 구분되는데, 무료 사용자는 공개 원격 저장소를 생성해서 사용해야 한다.

 

원격 저장소와 Git 명령어

- git clone : 원격 저장소의 모든 내용을 로컬 저장소로 복사한다.

- git remote add : 로컬 저장소를 특정 원격 저장소와 연결한다.

- git push : 로컬 저장소의 내용을 보내거나 로컬 저장소의 변경 사항을 원격 저장소로 보낸다.

- git fetch : 로컬 저장소와 원격 저장소의 변경 사항이 다를 때 이를 비교 대조하고 git merge 명령어와 함께 최신 데이터를 반영하거나 충돌 문제 등을 해결한다.

- git pull : git remote 명령을 통해 서로 연결된 원격 저장소의 최신 내용을 로컬 저장소로 가져오면서 병합한다. git push와 반대 성격의 명령어이다. 

 

반응형
반응형

머신러닝에 있어, 가장 먼저해야 하는 일 중 하나가 데이터 정제(Data Cleaning)입니다.

왜냐하면 바로 모델을 훈련할 수 있는 데이터셋을 확보하는 것이 실제로는 매우 어렵기 때문입니다.

따라서, 결측값(NaN)은 없는지, 이상치(outlier)는 없는지 알아보기 위해 데이터셋을 주의깊게 살펴보아야 합니다. 

값이 큰 열이 있는 경우 정규화를 통한 보정이 필요하기도 합니다. 

이번에는 데이터 정제(Data Cleaning)에 필요한 일반적인 작업에 대해 알아보도록 하겠습니다.

 

결측값(NaN)이 있는 열 정제하기

다음 데이터로 된 NaNDataset.csv 파일이 있다고 가정하겠습니다.

눈으로 봐도 몇개 열에 결측값이 있는 것을 확인할 수 있습니다.

작은 데이터셋에서는, 쉽게 결측값을 찾을 수 있습니다.

하지만, 큰 데이터셋에서는, 눈으로 알아내는 게 거의 불가능할 것입니다.

결측값을 찾아내는 효과적인 방법은 판다스(Pandas) 데이터프레임으로 데이터셋을 로드해서 데이터프레임의 빈 값(NaN) 여부를 확인하기 위해 isnull() 함수를 사용하는 것입니다.

>>> import pandas as pd
>>> df = pd.read_csv('NaNDataset.csv')
>>> df.isnull().sum()

B 컬럼에 두개의 빈 값이 있는 것을 볼 수 있습니다.

판다스(Pandas)에서 빈 값이 포함된 데이터셋을 로드할 때, 빈 필드를 나타내는 NaN을 사용할 것입니다.

다음은 데이터프레임의 결과물입니다.

컬럼의 평균값으로 NaN 대체하기

데이터셋의 NaN(빈 값)을 처리하는 방법 중 하나는 그 빈 값이 위치한 컬럼의 평균값으로 빈 값을 대체 처리하는 것입니다.

다음의 스니펫 코드는 B 컬럼의 모든 빈 값(NaN)을 B 컬럼의 평균값으로 대체합니다.

>>> df.B = df.B.fillna(df.B.mean()) # NaN(빈 값)을 B 컬럼의 평균값으로 대체합니다.
>>> df

열 제거하기

데이터셋에서 빈 값(NaN)을 처리하는 다른 방법은 빈 값이 포함된 열을 제거하는 것입니다.

아래와 같이 dropna() 함수를 사용해서 처리할 수 있습니다.

>>> df = pd.read_csv('NaNDataset.csv')
>>> df = df.dropna()
>>> df

NaN이 포함된 행을 제거한 후에 인덱스 순번이 더 이상 맞지 않는다는 것을 알 수 있습니다.

인덱스를 재설정하고 싶다면, reset_index() 함수를 사용합니다.

>>> df = df.reset_index(drop=True) # 인덱스를 재설정합니다
>>> df

반응형

중복된 열 제거하기

다음 데이터로 된 DuplicateRows.csv 파일이 있다고 가정하겠습니다.

중복된 모든 열을 찾기 위해, 먼저 데이터셋을 데이터프레임에 로드합니다.

그리고, duplicated() 함수를 적용합니다.

>>> df = pd.read_csv('DuplicateRows.csv') # 판다스(Pandas) 라이브러리는 이미 로드했다고 가정합니다.
>>> df.duplicated(keep=False))

어떤 열이 중복되었는지 알려줍니다. 위 예에서는, 인덱스 1, 2, 5, 6열이 중복입니다. 

keep 인수를 사용하면 중복을 표시하는 방법을 지정할 수 있습니다.

  • 기본값은 'first' : 첫번째 나타나는 것을 제외한, 모든 중복이 True로 표시됩니다.
  • 'last' : 마지막으로 나타나는 것을 제외한, 모든 중복이 True로 표시됩니다.
  • False : 모든 중복이 True로 표시됩니다.

만약 keep 인수를 'first'로 설정하면, 다음과 같은 결과물을 보게 될 것입니다:

따라서, 모든 중복 열들을 보고 싶다면, keep 인수를 False로 설정해야 합니다. 

>>> df[df.duplicated(keep=False)]

중복 행을 삭제하려면 drop_duplicates() 함수를 사용할 수 있습니다.

>>> df.drop_duplicates(keep='first', inplace=True) # 처음 열은 그대로 두고, 그 다음 중복 열만 제거합니다.
>>> df

기본적으로, drop_duplicates() 함수는 원본 데이터프레임을 수정하지 않고, 제거된 열이 포함된 데이터프레임을 반환합니다.

만약 원본 데이터프레임을 수정하고 싶다면, inplace 파라미터를 True로 설정해야 합니다.

때로는 데이터셋의 특정 열에서 발견된 중복만 제거하고 싶은 경우가 있습니다.

예를 들어, 3, 4열의 B컬럼은 값이 다르지만, A, C 컬럼은 동일합니다. 이를 기준으로 제거해 보도록 하겠습니다.

>>> df.drop_duplicates(subset=['A', 'C'], keep='last', inplace=True) # A, C 컬럼에 모든 중복을 제거하고, 마지막 열을 남깁니다.
>>> df

컬럼 정규화하기

정규화는 데이터 정리 프로세스 중에 자주 적용되는 기술입니다.

정규화의 목적은 데이터 범위의 숫자 열 값을 변경하여, 값 범위의 차이를 수정하지 않고 공통 척도를 적용하는 것입니다.

일부 알고리즘은 데이터를 올바르게 모델링하기 위해 정규화가 중요합니다. 

예를 들어, 데이터셋 열 중 하나는 0에서 1까지의 값을 포함하고 다른 열은 400,000에서 500,000까지의 값을 가질 수 있습니다. 

두 개의 열을 사용하여 모델을 훈련하면 숫자의 척도가 크게 달라질 수 있습니다. 

정규화를 사용하면 두 열의 값 비율을 제한된 범위로 유지하면서 값의 비율을 유지할 수 있습니다.

판다스(Pandas)에서는 MinMaxScaler 클래스를 사용하여 각 열을 특정 값 범위로 확장할 수 있습니다.

다음 데이터로 된 NormalizeColumns.csv 파일이 있다고 가정하겠습니다.

다음 스니펫 코드는 모든 열의 값을 (0,1) 범위로 조정합니다.

>>> import pandas as pd
>>> from skleran import preprocessing
>>> df = pd.read_csv('NormalizeColumns.csv')
>>> x = df.values.astype(float)
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> x_scaled = min_max_scaler.fit_transform(x)
>>> df = pd.DataFrame(x_scaled, columns=df.columns)
>>> df

이상치(outlier) 제거하기

통계에서 이상치(이상점, outlier)는 관측된 다른 점들과 먼 지점의 점입니다.

예를 들어, 다음과 같은 값들(234, 267, 1, 200, 245, 300, 199, 250, 8999, 245)이 세트로 주어졌다고 하면, 이 중에서 명백하게 1과 8999는 이상치(oulier)입니다. 

그들은 나머지 값들과 뚜렷이 구별되며, 데이터셋의 대부분의 다른 값들과 달리 "바깥에 위치합니다". 

이상치는 주로 기록 또는 실험 오류의 오류로 인해 발생하며 머신러닝에서는 모델을 학습하기 전에 이상치를 제거해야 합니다. 

그렇지 않으면 모델을 왜곡시킬 수 있습니다.

이상치를 제거하는 데는 여러 가지 기술이 있으며,이번에서는 두 가지를 논의합니다.

  • Tukey Fences
  • Z-Score

Tukey Fences

Tukey Fences는 사분위 범위(IQR, interquartile range)를 기반으로 합니다. 

Q1이라고 표시된 첫번째 사분위수는 데이터셋의 값 중 첫번째 25 %를 보유하는 값입니다.

3분위수(Q3)은 데이터셋의 값 중 3번째의 25 %를 보유하는 값입니다. 

따라서, 정의에 따르면, IQR = Q3-Q1입니다.

아래 그림은 짝수 및 홀수 값을 가진 데이터셋에 대해 IQR을 얻는 방법의 예를 보여줍니다.

Tukey Fences에서 이상치(outlier)는 다음과 같은 값입니다.

  • Q1 - (1.5 * IQR) 미만 or
  • Q3 + (1.5 * IQR) 초과

다음 스니펫 코드는 파이썬을 사용해 Tukey Fences를 실행하는 방법을 보여줍니다.

>>> import numpy as np
>>> def outliers_iqr(data):
              q1, q3 = np.percentile(data, [25, 75])
              iqr = q3 - q1
              lower_bound = q1 - (iqr * 1.5)
              upper_bound = q3 + (iqr * 1.5)
              return np.where((data > upper_bound) | (data < lower_bound))

np.where() 함수는 조건에 만족하는 아이템들의 위치를 반환합니다. 

outliers_iqr() 함수는 첫 번째 요소가 이상치(oulier)값을 갖는 행의 인덱스 배열인 튜플을 반환합니다.

Tukey Fences를 테스트하기 위해, 부모와 자녀의 키에 대해 유명한 Galton 데이터셋을 사용해 보도록 하겠습니다. 

이 데이터셋에는 Francis Galton이 1885년에 실시한 유명한 아동 연구결과를 기반으로 한 데이터가 포함되어 있습니다. 

각각의 경우는 성인용이며 변수는 다음과 같습니다.

  • Family : 자녀가 속한 가족으로서 1에서 204 사이의 숫자와 136A로 표시됩니다.
  • Father : 아빠의 키(인치)
  • Mother : 엄마의 키(인치)
  • Gender : 아이들의 성, 남성(M) 또는 여성(F)
  • Height : 아이들의 키(인치)
  • Kids : 아이들의 가정에서, 아이들의 숫자

이 데이터셋은 898 케이스를 갖고 있습니다. 

먼저 데이터를 읽어들입니다:

>>> import pandas as pd
>>> df = pd.read_csv('http://www.mosaic-web.org/go/datasets/galton.csv')
>>> df.head()

height 컬럼에서 이상치(outlier)를 찾고 싶다면, 다음과 같이 outliers_iqr() 함수를 불러옵니다.

>>> print('Outliers using ourliers_iqr()')
>>> print('=====================')
>>> for i in outliers_iqr(df.height)[0]:
                 print(df[i:i+1])

다음과 같은 결과를 볼 수 있습니다:

Tukey Fences 메서드를 사용해, height 컬럼에 하나의 이상치(outlier)가 있다는 것을 알 수 있었습니다.

Z-Score

이상치(outlier)를 결정하는 두번째 방법은 Z-Score 메서드를 사용하는 것입니다. 

Z-Score는 데이터 포인트가 평균에서 얼마나 많은 표준 편차를 가지는지 나타냅니다.

Z-Score의 공식은 다음과 같습니다.

여기서 xi는 데이터 포인트, μ는 데이터셋의 평균, σ는 표준편차입니다.

  • 음의 Z-Score는 데이터 포인트가 평균보다 작음을 나타내고 양의 Z-Score는 문제의 데이터 포인트가 평균보다 큰 것을 나타냅니다.
  • Z-Score가 0이면 데이터 포인트가 중간(평균)이고 Z-Score가 1이면 데이터 포인트가 평균보다 1 표준편차가 높다는 것을 알 수 있습니다.
  • 3보다 크거나 -3보다 작은 모든 Z-Score는 이상치(outlier)로 간주됩니다.

다음 스니펫 코드는 파이썬을 사용해 Z-Score를 실행하는 방법을 보여줍니다.

>>> def outliers_z_score(data):
           threshold = 3
           mean = np.mean(data)
           std = np.std(data)
           z_scores = [(y - mean) / std for y in data]
           return np.where(np.abs(z_scores) > threshold)

이전에 사용한 것과 동일한 Galton 데이터셋에 대해 outliers_z_score()함수를 사용해 height 컬럼에 대한 이상치(outlier)를 찾을 수 있습니다.

>>> print('Outliers using ourliers_z_score()')
>>> print('=========================')
>>> for i in outliers_z_score(df.height)[0]:
                 print(df[i:i+1])

다음과 같은 결과물을 볼 수 있습니다.

Z- Score 메서드를 사용하면 height 컬럼에 3개의 이상치(outlier)가 있음을 알 수 있습니다.

(Source : Python Machine Learning, Wiley, 2019)

반응형
반응형

사이킷런(Scikit-learn)으로 머신러닝을 시작하는 가장 쉬운 방법 중 하나가 선형 회귀분석을 구현해 보는 것입니다.

선형 회귀분석은 스칼라 종속 변수 y와 하나 이상의 설명 변수(또는 독립 변수) 간의 관계를 모델링하는 선형 접근법입니다.

예를 들어, 사람들의 키와 몸무게로 된 데이터셋이 있다고 합시다. 

>>> %matplotlib inline
>>> import matplotlib.pyplot as plt
>>> plt.rc('font', family='NanumGothic') # 네이버 글꼴을 미리 다운로드 받아야 합니다. 다른 글꼴을 사용하시려면 글꼴명을 변경해서 사용하시면 됩니다. 
>>> heights = [[1.6], [1.65], [1.7], [1.73], [1.8]] # 키는 미터(meter)로 계산합니다.
>>> weights = [[60], [65], [72.3], [75], [80]] # 몸무게는 킬로그램(kg)으로 계산합니다.
>>> plt.title('키 대비 몸무게 그래프')
>>> plt.xlabel('키(미터)')
>>> plt.ylabel('몸무게(킬로그램)')
>>> plt.plot(heights, weights, 'k.')
>>> plt.axis([1.5, 1.85, 50, 90])
>>> plt.grid(True)

그래프에서 볼 수 있듯이, 사람들의 몸무게와 키 사이에는 양의 상관관계가 있다는 것을 알 수 있습니다. 

위 그래프에서 점을 기반으로 직선을 그리고, 그 직선으로 키에 따른 다른 사람의 몸무게를 예측할 수 있습니다.

모델 피팅을 위한 LinearRegression 클래스 사용하기

그렇다면 모든 점들을 연결해서 중심축을 지나는 직선을 어떻게 그릴 수 있을까요? 이를 수행하기 위해 사이킷런(Scikit-learn) 라이브러리에는 LinearRegression 클래스가 있습니다. 우리가 해야 하는 일은 이 클래스의 인스턴스를 만들고, 몸무게와 키의 리스트를 사용해 fit() 함수로 다음과 같이 선형 회귀분석(linear regression) 모델을 생성하는 것입니다. 

>>> from sklearn.linear_model import LinearRegression
>>> model = LinearRegression() # 모델을 생성합니다.
>>> model.fit(X=heights, y=weights) # 모델에 X, y 값들을 적용합니다. fit 함수는 리스트 또는 배열 형태의 X, y 인수들을 필요로 합니다.
반응형

예측 만들기

fit 함수로 모델을 훈련하고 나면, predict 함수를 사용해 다음과 같이 예측을 만들 수 있습니다.

>>> weight = model.predict([[1.75]])[0][0]
>>> round(weight, 2) # 예측 값은 76.04로 나옵니다.

위 예제에서, 훈련된 모델을 기반으로 키가 1.75m인 사람의 몸무게는 76.04kg으로 예측되었습니다.  

선형 회귀분석 선 그리기

LinearRegression 클래스에 의해 생성된 선형 회귀분석 선을 시각화하는 것이 유용할 것입니다. 먼저 원래의 데이터 포인트를 플로팅한 다음 모델에 키 목록을 보내 가중치를 예측합니다. 그런 다음 일련의 예상 가중치를 플롯하여 선을 얻습니다. 다음 스니펫 코드는 수행되는 방식을 보여줍니다.

>>> import matplotlib.pyplot as plt
>>> plt.rc('font', family='NanumGothic') # 한글을 표시하기 위해, 한글 폰트를 설정합니다. 여기서는 네이버 글꼴로 처리했습니다. 무료로 지원되는 네이버 글꼴을 미리 다운로드 받아야 합니다. 다른 글꼴을 사용하시려면 글꼴명을 변경해서 사용하시면 됩니다. 
>>> heights = [[1.6], [1.65], [1.7], [1.73], [1.8]] # 키는 미터(meter)로 계산합니다.
>>> weights = [[60], [65], [72.3], [75], [80]] # 몸무게는 킬로그램(kg)으로 계산합니다.
>>> plt.title('키 대비 몸무게 그래프')
>>> plt.xlabel('키(미터)')
>>> plt.ylabel('몸무게(킬로그램)')
>>> plt.plot(heights, weights, 'k.')
>>> plt.axis([1.5, 1.85, 50, 90])
>>> plt.grid(True)
>>> plt.plot(heights, model.predict(heights), color='r') # 선형 회귀 선을 그립니다.

선형 회귀분석 선의 기울기 및 절편 얻기

위 그래프에서는 선형 회귀분석 선의 y 축 절편이 무엇인지 명확하지 않습니다. 이는 1.5로 플로팅을 시작하도록 x축을 조정했기 때문입니다. 이를 시각화하는 더 좋은 방법은 x 축을 0에서 시작하고 y 축의 범위를 확대하여 설정하는 것입니다. 그런 다음 높이 0과 1.8의 두 가지 극단 값을 입력하여 선을 그립니다. 다음 스니펫 코드는 점과 선형 회귀분석 선을 다시 그립니다.

>>> plt.title('키 대비 몸무게 그래프')
>>> plt.xlabel('키(미터)')
>>> plt.ylabel('몸무게(킬로그램)')
>>> plt.plot(heights, weights, 'k.')
>>> plt.axis([0, 1.85, -200, 200])
>>> plt.grid(True)
>>> extreme_heights = [[0], [1.8]] 
>>> plt.plot(extreme_heights, model.predict(extreme_heights), color='b') # 선형 회귀분석 선을 그립니다.

>>> round(model.predict([[0]])[0][0], 2) # 키가 0 인 경우 몸무게를 예측하여 y 절편(-104.75)을 얻을 수 있습니다.
>>> round(model.intercept_[0], 2) # intercept_ 속성을 통해 직접 답변(-104.75)을 받을 수 있습니다.
>>> round(model.coef_[0] [0], 2) # coef_ 속성을 통해 선형 회귀 선의 그래디언트(103.31)을 얻을 수도 있습니다.

RSS를 계산하여 모델의 성능 검토하기

선형 회귀분석 선이 모든 데이터 요소가 잘 맞는지 알아 보려면, RSS(Residual Sum of Squares) 메서드를 사용합니다.

먼저 이와 관련된 용어들에 대해 알아보도록 하겠습니다.

  • R-squared(R^2)는 우리말로 결정계수라고 합니다.
  • R-squared는 0부터 1 사이의 값을 가지고, 1에 가까울수록 설명력이 높은 것을 의미합니다(선형 회귀분석 모델이 얼마나 데이터를 잘 설명해 주는지에 대한 값입니다)
  • TSS(Total sum of squares) : 편차의 제곱합
  • RSS(Regression sum of squares) : 회귀식과 평균값의 차이
  • SSE(Sum of squared errors) : 회귀식과 실제값의 차이
  • TSS = RSS + SSE

다음 스니펫 코드는 어떻게 RSS가 파이썬에서 계산되는지 보여줍니다.

>>> import numpy as np
>>> print('RSS: %.2f' % np.sum((weights - model.predict(heights)) ** 2)) # RSS : 5.34

선형 회귀를 위한 RSS(Residual Sum of Squares) 계산하기

RSS는 가능한 한 작아야 하며 회귀 선이 점에 정확히 일치한다는 것을 나타냅니다 (실제 세계에서는 거의 달성 할 수 없음).

테스트 데이터셋을 사용하여 모델 평가하기

우리 모델이 훈련용 데이터로 훈련되었습니다. 이제 훈련이 잘 되었는지 테스트를 해봐야 합니다.

다음 테스트 데이터셋을 가지고 있다고 가정합니다. 

>>> heights_test = [[1.58], [1.62], [1.69], [1.76], 1.82]]
>>> weights_test = [[58], [63], [72], [73], [85]]

다음 코드 스니펫으로 R-squared(결정계수)를 계산해 봅니다.

>>> weights_test_mean = np.mean(np.ravel(weights_test))
>>> TSS = np.sum((np.ravel(weights_test) - weights_test_mean) ** 2) # ravel 함수는 2차원 목록을 인접한 병합된 평면(1 차원) 배열로 변환합니다.
>>> print("TSS: %.2f" % TSS)
>>> RSS = np.sum((np.ravel(weights_test) - np.ravel(model.predict(heights_test))) ** 2)
>>> print("RSS: %.2f" % RSS)
>>> R_squared = 1 - (RSS / TSS)
>>> print("R-squared: %.2f" % R_squared)

결정계수(R-squared)를 보니 선형 회귀분석 모델이 데이터를 잘 설명해 주고 있는 것으로 보입니다.

위와 같이 코드를 직접 작성해서 결정계수를 구해도 되지만, 사이킷런(Scikit-learn)에서는 결정계수(R-squared)를 바로 계산해주는 score() 함수가 존재합니다. 

>>> print('R-squared: %.4f' % model.score(heights_test, weights_test))

모델 유지하기

모델을 훈련하고 나면, 나중에 사용하기 위해 이 모델을 저장하는 것이 유용합니다. 테스트 할 새 데이터가 있을 때마다 모델을 다시 학습하는 대신 저장된 모델을 사용하면 훈련된 모델을 로드하고 모델을 재교육할 필요없이 즉시 실행이 가능합니다.

파이썬에서 훈련한 모델을 저장하는 방법입니다.

  • 파이썬에서 표준 pickle 모듈을 사용하여 객체 직렬화 및 비 직렬화하는 방법 
  • 사이킷(Scikit)에서 joblib 모듈 사용하기 - 넘파이(NumPy) 데이터를 처리하는 파이썬 객체를 저장하고 로드하기 위해 최적화된 학습 방법

먼저 pickle 모듈을 사용해서 모델을 저장하는 방법을 살펴봅니다.

>>> import pickle
>>> filename = 'HeightsAndWeights_model.sav'
>>> pickle.dump(model, open(filename, 'wb'))

파일을 'wb' 모드('w'는 읽는다는 의미, 'b'는 바이너리 형태로)로 읽어들입니다. 그 다음 pickle 모듈에서 dump() 함수를 사용해 모델을 파일로 저장합니다.

이 모델을 파일에서 로드하기 위해, load() 함수를 사용합니다.

>>> loaded_model = pickle.load(open(filename, 'rb')

이제 바로 이 모델을 사용할 수 있습니다.

>>> result = loaded_model.score(heights_test, weights_test)

다음은 사이킷런(Scikit-learn)의 joblib 모듈을 사용해 봅니다.

>>> from sklearn.externals import joblib
>>> filename = 'HeightsAndWeights_model2.sav'
>>> joblib.dump(model, filename) # 모델을 파일로 저장합니다.
>>> loaded_model = joblib.load(filename) # 파일에서 모델을 로드합니다.
>>> result = loaded_model.score(heights_test, weights_test)

다음 번에서는 데이터 전처리(Data Cleaning)와 정규화(Normalizing)에 대해 살펴보도록 하겠습니다.

(Source : Python Machine Learning, Wiley, 2019)

 

 

 

반응형
반응형

Scikit-learn 라이브러리는 파이썬에서 가장 유명한 머신러닝 라이브러리 중 하나로, 분류(classification), 회귀(regression), 군집화(clustering), 의사결정 트리(decision tree) 등의 다양한 머신러닝 알고리즘을 적용할 수 있는 함수들을 제공합니다.

이번에는 머신러닝 수행 방법을 알아보기 전에, 다양한 샘플 데이터를 확보할 수 있는 방법들을 알아보려고 합니다.  

데이터셋(Datasets) 얻기

머신러닝을 시작할 때, 간단하게 데이터셋을 얻어서 알고리즘을 테스트해 보는 것이 머신러닝을 이해하는데 있어 매우 유용합니다. 간단한 데이터셋으로 원리를 이해한 후, 실제 생활에서 얻을 수 있는 더 큰 데이터셋을 가지고 작업하는 것이 좋습니다.

우선 머신러닝을 연습하기 위해, 간단한 데이터셋을 얻을 수 있는 곳은 다음과 같습니다. 하나씩 차례대로 알아보도록 하겠습니다.

  • 사이킷런의 빌트인 데이터셋
  • 캐글(Kaggle) 데이터셋
  • UCI(캘리포니아 대학, 얼바인) 머신러닝 저장소

<사이킷런 데이터셋 사용하기>

사이킷런에는 머신러닝을 쉽게 배울 수 있도록 하기 위해, 샘플 데이터셋을 가지고 있습니다. 

샘플 데이터셋을 로드하기 위해, 데이터셋 모듈을 읽어들입니다. 다음은 Iris 데이터셋을 로드한 코드입니다.

>>> from sklearn import datasets
>>> iris = datasets.load_iris() # 아이리스 꽃 데이터셋 또는 피셔 아이리스 데이터셋은 영국의 통계 학자이자 생물학자인 로널드 피셔 (Ronald Fisher)가 소개한 다변수 데이터셋입니다. 데이터셋은 3종의 아이리스(Iris)로 된 50개 샘플로 구성되어 있습니다. 각 샘플로부터 4개의 피쳐(features:피쳐를 우리말로 변수 또는 요인이라고 표현하기도 함)를 측정할 수 있습니다: 꽃받침과 꽃잎의 길이와 너비입니다. 이러한 4가지 피쳐(features)의 결합을 바탕으로 피셔는 종을 서로 구분할 수 있는 선형 판별 모델을 개발했습니다. 

로드된 데이터셋은 속성-스타일 접근을 제공하는 파이썬 딕셔너리, 번치(bunch) 객체로 표현됩니다. 

>>> print(iris.DESCR) # DESCR 속성을 사용해 데이터셋의 정보를 다음과 같이 얻을 수 있습니다.

>>> print(iris.data) # data 속성을 사용해 피쳐를 알아볼 수 있습니다. 

>>> print(iris.feature_names) # feature_names 속성으로 피쳐 이름을 알아낼 수 있습니다.

이것은 데이터셋이 꽃받침 길이, 꽃받침 너비, 꽃잎 길이, 꽃잎 너비 등 4개의 컬럼들로 구성되어 있다는 것을 의미합니다.

꽃의 꽃잎(petal)과 꽃받침(sepal)

>>> print(iris.target) # 레이블을 알 수 있습니다.

>>> print(iris.target_names) # 레이블 이름을 알 수 있습니다.

여기서 0은 'setosa'를, 1은 'versicolor'를 2는 'virginica'를 나타냅니다.

(사이킷런의 모든 샘플 데이터가 feature_names, target_names 속성을 지원하는 것은 아닙니다)

여기서, 데이터를 쉽게 다루기 위해, 판다스(Pandas)의 데이터프레임으로 변환하는 것이 유용합니다.

>>> import pandas as pd # pandas 라이브러리를 읽어들입니다.
>>> df = pd.DataFrame(iris.data) 
>>> df.head()

<캐글(Kaggle) 데이터셋 사용하기>

 데이터 과학자 및 머신러닝 학습자들에게 있어, 캐글(Kaggle)은 세계에서 가장 큰 커뮤니티입니다.

머신러닝 경쟁을 제공하는 플랫폼에서 시작하여, 현재 캐글(Kaggle)은 공개 데이터 플랫폼과 데이터 과학자를 위한 클라우드 기반 워크 벤치도 제공합니다.

구글이 2017년 3월에 캐글(Kaggle)을 인수했습니다. 

우리는 머신러닝 학습자들을 위해, 캐글(Kaggle)에서 제공된 샘플 데이터셋을 이용할 수 있습니다.

몇가지 흥미로운 데이터셋이 있는데, 다음과 같습니다.

<캘리포니아 대학, 어바인의 머신러닝 저장소 사용하기>

캘리포니아 대학, 어바인의 머신러닝 저장소는 머신러닝 알고리즘의 데이터 생성 경험적 분석을 위해, 머신러닝 커뮤니티에서 사용하는 데이터베이스, 도메인 이론 및 데이터 생성기 모음입니다.

이 거대한 데이터셋 모음 중에서 흥미로운 몇가지 데이터셋을 살펴보면 다음과 같습니다.

< 직접 자신의 데이터셋 생성하기>

실험을 위한 적당한 데이터셋을 찾을 수가 없다면, 직접 자신의 데이터셋을 생성합니다.

사이킷런(Scikit-learn) 라이브러리의 sklearn.datasets.samples_generator 모듈에는 다양한 유형의 문제에 대해 서로 다른 유형의 데이터 세트를 생성할 수 있는 많은 함수가 포함되어 있습니다.

다음과 같은 데이터셋들을 만들 수 있습니다.

  • 선형으로 분산된 데이터셋
  • 군집화된 데이터셋
  • 순환 방식으로 분산되고 군집화된 데이터셋

1. 선형으로 분산된 데이터셋

make_regression() 함수를 사용해 선형으로 분산된 데이타를 생성합니다. 아웃풋에 적용된 가우스 노이즈의 표준 편차뿐만 아니라, 원하는 피쳐의 수를 지정할 수도 있습니다.

>>> % matplolib inline
>>> import matplotlib.pyplot as plt
>>> from sklearn.datasets.samples_generator import make_regression
>>> X, y = make_regression(n_samples=100, n_features=1, noise=5.4)
>>> plt.scatter(X, y)

2. 군집화된 데이터셋

make_blobs()함수는 n개의 무작위 데이터 클러스터를 생성합니다. 이것은 비지도(자율)학습에서 군집화를 수행할 때 매우 유용합니다.

>>> %matplotlib inline
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from sklearn.datasets import make_blobs
>>> X, y = make_blobs(500, centers=3) # 군집화를 위한 등방성 가우시안 블롭 생성
>>> rgb = np.array(['r', 'g', 'b'])
>>> plt.scatter(X[:, 0], X[:, 1], color=rgb[y]) # 산포도와 컬러 코딩을 사용해 그립니다.

3. 순환 방식으로 분산되고 군집화된 데이터셋

make_circles()함수는 두 개의 차원에 작은 원을 포함하는 큰 원이 포함된 임의의 데이터셋을 생성합니다. SVM(

Support Vector Machines)과 같은 알고리즘을 사용하여 분류(classifications)를 수행할 때 유용합니다.

>>> %matplotlib inline
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from sklearn.datasets import make_circles
>>> X, y = make_circles(n_samples=100, noise=0.09)
>>> rgb = np.array(['r', 'g', 'b'])
>>> plt.scatter(X[:, 0], X[:, 1], color=rgb[y])

다음 번에는 간단한 선형 회귀(linear regression) 알고리즘을 구현해 보면서 사이킷런(Scikit-Learn) 기초 사용법을 익혀 보겠습니다.

 

(Source : Python Machine Learning, Wiley, 2019)

 

반응형

+ Recent posts