나중에 요긴하게 쓰일 수 있도록 내가 작성한 프로젝트를 토대로 내용을 잘 정리해보겠다.
파이썬으로 특정 데이터로 머신러닝 실습을 진행하기 위해서는 데이터를 컴퓨터가 학습할 수 있는 형태로 다듬어야 한다. 데이터를 깔끔하게 다듬는 것이 머신러닝의 시작이다.
목표: 데이터를 불러와 데이터 다듬기
순서:
1. 데이터파일 불러오기
2. 필요없는 칼럼 없애기
3. 빠진 데이터 찾아 채워 넣기
4. 전처리((preprocessing) - 텍스트를 숫자로 변경
5. 정규화(nomalization) - feature값을 0~1사이의 값으로 만들어주기
1. 데이터파일 불러오기
- 보통의 데이터는 csv파일이나 엑셀파일로 되어있다. 이를 pandas 모듈을 이용해서 불러온다.
* pandas가 설치 안되어있으면 설치해야함.. 이건 다른 글 참고..
import pandas as pd
# 엑셀일땐 read_excel
df = pd.read_excel('assembly_data.xlsx', header = 4, usecols='B:R')
# csv일땐 read_csv
df = pd.read_csv('final_assembly.csv', encoding='utf-8')
read_excel parameter
- header: header로 지정할 행 번호, 쉽게 말해서 여기부터 파일을 읽어온다.
- usecols: 사용할 열의 범위를 지정
read_csv parameter
- encoding: 인코딩 방식
2. 필요없는 칼럼 없애기
원하는 범위만큼 데이터를 가져왔는데, 그 안에 필요없는 칼럼(column, 열)이 있을 수 있다.
예를 들어 칼럼이 텅 비었거나, 다 동일한 값을 가지고 있다면 굳이 학습에 넣어줄 필요가 없다.
이러한 칼럼을 제거해주는 과정이 필요하다.
df = df.drop(columns=['Weight','PCG명','착수','완료'])
방법은 위와 같이 간단하다. drop 함수를 쓰고 그 안에 colums를 리스트형태로 작성하면 된다. 각 원소는 칼럼의 이름이 들어간다. 아니 근데 특정 칼럼이 텅 비었거나, 다 동일한 값을 가지고 있는지 어떻게 알것인가?
수 천개의 데이터를 일일이 스크롤을 내려 확인해도 좋지만 매우 피곤할 것이다.
쉽게 알아내는 방법이 다 있다.
- 칼럼 전체가 비어있는지 여부
우선 데이터가 비어있는지는 아래와 같이 info() 메소드를 쓰면 된다.
print(df.info())
전체 데이터 행 개수가 나오고 각 칼럼에 대한 정보가 나오는데 이때 non-null 데이터 개수가 0이면 그 칼럼은 다 비어있다는 뜻이다. 이런 칼럼이 있다면 칼럼 이름을 기억해두었다가 drop 시키면 된다. 주의할 점은 위와 같이 4284개인 칼럼은 어쨌든 데이터가 있으니 지우면 안된다. 이따 나올 파트에서 빈 공간에 값을 채워 넣어주는 작업을 할 것이다.
- 칼럼 내 데이터가 오직 1개
칼럼 내 데이터의 종류가 1개인지 아는 방법은 아래와 같이 sklearn의 LabelEncoder()를 써주면 된다.
원하는 데이터를 fit시키고 le.classes_를 써주면 어떤 항목들이 있는지 출력된다. 여기서 항목이 하나면 이 칼럼은 지워줘도 되는 칼럼인 것이다.
>> from sklearn import preprocessing
>> le = preprocessing.LabelEncoder()
>> le.fit([1,2,2,3,3,3,4,4])
>> print(le.classes_)
[1,2,3,4]
3. 빠진 데이터 찾아 채워 넣기
이제 필요없는 칼럼들은 다 정리를 했고, 나머지 칼럼들을 다듬어야 한다.
먼저 여백이 있는 데이터, 즉 손실데이터가 있으면 컴퓨터의 학습이 제대로 이루어지지 않기때문에
이 부분에 적절한 값을 채워넣어야 한다.
위에서 df.info()로 공백이 있는 칼럼들을 일단 찾고, 그 칼럼 들에 대해 다음과 같이 fillna를 써주면 된다.
나 같은 경우는 문자로 이루어진 칼럼 속의 공백은 'NULL'로 채우고, 숫자 칼럼은 평균을 구해서 채웠다.
df = df.fillna({"Ass'y":'NULL'}) # fill in data with text
df = df.fillna({'길이(L)':round(df['길이(L)'].mean(),1)}) # fill in data with number
4. 전처리((preprocessing) - 텍스트를 숫자로 변경
이제 그럼 데이터에 여백은 없어지도록 만들었다. 근데 어떤 칼럼은 문자로, 어떤 칼럼은 숫자로 이루어져 있으면 이 역시 학습이 제대로 되지 않는다. 기본적으로 숫자 계산을 통해서 학습이 이루어지는 것이기 때문에 문자 데이터를 전부 숫자데이터로 바꾸는 과정이 필요하다.
방법은 LabelEncoder를 사용하면 된다. fit과 transform을 합친 fit_transform을 쓰면 다음과 같이 손쉽게 바꿀수 있다.
인코더가 문자 데이터를 저절로 1,2,3 .. 같은 정수 형태의 숫자로 바꿔준다.
le = preprocessing.LabelEncoder()
df['팀'] = le.fit_transform(df['팀'])
df['세부공정'] = le.fit_transform(df['세부공정'])
df['선종'] = le.fit_transform(df['선종'])
5. 정규화(nomalization) - feature값을 0~1사이의 값으로 만들어주기
마지막 데이터 다듬기는 정규화로, feature값의 스케일을 통일시켜주는 것이다.
어떤 칼럼은 0.1, 0.12, 0.2, 0.35 이러한 값들을 가지는 반면
다른 칼럼은 10000, 23000, 42200과 같은 값들을 가진다면
두 칼럼 사이의 스케일이 너무 달라 학습이 제대로 되지 않을 것이다.
위의 경우라면 위의 칼럼은 아래 칼럼에게 먹히기 쉽다. 즉 위의 칼럼의 특징들이 학습에 잘 반영되지 못할 것이다.
스케일링 방법은 다양하고 검색을 통해 이미 만들어져있는 스케일러도 쉽게 쓸 수 있지만
나는 minmax scaler를 직접 함수로 작성하였다. 이 스케일러는 최솟값을 0, 최댓값을 1로 스케일링해준다.
찾아보면 이외에도 평균과 표준편차를 사용하는 StandardScaler 등등이 존재한다.
* Label에 해당하는 칼럼은 굳이 스케일링 해줄 필요없다.
# normalize
def normalize(x):
return (x - min(x)) / (max(x)-min(x))
# scaling features
for i in range(len(df.columns)-2):
col = df.columns[i]
df[col] = normalize(df[col])
위의 과정을 모두 마치면 드디어 데이터가 머신러닝으로 학습가능한 형태로 잘 다듬어 진 것이다.
손실데이터가 없으며 모든 데이터가 숫자데이터고 0과 1 사이의 값을 가지는 아주 잘 다듬어진 형태.
이제 학습 모델을 잘 만들어서 모델에 이 데이터를 잘 넣어주기만 하면 된다.
댓글