프로그래밍 공부

파이썬 5일차

3452 2025. 5. 13. 17:51

다변량 시각화

 

산점도

 

plt.figure(figsize=(16,8))

# price와 duration의 산점도 그리기
plt.scatter(y=df['price'], x=df['duration'])
plt.xlabel('Duration')
plt.ylabel('Price')
plt.show()

 

비행시간과 항공권 가격의 관계를 나타내었다.

산점도는 2개의 연속형 변수의 관계를 보기 위해서 X축과 Y축에 표시하는 점들을 찍어서 만드는 그래프이다.

산점도에 표기되는 점들은 자료들의 관측값을 나타내며, 키와 몸무게와 같은 두 변수 간의 상관관계를 대략적으로 확인할수있다.

 

 

plt.figure(figsize=(16,6))

# "Economy" Class에 대한 price와 duration 간의 산점도 그리기
plt.scatter(y=df_eco['price'], x=df_eco['duration'])
plt.xlabel('Duration')
plt.ylabel('Price')
plt.show()

 

이코노미 클래스만 한정하여 찍은 산점도이다.

 

 

 

히트맵

# numpy 불러오기
import numpy as np

# 상관계수 데이터 만들기
heat = df_eco.corr(numeric_only=True)

# 상관계수로 heatmap 그리기
plt.pcolor(heat)

# X축 항목 정보 표시하기
plt.xticks(np.arange(0.5, len(heat.columns), 1), heat.columns)

# Y축 항목 정보 표시하기
plt.yticks(np.arange(0.5, len(heat.index), 1), heat.index)

# 히트맵 확인을 위한 컬러바 표시하기
plt.colorbar()
plt.show()

히트맵은 여러 카테고리 값의 변화를 한눈에 볼 수 있기 때문에 두 값 또는 각 칼럼 간의 상관관계를 나타낼때 주로 사용한다.

 

상관계수를 색깔로 표현하고 우측의 컬러바를 통해서 값을 알수있다.

 

 

 

seaborn 시각화 라이브러리 활용하기

 

범주형 산점도

# seaborn이 기본 설치되어 있지 않은 작업 환경에서는 아래 줄의 #을 삭제 후 seaborn 설치
# %pip install seaborn

# seaborn 불러오기
import seaborn as sns

#airline 별 price를 class로 구분하여 시각화하기
sns.catplot(y='airline', x='price', col='class', data=df, palette='Set2')

범주형 데이터와 수치형 데이터의 관계를 시각화 할 수 있는 그래프이다.

 

row, col, hue 파라미터를 사용해서 더 많은 범주형 데이터 관계를 확인할 수 있다.

 

 

선형 회귀 모델 그래프

# duration과 price의 회귀선을 빨간색으로 표시해서 시각화하기
sns.lmplot(x='duration', y='price', data=df_eco, line_kws={'color': 'red'})

선형 회귀 모델과 연관 있는 함수로 일반적인 산점도와 함께 직선의 회귀선을 그려주어 특성간의 선형적인 관계를 확인하기 쉬운 그래프이다.

 

 

빈도 그래프

# 항공권 데이터의 빈도를 airline으로 구분하여 class 별로 시각화하기
sns.countplot(x='airline', hue='class', data=df)

범주형 데이터에 대하여 항목별 개수를 세어서 막대 그래프를 그린다.

각 카테고리 값별로 데이터가 얼마나 있는지 표시할 수 있으며, 해당 특성을 구성하고 있는 값을 구분해서 보여준다.

 

 

조인트 그래프

# price와 duration의 관계를 조인트 그래프로 시각화하기
sns.jointplot(x='duration', y='price', data=df_eco)

중앙의 산점도 그래프의 가장자리의 히스토그램을 동시에 그려주는 그래프이다.

데이터의 분포와 상관관계를 한번에 볼 수 있지만 수치형 데이터만 표현할 수 있다.

 

 

히트맵

# 상관계수로 heatmap 그리기
sns.heatmap(df_eco.corr(numeric_only=True), annot=True)

이전과 동일하게 히트맵이고, 더 쉽게 그릴수 있다.

 

 

 

수치형 데이터 정제하기

 

# 판다스 불러오기
import pandas as pd

# 데이터 읽어오기
df = pd.read_csv('Clean_Dataset.csv')

# 지정 인덱스인 첫 번째 칼럼 삭제하기
df.drop([df.columns[0]], axis=1, inplace=True)

초기 세팅

 

# 랜덤하게 결측치 생성하기
# 랜덤과 넘파이 불러오기
import random
import numpy as np

# 같은 결과 출력을 위해 시드 고정하기
random.seed(2023)
np.random.seed(2023)

# 랜덤한 위치에서 결측치 5,000개를 포함한 데이터 df_na 생성하기(결측치 5,000개 생성)
df_na = df.copy()
for i in range(0, 5000) :
  df_na.iloc[random.randint(0, 300152), random.randint(0, 10)] = np.nan

