[기초 Pre과정] Python EDA 기초

라을·2024년 7월 2일

Upstage AI Lab

목록 보기
1/28
post-thumbnail
  • EDA : Exploratory Data Analysis

🖋️ 데이터 분석이란

✔️ 개념

  • 데이터 분석은 데이터를 조사, 정리, 모델링하여 유용한 정보를 발견하고 의사결정을 돕는 과정
  • 데이터 과학과 유사하며, 통계학, 데이터 분석, 머신러닝, 데이터 마이닝 등을 포함하는 포괄적인 개념
  • 데이터 분석은 데이터 과학의 한 부분으로 볼 수 있으며, 데이터 과학의 요소들을 살펴봄

✔️ 데이터 과학과 데이터 분석의 차이

  • 데이터 과학은 문제 해결을 위한 솔루션에 집중하고, 데이터 분석은 의사결정을 위한 통찰 제공에 집중
  • 데이터 과학자는 프로그래밍, 통계학, 시각화, 비즈니스 감각을 갖추어야 합니다.

--> 데이터 분석가의 역할과 기술:
프로그래밍 기술, 도메인 지식, 수학 및 통계 지식을 모두 필요로 함. 다양한 기술들이 조화를 이루어야 효과적인 데이터 분석이 가능!

데이터 분석 도구:
파이썬과 R이 대표적인 데이터 분석 언어

파이썬 : 비즈니스 문제를 해결하는 경우, CSV 파일을 읽어와 Pandas 라이브러리를 활용해 데이터를 분석


🖋️ API를 사용하여 데이터 수집하기

  • API : 어플리케이션 프로그래밍 인터페이스로, 두 프로그램 간의 대화 규칙을 정의하는 것

  • 웹 기반 API는 HTTP 통신 규약을 사용하여 데이터를 주고 받음
  • API를 통해 데이터베이스 접근이 제한된 경우에도 데이터를 가져올 수 있음

JSON 포맷

  • JSON은 파이썬의 딕셔너리와 유사한 형태로, 키와 값으로 이루어짐
  • JSON 데이터를 파이썬의 딕셔너리로 변환하여 사용 가능! : 'read_json' 함수를 통해 데이터프레임으로 변환 가능

XML 포맷

  • XML은 태그를 사용하여 데이터를 구조화하는 형식
  • 파이썬의 'xml' 모듈을 사용하여 데이터를 파싱하고 처리

예제


🖋️ 웹 스크래핑 사용하기

  • 웹 스크래핑의 필요한 경우 예시
    1) 도서관 정보 나루에서 제공하는 데이터에는 쪽수 정보가 없음
    2) 온라인 서점의 상세 페이지에서 쪽수 정보를 추출함

과정

  • yes24의 책 상세 페이지 URL을 얻기 위해 책 제목이나 ISBN으로 검색
  • 검색 결과 페이지에서 상세 페이지로 연결된 링크를 추출
  • 상세 페이지에서 쪽수 정보를 추출

HTML 파싱

  • 웹 페이지의 HTML 구조를 분석하여 원하는 데이터를 추출함
  • 크롬 개발자 도구를 사용하여 HTML 구조를 확인하고 원하는 데이터 위치를 파악
  • Beautiful Soup 라이브러리를 사용하여 HTML을 파싱하고 원하는 데이터를 추출

Beautiful Soup 사용

  • 'find()''find_all()' 메소드를 사용하여 특정 태그를 검색
  • 검색한 태그에서 필요한 정보를 추출

🔹HTML에서 데이터 추출 예제🔹
1. yes24의 상세 페이지에서 쪽수 정보를 포함한 태그를 찾아서 데이터 추출
2. 추출한 데이터를 파이썬 문자열 메소드를 사용하여 가공

