Home 4C
Post
Cancel

4C

4Cs

Correcting

  • outlying 데이터가 존재할 때, 이것들을 처리하는 과정
  • seaborn의 FacetGrid를 이용하여 outlier의 데이터를 파악하고 처리하는 코드
1
2
3
4
5
6
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.read_csv("train.csv")
graph = sns.FacetGrid(df, col="Survived")
graph.map(plt.hist, "Fare", bins=20)
1
<seaborn.axisgrid.FacetGrid at 0x21a7a654070>

png

  • fare 값이 400보다 큰 데이터는 outlying 하고 있다는 것을 파악할 수 있다.
  • loc 을 이용하여 조건에 맞는 데이터(400보다 큰 데이터)를 필터링하고, 그 데이터를 중앙값으로 업데이트
1
df.loc[df["Fare"] > 400, "Fare"] = df["Fare"].median()

아래와 같이 400보다 큰 데이터는 사라진 것을 확인할 수 있다.

1
2
graph = sns.FacetGrid(df, col="Survived")
graph.map(plt.hist, "Fare", bins=20)
1
<seaborn.axisgrid.FacetGrid at 0x21a7a60dc10>

png

1
2
graph_age = sns.FacetGrid(df, col="Survived")
graph_age.map(plt.hist, "Age", bins=20)
1
<seaborn.axisgrid.FacetGrid at 0x21a4d728c70>

png

1
df.loc[df['Age'] > 70, 'Age'] = 70
1
2
graph_age = sns.FacetGrid(df, col='Survived')
graph_age.map(plt.hist, 'Age', bins=20)
1
<seaborn.axisgrid.FacetGrid at 0x21a4d9c7850>

png

Completing

  • Null value들을 채워넣는 과정
    • ex) age: 그 사람의 나이를 추정하거나 median 값으로 대체
1
2
for column in df:
  print(column, ": ", df[column].isnull().sum()) # null 데이터 개수 column 별로 출력
1
2
3
4
5
6
7
8
9
10
11
12
PassengerId :  0
Survived :  0
Pclass :  0
Name :  0
Sex :  0
Age :  177
SibSp :  0
Parch :  0
Ticket :  0
Fare :  0
Cabin :  687
Embarked :  2
1
2
df['Age'].fillna(df.Age.median(), inplace = True) # inplace: Save changes

1
2
for column in df:
  print(column, ": ", df[column].isnull().sum()) 
1
2
3
4
5
6
7
8
9
10
11
12
PassengerId :  0
Survived :  0
Pclass :  0
Name :  0
Sex :  0
Age :  0
SibSp :  0
Parch :  0
Ticket :  0
Fare :  0
Cabin :  687
Embarked :  2
1
print(df['Embarked'].value_counts()) # number of different values
1
2
3
4
S    644
C    168
Q     77
Name: Embarked, dtype: int64
1
print(df.Pclass.value_counts())
1
2
3
4
3    491
1    216
2    184
Name: Pclass, dtype: int64
1
df.Embarked.fillna("S", inplace=True)
1
del df["Cabin"]
1
2
for column in df:
  print(column, ": ", df[column].isnull().sum()) 
1
2
3
4
5
6
7
8
9
10
11
PassengerId :  0
Survived :  0
Pclass :  0
Name :  0
Sex :  0
Age :  0
SibSp :  0
Parch :  0
Ticket :  0
Fare :  0
Embarked :  0

Creating

  • Feature Engineering
  • 이미 존재하는 특징을 이용하여 새로운 특징을 만들어서 머신러닝 모델의 prediction power를 높여주는 과정
  • 더 작은 수의 카테고리로 만들어 변수를 simplify 해 주는 기능