# 결측치 처리 여부 확인을 위한 1번, 3번 인덱스 전체 결측치 처리하기(2개 결측치 생성)
df_na.iloc[1] = np.nan
df_na.iloc[3] = np.nan

기존의 클린데이터의 경우에는 결측치가 없기 때문에 일부러 결측치를 만들어준다.

 

# 데이터 정보 확인하기
df_na.info()

결측치가 반영된 데이터의 모습이다.

 

 

# 결측치 수 확인하기
df_na.isnull().sum(axis=0)

 

각 컬럼 별로 결측치가 발생한 갯수이다.

 

# 데이터 변경에 대비하여 원본 데이터 복사하기
df_na_origin = df_na.copy()

결측치가 반영된 데이터를 복사해둔다.

 

 

결측치 삭제하기

# 결측치를 하나라도 가지는 행 모두 삭제하기
df_na = df_na.dropna()
df_na.info()

결측치를 가지는 모든 행을 삭제했다.

원래 300153개의 데이터가 295192개로 줄었다.

 

# 결측치 삭제하기 전 원래 데이터 가져오기
df_na = df_na_origin.copy()

# 모든 데이터가 결측치인 행만 삭제하기
df_na = df_na.dropna(how='all')
df_na.info()

이번에는 모든 데이터가 결측치인 행만 삭제한다.

아까보다 데이터 손실이 적다.

 

# 결측치 삭제하기 전 원래 데이터 가져오기
df_na = df_na_origin.copy()

# stops와 flight 제거하기
df_na = df_na.drop(['stops', 'flight'], axis=1)
df_na.info()

선택한 컬럼만 삭제하기

 

 

# 결측치를 하나라도 가지는 행 모두 삭제하기
df_na = df_na.dropna()
df_na.info()

결측치를 하나라도 가지는 행 삭제하기

모든 결측치를 가진 행을 삭제하는것과 동일하지만, 컬럼이 2개 없어진 후라 갯수 차이가 난다.

 

 

 

결측치 대체하기

df_na = df_na_origin.copy()

# 칼럼별 평균값으로 결측치 대체하기
df_na = df_na.fillna(df_na.mean(numeric_only=True))
df_na.info()

이번 방법은 결측치를 삭제하지 않고, 대신 평균값을 넣는 방식이다.

이로 인해 데이터 손실은 발생하지 않는다.

 

# 0번 인덱스부터 5개의 데이터를 불러와서 1번, 3번 인덱스 삭제 결과 확인하기
df_na.head()

행에 NaN이 포함되어 있지만 수치형 데이터를 평균치로 채워넣어 사라지지 않았다.

 

df_na = df_na.ffill()
df_na.info()

이 방식은 위와 비슷해보이지만 범주형 데이터도 채워준다.

 

# 0번 인덱스부터 5개의 데이터를 불러와서 1번, 3번 인덱스 삭제 결과 확인하기
df_na.head()

 

아까와는 다르게 수치형 데이터 뿐만 아니라 범주형 데이터도 채워졌다.

 

 

 

이상치 파악하기

 

이상치는 제1사분위보다 -25%보다 작은 값, 제3사분위보다 25% 큰 값을 의미한다.

 

# Z-score를 기준으로 신뢰 수준이 95%인 데이터 확인하기
df[(abs((df['price'] - df['price'].mean(numeric_only=True))/df['price'].std())) > 1.96].head()

위의 코드는 Z-score를 이용하여 신뢰 수준이 95% 이상인 데이터만 확인하는 방법이다

 

 

i번째 데이터에서 전체 평균을 빼고 그 값을 표준편차로 나누는 방식이다.

 

# IQR 기준 이상치 확인하는 함수 만들기
def findOutliers(x, column):

  # 제1사분위수 q1구하기
  q1 = x[column].quantile(0.25)

  # 제3사분위수 q1구하기
  q3 = x[column].quantile(0.75)

   # IQR의 1.5배수 IQR 구하기
  iqr = 1.5 * (q3 - q1)

   # 제3사분위수에서 IQR의 1.5배보다 크거나 제1사분위수에서 IQR의 1.5배보다 작은 값만 저장한 데이터 y 만들기
  y = x[(x[column] > (q3 + iqr)) | (x[column] < (q1 - iqr))]

   # IQR 기준 이상치 y 반환하기
  return len(y)

이 코드는 IQR을 기준으로 이상치에 해당하는 값들을 반환하는 함수이다.

 

# price, duration, days_left에 대하여 IQR 기준 이상치 개수 확인하기
print('price IQR Outliers :',findOutliers(df, 'price'))
print('duration IQR Outliers :',findOutliers(df, 'duration'))
print('days_left IQR Outliers :',findOutliers(df, 'days_left'))

만들어낸 함수를 이용해서 각 컬럼에 이상치가 얼마나 있는지 도출한다.

'프로그래밍 공부' 카테고리의 다른 글

파이썬 7일차  (0) 2025.05.15
파이썬 6일차  (0) 2025.05.14
파이썬 4일차  (0) 2025.05.12
파이썬 3일차  (0) 2025.05.09
파이썬 2일차  (0) 2025.05.08