주의사항

  • 웹사이트의 HTML 구조가 변경될 수 있어 프로그램 수정이 필요할 수 있음
  • 웹사이트의 'robots.txt'파일을 확인하여 스크래핑이 허용되는지 확인
  • 페이지가 동적으로 생성되는 경우, 스크래핑이 어려울 수 있음
  • 스크래핑 작업이 웹사이트의 디자인 변경에 민감할 수 있음

Pandas DataFrame 행과 열 선택하기

  • 판다스의 'iloc' 메소드를 사용하여 데이터프레임의 특정 행과 열을 선택
  • 슬라이싱 연산자를 사용하여 원하는 범위의 행과 열을 선택
  • 열 이름을 리스트로 지정하여 특정 열만 선택

🖋️ 데이터 조작

데이터 정제의 중요성

  • 데이터 분석을 위해 데이터를 준비할 때, 불필요하거나 잘못된 데이터가 포함된 경우가 많음
  • 데이터 정제(전처리) 과정은 데이터를 수정하고 고치는 작업을 의미
  • 데이터 정제 과정을 기록하는 것도 중요!

📌 불필요한 데이터 삭제하기

📍 열 삭제 방법

  • 열 삭제 : 슬라이싱 연산자를 사용하여 특정 열을 선택하고 불필요한 열을 제외할 수 있음

drop : 특정 열 삭제
dropna : 'NaN' 값을 포함한 열 삭제

📍 행 삭제 방법

  • 행 삭제 : 대괄호 연산자와 불리안 배열을 사용하여 조건에 맞는 행을 선택할 수 있음

drop : 특정 행 삭제

📍 그룹별 데이터 처리

groupby : 특정 열을 기준으로 데이터를 그룹화하고, 그룹별로 합계를 구하는 등의 작업 수행 가능
sum : 그룹화된 데이터의 합계를 계산


📌 잘못된 데이터 수정하기

📍 데이터의 문제점 확인

데이터가 비어있거나 잘못된 값이 있을 수 있음

  • 'info()' : 데이터프레임의 각 열에 대한 통계를 요약해서 보여줌

📍 NA 값 처리

  • 'isna()''sum()' : 각 열의 NA 값 개수를 확인
  • NaN 값은 판다스에서 특수한 부동소수점으로 저장됨
  • 정수형 열에 'NaN' 값을 입력하면 해당 열이 실수형으로 변경됨

📍 NA 값 대체

  • 'fillna()' : NaN 값을 다른 값으로 대체
  • 특정 열에 대해서만 'fillna()를 적용할 수도 있음
  • 여러 열에 대해 다른 값을 대체할 시 딕셔너리를 사용

📍 특정 값 대체

  • replace : 특정 값을 다른 값으로 대체
  • 리스트나 딕셔너리를 사용하여 여러 값을 동시에 대체할 수 있음

📍 정규 표현식 사용

  • 정규 표현식을 사용하여 문자열 매칭대체 작업 수행
  • 정규 표현식으로 숫자, 문자열 패턴을 매칭하여 필요한 부분만 추출
  • replace() 메서드에서 정규 표현식 사용가능

예제

  • str.extract : 원하는 부분 추출
  • str.contains : 지정된 문자열이 포함되어 있는지 확인
  • 메타문자 Meta Characters : 원래 그 문자가 가진 뜻이 아닌, 특별한 용도로 사용되는 문자

. ^ $ * + ? { } [ ] \ | ( )

1) [ ] : 대괄호 안에 포함된 문자들 중 하나와 매치를 뜻함

[abc] : abc 중 하나와 매치
'a' : a와 매치
'boy' : b와 매치
'edf' : 어느 문자와도 매치되지 않음

[a-c] : [abc]와 같음 --> -를 사용하면 두 문자 사이의 범위를 의미
[0-3] : [0123]과 같음
[a-zA-Z] : 알파벳 모두
[0-9] : 숫자

^ : 반대를 의미
[^0-9] : 숫자가 아닌 문자만 매치

