ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 데이터 사이언스: 좋은 데이터란? 데이터 클리닝(Data clearing)공부하기!
    데이터 사이언스 2020. 8. 2. 01:31

    출처: 미소 가사도우미

     

     

     

    데이터를 올바르고 효율적으로 사용하기 위해서는

     

    좋은 데이터, 즉 퀄리티가 높은 데이터를 사용해야합니다. 

     

    그런데 좋은 데이터란 무엇일까요?

     

    다음과 같은 조건을 만족한다면 좋은 데이터라고 할 수 있습니다. 

     

     

     

    → 완결성

     

    필수적으로 기입되어야 하는 데이터는 모두 입력되어야 합니다.

     

    결측값이 있으면 안됩니다. 

     

     

     

    → 유일성

     

    동일한 데이터가 불필요하게 중복되어 있으면 안됩니다. 

     

    예를 들어, 우리가 어떤 사이트에 가입할때 이메일인증을 하죠? 만약 가입한 사이트라면

     

    이미 등록되어 있는 이메일이라는 메시지가 나올겁니다. 그렇지 않다면 문제가 생길겁니다. 

     

     

     

    → 통일성

     

    모두 동일한 형식으로 저장되어 있어야 합니다.

     

    만약 사람들의 키 데이터가 있을 때 어떤 사람은 m으로, 어떤 사람은 cm로 저장되어 있으면

     

    나중에 문제가 발생하겠죠?

     

     

     

     

     

    예시를 통해서 자세히 알아봅시다. 

     

     

     

    1. 완결성

     

     

    결측값(Nan)이 있는 데이터 입니다. 

     

    import pandas as pd
    import seaborn as sns
    
    attendance_df = pd.read_csv("Downloads/attendance.csv")

     

     

    isnull() 메서드는 결측값이 있다면 True, 그렇지 않다면 False를 출력합니다. 

     

    attendance_df.isnull().sum()

     

    연도      0
    야구      0
    축구      0
    배구      3
    남자농구    0
    여자농구    0
    dtype: int64

     

    "배구" 칼럼에 3개의 Nan 값이 있음을 알 수 있습니다.  

     

     

     

     

    이렇게 Nan 값이 있으면 데이터를 다룰때 문제가 생길겁니다.

     

    예를 들어 년도별 평균을 낸다던가 하면 다른 값들과 차이가 생기겠죠

     

    그래서 이럴때  Nan 값을 가진 행을 지워주는 방법이 있습니다. 

     

    attendance_df.dropna()

     

     

     

     

     

    그리고 이렇게 axis = "columns" 를 이용해서 Nan 있는 칼럼을 지워주는 방법이 있습니다.

     

    attendance_df.dropna(axis = "columns")

     

     

     

     

     

    어떤 값도 지우기 싫다면 중간 값을 넣어줍니다.

     

    Nan 값이 있는 칼럼의 중간 값을 넣어줍니다. 

     

    attendance_df.fillna(attendance_df["배구"].median())
    attendance_df.fillna(attendance_df.median())

    (같은 내용을 출력)

     

     

     

     

     

    만약 중간값 말고 평균 값을 넣어주고 싶다면 이렇게 

     

    attendance_df.fillna(attendance_df.mean())

     

     

     

     

     

     

    2. 유일성

     

     

    중복되는 값이 있을 경우입니다. 

     

    import pandas as pd
    dust_df = pd.read_csv("Downloads/dust.csv",index_col = 0)

     

     

     

     

    이 데이터는 같은 행을 두개나 가지고 있네요

     

    dust_df.index.value_counts()

     

    07월 31일    2
    07월 14일    1
    08월 08일    1
    07월 19일    1
    07월 29일    1
    08월 11일    1
    08월 03일    1
    07월 18일    1
    07월 16일    1
    07월 13일    1
    08월 09일    1
    08월 10일    1
    07월 25일    1
    07월 20일    1
    07월 24일    1
    08월 01일    1
    07월 26일    1
    08월 05일    1
    07월 28일    1
    07월 23일    1
    07월 22일    1
    07월 21일    1
    08월 06일    1
    08월 04일    1
    07월 17일    1
    07월 27일    1
    07월 30일    1
    08월 02일    1
    07월 15일    1
    08월 07일    1
    Name: 날짜, dtype: int64

     

    7월 31일이 두개나 있네요

     

     

     

     

    중복되는 행이 있는경우 drop_duplicate() 메서드로 중복되는 행 하나를 지워줍니다.

     

    dust_df.drop_duplicate(inplace = True)
    dust_df.index.value_counts()

     

    07월 14일    1
    08월 08일    1
    07월 31일    1
    07월 19일    1
    07월 29일    1
    08월 11일    1
    08월 03일    1
    07월 18일    1
    07월 16일    1
    07월 13일    1
    08월 09일    1
    08월 10일    1
    07월 25일    1
    07월 20일    1
    07월 24일    1
    08월 01일    1
    07월 26일    1
    08월 05일    1
    07월 28일    1
    07월 23일    1
    07월 22일    1
    07월 21일    1
    08월 06일    1
    08월 04일    1
    07월 17일    1
    07월 27일    1
    07월 30일    1
    08월 02일    1
    07월 15일    1
    08월 07일    1
    Name: 날짜, dtype: int64

     

    중복되는 행이 지워졌네요?

     

     

     

     

    이번에는 칼럼도 확인해 보겠습니다. 

     

    dust_df.columns.value_counts()

     

    제주      1
    전남      1
    경기      1
    부산      1
    대전      1
    세종      1
    충북      1
    광주      1
    대구      1
    충남      1
    강원      1
    전북      1
    경북      1
    경남      1
    인천      1
    강원.1    1
    울산      1
    서울      1
    dtype: int64

     

     

    "강원.1"이라는 칼럼과 "강원"이 중복이 되네요

     

     

     

     

    drop_duplicate는 중복되는 행만 지워줄 수 있기 때문에 T를 이용합니다.

     

    T를 이용하면 행과 열을 바꿔 줍니다.  

     

    다음과 같이 처음에 T 한번, 마지막에 T를 사용합니다.

     

    dust_df2 = dust_df.T.drop_duplicate().T
    dust_df2.columns.value_counts()

     

    제주    1
    대구    1
    경기    1
    부산    1
    대전    1
    세종    1
    충북    1
    광주    1
    충남    1
    전남    1
    강원    1
    전북    1
    경북    1
    경남    1
    인천    1
    울산    1
    서울    1
    dtype: int64

     

    "강원.1" 칼럼이 없어졌네요. 성공!

     

     

     

     

     

    3. 통일성 

     

     

    데이터는 동일한 데이터형식으로 기록되어 있어야 합니다.

     

    그렇지 않다면 데이터 시각화를 했을 때, 이상점이 있는 경우가 생기죠

     

    종종 부정확한 데이터일 경우 이상점이 두드러지게 나타나는데

     

    보통은 q3 + IQR x 1.5 보다 크고, q1 - IQR x 1.5 보다 작은 범위에 있을 경우

     

    이상점이라고 판단합니다.

     

     

    출처: 네이버 블로그 PANSPACE-팬스페이스

    q1은 25% (하위 일분위), q3는 75% (상위 삼분위)입니다.

     

     

     

     

    다음은 맥주들의 도수를 기록한 데이터입니다. 

     

    import pandas as pd
    beer_df = pd.read_csv("Downloads/beer.csv",index_col = 0)
    
    beer_df.plot(kind = "box", y = "abv")

     

    박스플롯으로 봤을 때 이상점이 아주 두드러집니다.

     

     

     

     

     

    이상점을 구하기 위해 q1, q3, iqr을 구해줍니다.

     

    q1 = beer_df["abv"].quantile(0.25)
    q3 = beer_df["abv"].quantile(0.75)
    iqr = q3 - q1

     

     

     

     

    이상점을 갖는 범위는 다음과 같습니다. 

     

    beer_df[beer_df["abv"] > iqr * 1.5 + q3 | beer_df["abv"] - 1.5 * iqr]

     

     

    963, 1856번은 맥주가 아닌 보드카와 소주라 잘못된 값,

     

    2250번은 abv 0.055로 입력하려다가 실수로 5.5로 입력한것 같네요.

     

     

     

     

     

    올바른 값으로 다시 입력해줍시다.

     

    beer_df.loc[2250, "abv"] = 0.055

     

    condition = (beer_df["abv"] < q1 - iqr * 1.5 )| (beer_df["abv"] > q3 + iqr * 1.5)
    beer_df[condition]

     

     

    다시 이상점을 확인해봤더니 2250번은 이상점으로 나오지 않네요.

     

    제대로 들어간 것 같습니다. 

     

     

     

     

    963, 1856을 데이터에서 완전히 지우고 박스플롯을 확인해봅시다.

     

    beer_df.drop(beer_df[conditoin].index, inplace = True)
    
    beer_df.plot(kind = "box", y = "abv")

     

    이제 박스플롯에 이상점이 보이지 않네요 ㅎㅎ

     

     

     

     

    통일성을 확인하는 또 다른 방법은 

     

    관계적 이상점(Relational outlier)을 확인하는 방법입니다.

     

    두 변수의 관계를 생각했을 때 이상한 데이터를 의미합니다. 

     

     

     

     

    다음은 읽기 데이터와 쓰기 데이터의 관계를 나타낸 산점도입니다. 

     

    import pandas as pd
    import seaborn as sns
    exam_df = pd.read_csv("Downloads/exam_outlier.csv")
    
    exam_df.plot(kind = "scatter", x = "reading score", y = "writing score")

     

    writing score 가 두드러지게 높은 점하나가 있는데 이상하네요. 이상점인것 같습니다. 

     

     

     

     

    exam_df.corr()

     

     

    두 점수간의 상관관계를 확인해보면, 약 0.58정도로 약한 정적 상관관계를 갖네요.

     

     

     

     

    방금 전, 이상점으로 의심된 점을 찾아 지워줍니다.

     

    대략 writing score가 400이상이므로 다음과 같이 찾아 지워줍니다.

     

    condition = exam_df[exam_df["writing score"] > 400]
    
    exam_df.drop(condition.index, inplace = True)

     

     

     

     

    산점도를 확인해본 결과 이상점을 지우기전보다 더 뚜렷한 상관관계를 갖네요

     

    exam_df.plot(kind = "scatter", x = "reading score", y = "writing score")

     

     

    그리고 이상점으로 추정되는 점이 하나 더 보입니다.

     

     

     

     

    마찬가지로 이상점을 지워줍니다.

     

    exam_df[exam_df["reading score"] < 40 & exam_df["writing score"] > 80]

     

     

    exam_df.drop(373, inplace = True)

     

     

     

     

    산점도를 확인해보니 이상점이 깔끔히 지워졌네요

     

    exam_df.plot(kind = "scatter", x = "reading score", y = "writing score")

     

     

    이렇게 이상점으로 추정된 점들을 차례로 지워봤습니다.

     

    확실히 두 점수가 전보다 더 뚜렷한 상관관계를 갖네요

     

     

     

     

    마지막으로 상관계수를 확인해보면 

     

    exam_df.corr()

     

     

    이상점을 지우기전 상관계수는 대략 0.58이였다면

     

    이상점을 지우고난 후는 대략 0.95로 꽤 많이 증가했네요.

    반응형

    댓글

Designed by Tistory.