31 Oct 2018
|
python
전처리
데이터 전처리
나중에 데이터를 탐색하거나, 데이터를 프로세싱을 진행할 때 편하도록 전처리를 진행한다. 여기에서는 데이터 값 중 같은 항목을 하나의 이름으로 통일시키고, 불필요하게 긴 데이터를 짧게 줄였다.
확장자명 통일
.value_counts()
.replace(dict)
- 미리 지정해둔 값으로 교체
- 바꾸고 싶은 값만 dict으로 지정하여 교체할 수 있음
df.ext.value_counts()
# PDF 82004
# DOCX 58303
# XLSX 52118
# HWP 26244
# DOC 24586
# XLS 24489
# PPTX 15385
# TXT 9814
# PPT 5382
# PPSX 2374
# ODT 820
# PPS 324
# JPG 9
# SHEET 5
# WORD 2
# PNG 2
# Name: ext, dtype: int64
ext_dic = {'DOCX': 'DOC',
'XLSX': 'XLS',
'PPTX': 'PPT',
'PPSX': 'PPT',
'PPS': 'PPT',
'ODT': 'TXT',
'PNG': 'JPG'
}
df['ext'] = df['ext'].replace(ext_dic)
df.ext.value_counts()
# DOC 82889
# PDF 82004
# XLS 76607
# HWP 26244
# PPT 23465
# TXT 10634
# JPG 11
# SHEET 5
# WORD 2
# Name: ext, dtype: int64
신규 session_id 부여
필수는 아니나, 계산량 감소를 위해 텍스트 사이즈 감량 진행
DataFrame.ix[]
- 데이터프레임의 정보를 인덱스로 호출 하는 속성값
- [_] 내부 인자로 숫자와 함께 칼럼명 같이 사용이 가능함
DataFrame.loc[]
, DataFrame.iloc[]
와 같은 indexer이지만, 숫자와 칼럼명같이 쓰는데에 유용함.
- 한 행씩 돌면서 값에 처리를 할 때 유용함
.ix is exceptionally useful when dealing with mixed positional and label based hierarchical indexes.
pandas 0.23.4 documentation
s = [] # empty list
j = 0 # default setting
# loop
for i in range(len(df)-1):
if df.ix[i, 'sessionid'] == df.ix[i+1, 'sessionid']:
s.append(j)
else:
s.append(j)
j += 1
31 Oct 2018
|
python
missing value
prediction
머신러닝
결측값에 예측모형으로 예측치 넣기
결측치를 다루는 방법 중 적절성은 비교적 높으나 별도의 모형과 계산량이 필요하다.
1. 데이터 준비
sklearn
(사이킷런)을 이용함
ind_cols
- 예측하고 싶은 값에 영향을 주는 요소 중 서로 독립적인 칼럼명만 넣어둔다.
- train, test, predict 데이터 x 값에 바로 넣기 편하다.
- DS school에서 배울 때에는 상관도를 이용하여 영향 없는 칼럼을 골랐었다.
# fill na using predictive model
# train without na
df_msl = df_ms.dropna()
# set independent cols <-- 서로 영향 없는 칼럼만 고르기
ind_cols = ['actiontype', 'ismydoc', 'ext', 'screen']
#split ind, tar --> 학습시키고 싶은 칼럼과 인풋 칼럼 나누기
x = df_msl[ind_cols]
y = df_msl[['documentposition']]
2. 항목값 전처리 - Label Encoder
Label Encoder는 독립 변수가 아닌 종속 변수(라벨)에 대해 사용한다. 문자열이나 정수로된 라벨 값을 0 ~ K−1 까지의 정수로 변환한다. 변환된 규칙은 classes_
속성에서 확인할 수 있다. 예측 결과에 적용할 수 있도록 역변환을 위한 inverse_transform
메서드도 지원한다. 출처
인코딩이란?
인코딩은 카테고리 값이나 텍스트 정보를 처리가 쉬운 정수로 변환하는 과정이다.
예전에 배웠을 때에는 ‘One-Hot-Encoder’를 사용했었음
One-Hot-Encoding은 항목형 데이터를 해당 항목 칼럼을 만들고 해당하는 값에만 정수 1을 넣어주는 방식이다. 참고
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
X = x.apply(lambda x: encoder.fit_transform(x))
y = y.apply(lambda y: encoder.fit_transform(y))
# .inverse_transform()를 이용해서 역방향도 가능하다.
3. 훈련데이터와 평가데이터 추출하기
train_test_split
는 데이터의 표본을 무작위로 추출해 훈련 데이터와 평가 데이터로 나눈다.
이때 random_state
속성값을 이용해서 적절히 섞은 곳에서 추출할 수 있다. (그냥 하는 경우 정렬되어 있거나 할 때 그 비율에 맞춰 추출될 가능성이 있는 것 같음 - 자세히 찾아봐라)
참고
from sklearn.model_selection import train_test_split
# X: df_ms_ind / y: df_ms_tar
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=10)
4. 학습모형 만들기 - KNN Algorithm
k-최근접 이웃 알고리즘(또는 줄여서 k-NN)은 분류나 회귀에 사용되는 비모수 방식이다. 특정한 공간내(X 값에 따라 결정) 내 k개의 가장 가까운 훈련 데이터를 가지고 해당 값을 예측하는 모델
- k-NN 분류에서 출력은 소속된 항목이다. 객체는 k개의 최근접 이웃 사이에서 가장 공통적인 항목에 할당되는 객체로 과반수 의결에 의해 분류된다(k는 양의 정수이며 통상적으로 작은 수). 만약 k = 1 이라면 객체는 단순히 하나의 최근접 이웃의 항목에 할당된다.
- k-NN 회귀에서 출력은 객체의 특성 값이다. 이 값은 k개의 최근접 이웃이 가진 값의 평균이다.
검증 표본(초록색 원)은 첫 번째 파랑 네모의 항목이나 빨강 삼각형의 두 번째 항목으로 분류되어야 한다. 만약 “k = 3” (실선으로 그려진 원)이면 두 번째 항목으로 할당되어야 한다. 왜냐하면 2개의 삼각형과 1개의 사각형만이 안쪽 원 안에 있기 때문이다. 만약 “k = 5” (점선으로 그려진 원)이면 첫 번째 항목으로 분류되어야 한다. (바깥쪽 원 안에 있는 3개의 사각형 vs. 2개의 삼각형)
참고
텐서플로우 knn
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5).fit(X_train, y_train)
5. 학습모형 평가하기 - Score
- 학습을 통해 만들어진 예측 모형에 평가 데이터를 넣어 실제값과 얼마나 유사하게 예측하는지 평가한다.
- 즉, X를 넣어 나온 predicted Y가 넣어준 Y와 맞는지 확인
- 즉, 스코어는 해당 모델의 예측 정확도를 확인할 수 있음
print(knn.score(X_test, y_test))
6. 학습모형 평가하기 - 분류 성능 평가(sklearn.metrics
)
분류 문제는 회귀 분석과 달리 다양한 성능 평가 기준이 필요하다.
- 분류 결과표
Confusion Matrix
- 분류 결과표는 타겟의 원래 클래스와 모형이 예측한 클래스가 일치하는지는 갯수로 센 결과이다.
- 원래 클래스는 행(row)으로 예측한 클래스는 열(column)로 나타낸다.
- 이진 분류 결과표
Binary Confusion Matrix
- 클래스가 0과 1 두 종류 밖에 없는 경우에는 일반적으로 클래스 이름을 “Positive”와 “Negative”로 표시한다.
- 또, 분류 모형의 예측 결과가 맞은 경우, 즉 Positive를 Positive라고 예측하거나 Negative를 Negative라고 예측한 경우에는 “True”라고 하고 예측 결과가 틀린 경우, 즉 Positive를 Negative라고 예측하거나 Negative를 Positive라고 예측한 경우에는 “False”라고 한다.
- 통계에서 1종 오류, 2종 오류 확인하는 것과 비슷하다
- 정보
- precision(정밀도) : 전체 중에 잘 맞게 들어간 비율
- recall(재현도) : 진짜 중에 진짜라고 분류된 것 비율
- Fall-Out (위양성율) : 가짜 중에 진짜라고 분류된 것 비율
- f1-score : precision(정밀도)와 recall(재현도)을 함께 고려한 값
- support : 그 값으로 예측된 항목 수
#행열에서 대각선 부분 외에는 잘 못 예측한것임
from sklearn.metrics import confusion_matrix
print(confusion_matrix(y_test, knn_pred))
# [[ 4733 0 0 0 3 0 0]
# [ 2 13895 0 0 0 0 0]
# [ 0 0 1920 0 3 0 0]
# [ 0 0 2 1085 0 0 0]
# [ 1 0 1 0 53383 0 0]
# [ 0 1 0 0 0 413 0]
# [ 0 3 0 0 0 0 19]]
from sklearn.metrics import classification_report
print(classification_report(y_test, knn_pred))
# precision recall f1-score support
#
# 0 1.00 1.00 1.00 4736
# 1 1.00 1.00 1.00 13897
# 2 1.00 1.00 1.00 1923
# 3 1.00 1.00 1.00 1087
# 4 1.00 1.00 1.00 53385
# 5 1.00 1.00 1.00 414
# 6 1.00 0.86 0.93 22
#
# avg / total 1.00 1.00 1.00 75464
7. 결측값에 예측치 채워 넣기
# 인코딩에서 숫자로 변환되었던 항목값
class_cd = pd.Series(encoder.classes_).to_dict()
# 결측치가 하나 이상 있는 Case만 선택
df_ms_only = df_ms[df_ms.isna().any(axis=1)]
# 결측치가 없는 Case만 선택
df_ms_dropna = df_ms.dropna()
# 평가에 필요한 칼럼만 뽑으면서, 동시에 인코딩 진행
df_ms_only[ind_cols].apply(lambda x: encoder.fit_transform(x))
# 학습모형에 집어 넣어 값 예측하기
knn.predict(df_ms_only[ind_cols].apply(lambda x: encoder.fit_transform(x)))
# 예측값 저장하기
fill_na_values = knn.predict(df_ms_only[ind_cols].apply(lambda x: encoder.fit_transform(x)))
# 결측치가 있는 곳에 예측값 집어 넣기
df_ms_only['documentposition'] = fill_na_values
# 인코딩된 칼럼값을 되돌리기
df_ms_only['documentposition'] = df_ms_only['documentposition'].replace(class_cd)
#원래 데이터에 합치기
df_ms_final = pd.concat([df_ms_dropna, df_ms_only], axis=0)
31 Oct 2018
|
python
missing value
결측치 처리(Missing Value)
결측치를 어떻게 처리할 것인가는 결측치의 수량, 데이터 타입, 그리고 결측값의 원인에 따라 다르다. 전체 샘플의 수가 많다면 상대적으로 적은 결측값을 버릴 수도 있고, 데이터의 타입이 연속되어 있는 시간이라면 앞뒤 중간 값을 넣을 수 있다. 데이터를 합치면서 새로운 데이터를 만드는 경우, 예를 들어 결제 내역 로그를 바탕으로 일별 결제건수를 정리한다면 결제건수 중 결측값이 있는 곳은 결제 내역이 없는 즉 0개의 결제가 일어난 날로 보고 0으로 결측값을 채워 넣기도 한다. 또한 결측값을 채워 넣을 정보가 없는 경우, 결측값이 없는 데이터들을 바탕으로 결측값을 모델링을 통해 예측하여 넣을 수 있다.
dropna()
- 샘플수가 많다면 missing values 를 포함하는 행을 모두 삭제하는 것이 가능함
# 결측치가 하나라도 있으면 버리는 코드 예제
df.dropna()
# 모든 값이 Null일 경우만 버리는 코드 예제
df.dropna(how='all')
# 결측치가 두개 이상인 경우 버리는 코드 예제
df.dropna(thresh=2)
# 해당 column의 결측치가 있는 것을 선택하여 버리는 코드 예제
df.dropna(subset=['name', 'born'])
# 결측치가 하나 이상 있는 Case만 선택하는 코드 예제
df[df.isnull().any(axis=1)]
fillna()
- 샘플수가 충분하지 않을 경우, 이 명령어를 이용해 Null값을 채우는 것이 가능하다.
- 연속형인 경우 Mean값이나 Median을 이용하고, 명목형인 경우 Mode(최빈치)를 이용한다.
- 결측값이 없는 데이터를 이용해 예측 모형을 만들어 Null 값을 채워 넣을 수 있다.
# frequency table - 가장 빈도가 높은 것부터 차근차근 나온다
df_ms.documentposition.value_counts()
# OTHERAPP 213775
# MYPOLARISDRIVE 55518
# LOCALSTORAGE 18922
# NEWDOCUMENT 7612
# NONE 4335
# OTHERCLOUD 1617
# SHAREDDOCUMENT 76
# Name: documentposition, dtype: int64
# fillna with most frequent value (MODE)
freq_values = df_ms.documentposition.value_counts().index[0]
df_ms['documentposition'] = df_ms['documentposition'].fillna(freq_values)
31 Oct 2018
|
python
datetime
날짜 데이터 다루기
데이터 분석시 날짜 데이터를 활용하면 편하게 시간에 따른 추이 분석이 가능하다. 요일별, 날짜별, 월별, 년도별 그리고 시간별까지 쪼개어 트렌드를 살펴볼 수 있다. 그 중 유의미한 시간기준이 무엇인지 찾는 것이 시간 데이터를 다뤄 얻어내야 할 목표이다.
pandas.to_datetime()
: 날짜 데이터로 변경 참고
- Pandas Datetime API
.dt.year
.dt.month
.dt.date
.dt.day
.dt.dayofweek
: 0-Monday, 6-Sunday
df["datetime"] = pd.to_datetime(df["datetime"])
df.info()
# <class 'pandas.core.frame.DataFrame'>
# Int64Index: 301861 entries, 0 to 301860
# Data columns (total 7 columns):
# actiontype 301861 non-null object
# ismydoc 301861 non-null object
# ext 301861 non-null object
# sessionid 301861 non-null object
# documentposition 301861 non-null object
# datetime 301861 non-null datetime64[ns]
# screen 301861 non-null object
# dtypes: datetime64[ns](1), object(6)
# memory usage: 18.4+ MB
df["datetime"].dt.month[:5]
# 0 7
# 1 7
# 2 7
# 3 7
# 4 7
df["datetime"].dt.day[:5]
# 0 18
# 1 18
# 2 18
# 3 18
# 4 6
- 날짜데이터 다룰 때 유용한
.groupby()
- gropyby 해서 나온 결과를 dataframe으로 바꾸고 싶을 때
pandas.DataFrame()
: index가 gruopby의 기준 칼럼 값이 된다.
pd.DataFrame().reset_index()
: index에 0부터 넣고, 기준 칼럼이 하나의 칼럼으로 들어가게 한다.
# 날짜별 날짜의 갯수를 확인하는 코드
df.groupby('datetime').size()
# 날짜별로 세션 수를 계산하는 코드
df.groupby("datetime")['sessionid'].nunique()
# groupby로 나온 결과의 index를 칼럼으로 넣고, index에는 정수를 넣는 코드
pd.DataFrame({'counts': df.groupby('datetime').size()}).reset_index()