2) * : 앞의 문자를 **1번 이상 반복**하는 것

3) + : 앞의 문자를 0번 이상 반복하는 것

3) + : 앞의 문자를 0번 이상 반복하는 것

3) ? : 앞의 문자를 0번 or 1번 반복하는 것

3) . : 1글자(문자)가 있다는 것

3) {3,5} : 3이상 5이하 반복하는 것


자주 사용하는 문자 클래스

  • [0-9] : 숫자
  • \d : 숫자와 매치, [0-9]와 동일한 표현식
  • \D : 숫자 아닌 것과 매치, [^0-9]와 동일한 표현식
  • \s : whitespace문자와 매치, [ \t\n\r\f\v]와 동일한 표현식. 맨 앞의 빈칸은 공백문자를 의미
  • \S : whitespace문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일한 표현식
  • \w : 문자+숫자와 매치, [a-zA-Z0-9_]와 동일한 표현식
  • \W : 문자+숫자가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일한 표현식
  • ^…$ : Starts and ends

📍 특정 조건에 맞는 데이터 추출

  • contains() : 특정 조건에 맞는 데이터를 추출

📌 통계로 요약하기

  • describe() : 데이터프레임의 수치형 열을 요약
    • count, mean, std, min, max, quantile 값 제공
  • mean() : 평균값
  • median() : 중앙값
  • min() / max() : 최소값 / 최대값
  • var() : 분산
  • std() : 표준편차
  • mode() : 최빈값

📌 분포 요약하기

그래프는 데이터를 한눈에 보기 쉽게 만들고, 시각적으로 이해하기 쉽도록 도와줌

📍 산점도 Scatter Plot

  • Scatter Plot : 두 변수 간의 관계를 시각화
    • alpha : 투명도 조절
import matplotlib.pyplot as plt
plt.scatter(x, y)
plt.scatter(x, y, alpha=0.1)
plt.show()

📍 히스토그램 Histogram

  • Histogram : 데이터의 분포를 나타내는 그래프
    • bins : 구간의 개수 지정
plt.hist(data, bins=5)
plt.show()

#numpy의 histogram 함수를 사용하여 정확한 구간 값을 얻을 수 있음
import numpy as np
hist, bin_edges = np.histogram(data, bins=5)

📍 정규분포 히스토그램 Normal Distribution

  • Normal Distribution : 데이터를 생성하고 히스토그램을 그릴 수 있음
    • plt.yscale('log') : y축을 로그 스케일로 변경
data = np.random.randn(1000)
plt.hist(data, bins=30)
plt.show()

📍 Box Plot

  • Box Plot : 데이터의 분포를 시각적으로 나타내는데 사용
    • 아랫면 : 1사분위수 (25%)
    • 윗면 : 3사분위수 (75%)
    • 중앙선 : 중앙값 (50%)
plt.boxplot(data)
plt.yscale('log') #y축 로그 스케일로 변경
plt.show()

🖋️ 데이터 시각화

📌 Matplotlib

📍 Figure 객체 생성하기

Matplotlib에서 그래프를 그리기 위해서는 먼저 Figure 객체를 생성해야 함. Figure 객체는 그래프의 전체적인 틀을 담당!

  • plt.figure () : 피겨 객체를 생성
    --> 그 안에 여러 개의 서브플롯을 추가할 수 있음!
import matplotlib.pyplot as plt
fig = plt.figure()

📍 서브플롯(Subplot) 추가하기

  • fig.add_suplot() : 서브플롯을 추가
  • plt.subplots() : 한 번에 여러 개의 서브플롯을 생성
# 1행 2열 중 첫 번째 서브플롯
ax1 = fig.add_subplot(1, 2, 1) 

# 1행 2열 중 두 번째 서브플롯
ax2 = fig.add_subplot(1, 2, 2) 

# 2행 1열의 서브플롯
fig, axs = plt.subplots(2, 1) 