1
df['Name'].sample(20)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
870                                    Balkic, Mr. Cerin
35                        Holverson, Mr. Alexander Oskar
401                                      Adams, Mr. John
168                                  Baumann, Mr. John D
207                          Albimona, Mr. Nassef Cassem
252                            Stead, Mr. William Thomas
199               Yrois, Miss. Henriette ("Mrs Harbeck")
454                                  Peduzzi, Mr. Joseph
298                                Saalfeld, Mr. Adolphe
529                          Hocking, Mr. Richard George
670    Brown, Mrs. Thomas William Solomon (Elizabeth ...
451                      Hagland, Mr. Ingvald Olai Olsen
59                    Goodwin, Master. William Frederick
886                                Montvila, Rev. Juozas
47                             O'Driscoll, Miss. Bridget
738                                   Ivanoff, Mr. Kanio
185                                Rood, Mr. Hugh Roscoe
412                               Minahan, Miss. Daisy E
94                                     Coxon, Mr. Daniel
646                                    Cor, Mr. Liudevit
Name: Name, dtype: object

위에서 Mr, Mrs, Miss 등과 같이 이름이 아닌데 이름 앞에 붙는 title을 따로 떼어내는 과정을 진행

1
2
3
4
5
def get_title(name):
  if "." in name:
    return name.split(',')[1].split(".")[0].strip()
  else:
    return "No title in name"
1
2
titles = set([x for x in df['Name'].map(get_title)]) # functional programming
# titles = set([x for x in df.Name.map(lambda x: get_title(x))])
1
print(titles)
1
{'Major', 'the Countess', 'Lady', 'Ms', 'Jonkheer', 'Master', 'Don', 'Rev', 'Col', 'Dr', 'Sir', 'Mme', 'Capt', 'Mr', 'Mlle', 'Mrs', 'Miss'}
1
2
3
4
5
6
7
8
9
10
11
12
def shorter_titles(x):
    title = x["Title"]
    if title in ["Capt", "Col", "Major"]:
        return "Officer"
    elif title in ["Jonkheer","Don","the Countess","Dona","Lady",'Str']:
        return "Royalty"
    elif title == "Mme":
        return "Mrs"
    elif title in ["Mlle", "Ms"]:
        return "Miss"
    else:
        return title
1
df['Title'] = df['Name'].map(get_title) # df에 Title column 자동 생성

apply

  • Series(1차원) 및 Dataframe(2차원) 타입의 객체에서 호출 가능
  • 행 혹은 열 전체의 원소에 원하는 연산 적용
  • axis를 통해 사라질 출 지정
    • axis = 0: 행은 사라지고 열 단위로 집계
    • axis = 1: 열은 사라지고 행 단위로 집계

아래는 Title 열을 기준으로 각각의 행 단위의 데이터에 적용하는 코드

1
df['Title'] = df.apply(shorter_titles, axis=1)

참고사항

map과 apply 함수 차이

  • map 함수는 단일 column 데이터에 적용가능
  • apply 함수는 단일 및 다중 column 데이터에 적용가능

결과는 아래와 같다.

1
print(df.Title.value_counts())
1
2
3
4
5
6
7
8
9
10
Mr         517
Miss       185
Mrs        126
Master      40
Dr           7
Rev          6
Officer      5
Royalty      4
Sir          1
Name: Title, dtype: int64
1
df.drop("Name", axis=1, inplace=True)

name이 사라진 것을 확인할 수 있다.

1
df.sample(20)
PassengerIdSurvivedPclassSexAgeSibSpParchTicketFareEmbarkedTitle
82182213male27.0003150988.6625SMr
66066111male50.020PC 17611133.6500SDr
68268303male20.00065639.2250SMr
53353413female28.002266822.3583CMrs
11912003female2.04234708231.2750SMiss
63363401male28.0001120520.0000SMr
51751803male28.00037111024.1500QMr
5603male28.0003308778.4583QMr
47847903male22.0003500607.5208SMr
76076103male28.00035858514.5000SMr
55655711female48.0101175539.6000CRoyalty
30730811female17.010PC 17758108.9000CMrs
36836913female28.000143137.7500QMiss
87787803male19.0003492127.8958SMr
21021103male24.000SOTON/O.Q. 31013117.0500SMr
31731802male54.0002901114.0000SDr
67867903female43.016CA 214446.9000SMrs
78378403male28.012W./C. 660723.4500SMr
85585613female18.0013920919.3500SMrs
58258302male54.0002840326.0000SMr

Converting

  • 컴퓨터가 학습하기 위해서 데이터들을 모두 “Numerical”한 숫자로 표현하는 과정
    • ex) male = 0, female = 1
1
df.Sex.replace(('male', 'female'), (0,1), inplace = True) # 순서는 중요하지 않은 변수
1
df.Embarked.value_counts()
1
2
3
4
S    646
C    168
Q     77
Name: Embarked, dtype: int64
1
df.Embarked.replace(('S','C','Q'), (0,1,2), inplace = True)
1
df.Title.replace(('Mr','Miss','Mrs','Master','Dr','Rev','Officer','Royalty','Sir'), (0,1,2,3,4,5,6,7,8), inplace=True)
1
df.sample(20)
PassengerIdSurvivedPclassSexAgeSibSpParchTicketFareEmbarkedTitle
55155202027.00024435826.000000
565712121.000C.A. 3102610.500001
66466513020.010STON/O 2. 31012857.925000
63964003028.01037656416.100000
50450511116.00011015286.500001
79980003130.01134577324.150002
83783803028.0003920928.050000
36036103040.01434708827.900000
46746801056.00011379226.550000
48348413163.00041349.587502
83683703021.0003150978.662500
676803019.000S.P. 34648.158300
80880902039.00024872313.000000
23423502024.000C.A. 2956610.500000
51451503024.0003492097.495800
56957013032.0003504177.854200
55555601062.00011380726.550000
21521611131.01035273113.275011
32232312130.00023481812.350021
50650712133.0022636026.000002