📍 그래프 그리기, 크기/해상도 조정하기

  • figsize : 피겨 크기를 조정
  • dpi : 해상도를 조정
ax1.plot(x, y)
ax2.scatter(x, y)

fig = plt.figure(figsize=(10, 6))
fig = plt.figure(dpi=144

📍 rcParams 설정하기

  • rcPrarms : matplotlib 라이브러리에서 그래프의 기본 설정값을 관리하는 데 사용되는 설정 파일
    • figure.figsize : 기본 피겨 크기
    • lines.linewidth : 기본 선 너비
    • axes.titlesize : 기본 제목 크기
import matplotlib.pyplot as plt
import matplotlib as mpl

# 그래프의 기본 크기 변경
mpl.rcParams['figure.figsize'] = (10, 6)

# 선의 기본 너비 변경
mpl.rcParams['lines.linewidth'] = 2

# 제목의 기본 크기 변경
mpl.rcParams['axes.titlesize'] = 'large'

#x/y축 틱 라벨 글꼴 크기 변경
mpl.rcParams['x/ytick.labelsize'] = 'small'


# 변경된 설정을 적용한 그래프 그리기
plt.plot([1, 2, 3], [4, 5, 6])
plt.title('Example Plot')
plt.show()

예제

fig, axs = plt.subplots(2, 1, figsize=(8, 10))
axs[0].scatter(x, y, alpha=0.5)
axs[0].set_title('Scatter Plot')
axs[1].hist(data, bins=30, alpha=0.75)
axs[1].set_title('Histogram')
plt.show()

📌 Line Graph & Bar Graph

📍 Line Graph

  • plot 함수 사용
import matplotlib.pyplot as plt

# 예시 데이터
count_by_year = {2000: 120, 2001: 150, 2002: 170, 2003: 180, 2004: 190}

plt.plot(list(count_by_year.keys()), list(count_by_year.values()))
#선 스타일 바꾸기
plt.plot(list(count_by_year.keys()), list(count_by_year.values()), marker='o', linestyle='--', color='r')

plt.xlabel('Year')
plt.ylabel('Count')
plt.title('Books Borrowed by Year')
plt.show()


#그래프에 텍스트 추가하기
plt.plot(list(count_by_year.keys()), list(count_by_year.values()), marker='o', linestyle='--', color='r')
plt.xlabel('Year')
plt.ylabel('Count')
plt.title('Books Borrowed by Year')
for idx, val in count_by_year.items():
    plt.annotate(f'{val}', xy=(idx, val), xytext=(5, 5), textcoords='offset points')
plt.show()

📍 Bar Graph

  • bar 함수 사용
    • 막대에 값 표시 : annotate() 함수 사용
# 예시 데이터
count_by_subject = {'Math': 120, 'Science': 150, 'English': 170}

plt.bar(list(count_by_subject.keys()), list(count_by_subject.values()))
plt.xlabel('Subject')
plt.ylabel('Count')
plt.title('Books Borrowed by Subject')
plt.show()

#막대에 값 표시 : annotate() 함수 사용
bars = plt.bar(list(count_by_subject.keys()), list(count_by_subject.values()))
plt.xlabel('Subject')
plt.ylabel('Count')
plt.title('Books Borrowed by Subject')
for bar in bars:
    yval = bar.get_height()
    plt.annotate(f'{yval}', xy=(bar.get_x() + bar.get_width() / 2, yval), xytext=(0, 3), textcoords='offset points', ha='center', va='bottom')
plt.show()

세로 막대 그래프 그리기

  • barh 함수 사용
bars = plt.barh(list(count_by_subject.keys()), list(count_by_subject.values()))
plt.ylabel('Subject')
plt.xlabel('Count')
plt.title('Books Borrowed by Subject')
for bar in bars:
    xval = bar.get_width()
    plt.annotate(f'{xval}', xy=(xval, bar.get_y() + bar.get_height() / 2), xytext=(5, 0), textcoords='offset points', ha='left', va='center')
plt.show()

📌 객체지향 API로 그래프 그리기

📍 객체지향 API 방식

  • 서브플롯 함수를 사용하여 명시적으로 Figure 객체와 Axis 객체를 만들어 사용하는 방식
    • 이 방식은 그래프의 세부적인 옵션을 더 많이 제어할 수 있는 장점이 있음
fig, ax = plt.subplots()
ax.plot([1, 4, 9, 16])
ax.set_title('Simple Line Graph')
plt.show()

발행년도 vs 출판사 산점도 그리기

fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(x=publish_years, y=publishers)
ax.set_title('출판사별 발행년도 도서')
ax.set_xlabel('발행년도')
ax.set_ylabel('출판사')
plt.show()

마커 크기 키우기

fig, ax = plt.subplots(figsize=(10, 6))
sizes = [loan * 10 for loan in loan_counts]  # 대출 건수에 따라 크기 조정
ax.scatter(x=publish_years, y=publishers, s=sizes)
ax.set_title('출판사별 발행년도 도서')
ax.set_xlabel('발행년도')
ax.set_ylabel('출판사')
plt.show()

마커 꾸미기

fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(x=publish_years, y=publishers, s=sizes, edgecolors='k', alpha=0.3, linewidths=0.5, c=loan_counts, cmap='viridis')
ax.set_title('출판사별 발행년도 도서')
ax.set_xlabel('발행년도')
ax.set_ylabel('출판사')
plt.colorbar(ax.scatter(x=publish_years, y=publishers, s=sizes, c=loan_counts, cmap='viridis'), ax=ax, label='대출 건수')
plt.show()

컬러맵 추가하기

  • cmap 매개변수 사용
fig, ax = plt.subplots(figsize=(10, 6))
sc = ax.scatter(x=publish_years, y=publishers, s=sizes, c=loan_counts, cmap='jet')
ax.set_title('출판사별 발행년도 도서')
ax.set_xlabel('발행년도')
ax.set_ylabel('출판사')
plt.colorbar(sc, ax=ax, label='대출 건수')
plt.show()

🖋️ 통계적으로 추론하기

📍 가설 검증

  • 모집단에서 표본을 뽑아 그 표본을 가지고 모집단의 성격을 검증하는 전통적인 통계적 방법
  • 두 가지 가설, 즉 영가설(H0)과 대립가설(H1)을 세우고, 이를 검증하는 과정
  • ttest_ind 함수 사용
from scipy.stats import ttest_ind

# 두 그룹의 데이터
data1 = [20, 21, 19, 22, 20, 23, 21]
data2 = [30, 31, 29, 32, 30, 33, 31]

# t-검정 수행
t_stat, p_value = ttest_ind(data1, data2)
print('t-statistic:', t_stat)
print('p-value:', p_value)

📍 모수 검정

  • 전체 모집단의 성격을 추정하기 위해 표본을 사용하는 방법
  • 표본은 모집단에서 무작위로 추출한 데이터 집합을 의미

📍 표준 점수 (Z-Score)

  • 정규분포에서 데이터 포인트가 평균에서 얼마나 떨어져 있는지를 나타냄
  • 정규분포는 평균을 중심으로 좌우 대칭인 분포로, 데이터가 평균에서 얼마나 멀리 떨어져 있는지를 표준편차를 이용해 측정합

📍 중심극한정리 (Central Limit Theorem)

  • 모집단이 정규분포를 따르지 않더라도, 표본의 평균들이 정규분포를 따르게 된다는 이론
  • 표본의 평균들은 모집단의 평균과 같으며, 표본의 평균의 표준편차는 모집단의 표준편차를 표본 크기의 제곱근으로 나눈 값과 같음

📍신뢰구간 (Confidence Interval)

  • 모집단의 평균을 포함할 가능성이 높은 구간을 나타냄
  • 표본 평균을 이용해 모집단의 평균을 추정할 때 사용

예) 95% 신뢰구간은 표본 평균을 중심으로 1.96 표준편차 내에 모집단의 평균이 포함될 확률이 95%임을 의미

📍순열 검정

  • 두 표본을 섞어 무작위로 나눈 후 평균의 차이를 계산하는 방법
  • 이를 여러 번 반복하여 평균의 차이가 의미가 있는지를 판단
  • permutation_test 함수 사용
from scipy.stats import permutation_test

# 두 그룹의 데이터
data1 = [20, 21, 19, 22, 20, 23, 21]
data2 = [30, 31, 29, 32, 30, 33, 31]

# 순열 검정 수행
result = permutation_test((data1, data2), statistic=lambda x, y: np.mean(x) - np.mean(y), 
                          permutation_type='independent', alternative='two-sided')
print('p-value:', result.pvalue)

🖋️ 머신러닝으로 예측하기

머신러닝이란?

머신러닝은 인공지능의 한 분야로, 컴퓨터를 사용해 데이터를 통해 패턴과 규칙을 학습하는 방법이다. 머신러닝에는 크게 지도학습과 비지도학습이 있다.

  • 지도학습: 정답을 알고 있는 데이터를 사용하여 모델을 훈련시키는 방법

    • 예) 스팸메일 감지에서는 스팸인지 아닌지 이미 분류된 데이터를 사용해 모델을 훈련시키고, 새로운 이메일이 스팸인지 아닌지 예측하게 함
  • 비지도학습: 정답이 없는 데이터를 사용하여 모델을 훈련시키는 방법으로, 데이터의 특성을 분석하거나 군집화하는 데 주로 사용

    • 예) 고객 데이터를 분석해 비슷한 고객 그룹을 찾는 클러스터링 등이 있음

📍 모델 훈련

  • 모델 훈련이란 주어진 데이터로부터 패턴이나 규칙을 학습하는 과정을 의미
  • 모델을 훈련시키기 위해서는 데이터를 훈련용 데이터셋과 테스트용 데이터셋으로 나누어 사용
  • 훈련용 데이터셋으로 모델을 학습시키고, 테스트용 데이터셋으로 모델의 성능을 평가함

📍 선형 회귀

  • Linear Regression : 입력 변수와 출력 변수 사이의 선형 관계를 모델링하는 방법
from sklearn.linear_model import LinearRegression

# 데이터 준비
X = [[1], [2], [3], [4], [5]]
y = [2, 3, 5, 7, 11]

# 모델 훈련
model = LinearRegression()
model.fit(X, y)

# 예측
predictions = model.predict([[6], [7]])
print(predictions)

📍 로지스틱 회귀

  • Logistic Regression : 이진 분류 문제에서 사용되며, 출력값을 0과 1 사이로 압축하여 특정 임계값을 기준으로 분류
from sklearn.linear_model import LogisticRegression

# 데이터 준비
X = [[1], [2], [3], [4], [5]]
y = [0, 0, 1, 1, 1]

# 모델 훈련
model = LogisticRegression()
model.fit(X, y)

# 예측
predictions = model.predict([[1.5], [3.5]])
print(predictions)

📍 정확도 평가

  • 회귀 모델 : R^2 점수
    • R^2 : 예측값이 실제 값과 얼마나 일치하는지를 나타냄. 1에 가까울수록 좋은 모델!
  • 분류 모델 : 정확도
    • 정확도 : 예측한 값 중에서 실제 값과 맞는 비율
from sklearn.metrics import accuracy_score, r2_score

# 회귀 모델 평가
r2 = r2_score(y_true, y_pred)
print(f'R² score: {r2}')

# 분류 모델 평가
accuracy = accuracy_score(y_true, y_pred)
print(f'Accuracy: {accuracy}')

profile
욕심 많은 공대생

0개의 댓글