Hyun's Wonderwall

[Pylots] 파머완 - 01. 파이썬 기반의 머신러닝과 생태계 이해 본문

Study/Python-Machine-Learning

[Pylots] 파머완 - 01. 파이썬 기반의 머신러닝과 생태계 이해

Hyun_! 2024. 3. 23. 13:49

[Chapter 01] 파이썬 기반의 머신러닝과 생태계 이해

1. 머신러닝의 개념

  • 머신러닝(Machine Learning): 데이터를 기반으로 숨겨진 패턴을 학습하고 결과를 예측하는 알고리즘 기법.
  • 머신러닝 알고리즘은 데이터를 기반으로 통계적인 신뢰도를 강화하고 예측 오류를 최소화하기 위한 다양한 수학적 기법을 적용하여 데이터 내의 패턴을 스스로 인지하고 신뢰도 있는 예측 결과를 도출해 낸다.
  • 데이터 분석 영역은 재빠르게 머신러닝 기반의 '예측 분석(Predictive Analysis)'으로 재편되고 있다.

머신러닝의 분류

  • 지도학습(Supervised Learning): 크게 회귀(regression) 분류(classification) 두 유형으로 나뉘어짐. (+ 추천 시스템, 시각/음성 감지/인지, 텍스트 분석, NLP)
  • 비지도학습(Un-Supervised Learning): 클러스터링, 차원 축소
  • 강화학습(Reinforcement Learning): 비지도학습의 한 종류

데이터 전쟁

머신러닝에서는 데이터와 머신러닝 알고리즘 모두 중요.
머신러닝의 가장 큰 단점: 데이터에 매우 의존적. "Garbage in, Garbage out" 좋은 품질의 데이터를 갖추지 못하면 머신러닝의 수행 결과도 좋을 수 없다.
=> 데이터 이해하고 효율적으로 가공, 처리, 추출해 최적의 데이터를 준비하는 능력 중요. 데이터 다양성, 양, 품질 중요.

파이썬과 R 기반의 머신러닝 비교

파이썬은 다양한 영역에서 사용되는 개발 전문 프로그램 언어. R은 통계 전용 프로그램 언어. 
파이썬의 장점:
- 직관적 문법, 객체지향, 함수형 프로그래밍 포괄하는 유연한 프로그래밍 아키텍쳐. 쉽고 뛰어난 개발 생산성.
- 오픈소스 라이브러리 매우 방대함.
- 인터프리터 언어 (속도는 느리지만 뛰어난 확장성, 유연성, 호환성)
- 머신러닝과 결합한 다양한 애플리케이션 개발 가능.
- 딥러닝 프레임워크인 텐서플로, 케라스, 파이토치 등에서 파이썬 우선 정책으로 파이썬을 지원함.


2. 파이썬 머신러닝 생태계를 구성하는 주요 패키지

  • 머신러닝 패키지 - 사이킷런(SciKit-Learn): 데이터 마이닝 기반 머신러닝. 딥러닝 지원x. // 딥러닝에서는 텐서플로, 파이토치, 케라스 등
  • 행렬/선형대수 패키지 - 넘파이(NumPy): 행렬 기반 데이터 처리에 특화. // 자연과학&통계 패키지 - 사이파이(SciPy)
  • 데이터 핸들링 - 판다스(Pandas): 2차원 데이터 처리에 특화, 데이터 처리가 편리.
  • 시각화 - 맷플롯립(Matplotlib), 시본(Seaborn)

+ 머신러닝 프로그램 개발 - 주피터 노트북(Jupyter Notebook) 사용

2.1. 파이썬 머신러닝을 위한 S/W 설치

Anaconda: 파이썬 기반의 머신러닝에 필요한 패키지들 일괄적으로 설치 가능.
- Anaconda를 이용해 패키지를 설치할 때 Anaconda Prompt 사용
- Jupiter Notebook은 localhost:8888
 
머신러닝 알고리즘과 사이킷런을 다루기 전에 넘파이판다스를 이해해야 함.
- 데이터 처리 시 사용. (데이터 추출/가공/변형, 알고리즘 처리 결과 가공 등)
- 파이썬 머신러닝 생태계를 구성하는 주요 요소 (사이킷런이 넘파이 기반)
- 다만 둘은 API 너무 방대함
=> 넘파이와 판다스의 기본 프레임워크중요 API를 습득하고, 일단 부딪쳐 가며 모르는 API는 추가 공부하자.


3. 넘파이

넘파이(NumPy): 파이썬에서 선형대수 기반의 프로그램을 쉽게 만들 수 있도록 지원하는 패키지.
많은 머신러닝 알고리즘이 넘파이 기반으로 작성되어있고, 알고리즘의 입출력 데이터를 넘파이 배열 타입으로 사용함.

  • 배열 연산: 루프를 사용하지 않고 대량 데이터 배열 연산 가능 ->  빠른 배열 연산 속도.
  • C/C++과 같은 저수준 언어 기반의 호환 API 제공: 파이썬이 느리므로, 수행 성능이 매우 중요한 부분은 C/C++ 기반 코드로 작성하고 이를 넘파이에서 호출하도록 함. (ex. 텐서플로)
  • 넘파이에서 데이터 핸들링도 가능하지만, 편의성과 다양한 API 지원 측면에서 아쉽. So 데이터 핸들링을 할 때에는 판다스의 데이터프레임을 이용할 것임.

넘파이의 기본 지식과 이 책에서 자주 사용되는 넘파이 API를 알아보자.

번외) 여기서 말하는 API는 무엇일까?
API(Application Programming Interface): 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. (Open API, REST API 등)
따라서 라이브러리의 API는 라이브러리를 활용하는 규약으로서, 라이브러리가 제공하는 기능을 사용할 수 있게 한다.
*참고: https://dankthedust.notion.site/API-Library-Framework-edaca5d855e5404e9477e78a687ebd68

3.1. 넘파이 ndarray 개요

import numpy as np #넘파이 모듈 임포트 (numpy를 np로 alias함)

*임포트 시 as np를 추가해 약어 'np'로 모듈을 표현하는 게 관례.
 
넘파이의 기반 데이터 타입: ndarray - 다차원 배열을 쉽게 생성, 다양한 연산 수행 가능
[1 2 3] 와 같이 표현됨. 리스트와 달리 ','가 없음.
 
(*아래에서 np: 패키지, ndarray: ndarray 배열을 의미)

  • np.array( ): 다양한 인자(리스트 등)를 입력받아 ndarray로 변환
  • ndarray.shape: ndarray의 크기를 튜플 형태로 가짐. (행의 수, 열의 수)
    - ex. 1차원: (1, ). 2차원: (2, 3) // 차원을 알 수 있음
  • ndarray.ndim: ndarray의 차원을 숫자로 반환 (ex.1, 2, ...)

3.2. ndarray의 데이터 타입

ndarray 내 데이터 타입은 같은 데이터 타입만 가능. (숫자 값, 문자열 값, 불 값 등 다 가능)
-> 데이터 타입이 섞여 있는 리스트를 ndarray로 변형 시, 더 큰 데이터 타입으로 형 변환 일괄 적용

  • ndarray.dtypendarray 내 데이터 타입 확인하는 속성. (ex. int32, float64...)
  • ndarray.astype('바꿀 타입 문자열') ndarray 내 데이터 타입 변경.
    ex. array_int.astype('float64')    # array_int가 [1 2 3]에서 [1. 2. 3.]으로 타입 변경됨.

3.3. ndarray를 편리하게 생성 - arange, zeros, ones

일괄적으로 초기화할 때 사용.

  • np.arange( ): 인자로 stop 값 받아 '0 ~ stop-1' 연속값으로 구성된 1차원 ndarray 생성.
    - start값 부여 가능. array를 range( )로 표현한 것.
      ex. sequence_array = np.arange(10)과 같이 쓴다.
  • np.zeros(_,_): 인자로 튜플 값을 받아, 모든 값을 0으로 채운 해당 shape의 ndarray를 반환.
  • np.ones(_,_)인자로 튜플 값을 받아, 모든 값을 1로 채운 해당 shape의 ndarray 반환.
    - 함수 인자로 dtype 정해주지 않으면 default는 float64.
      ex. np.ones((1, 2)) 하면 [[1. 1. ]]이렇게 된다.

3.4. ndarray의 차원과 크기를 변경하는 reshape( )

  • ndarray.reshape( ): ndarray를 특정 차원 및 크기로 변환.
    - 인자로 -1을 사용하면 원래 ndarray와 호환되는 새로운 shape로 변환.
    - 지정된 사이즈로 변경 불가능하면 오류 발생.
    - ex. array1의 shape가 (10, )일 때 array1.reshape(-1, 5)하면 (2, 5)로 변환, array1.reshape(5, -1)하면 (5, 2)로 변환. 그러나 (-1, 4)는 오류 발생.
    - reshape(-1, 1)과 같은 형태로 자주 사용됨. (2차원, 1개 칼럼에 여러개의 로우.)
  • ndarray.tolist(): ndarray를 리스트 자료형으로 변환.

3.5. 넘파이 ndarray의 데이터 세트 선택하기 - 인덱싱(Indexing)

  1. 단일 값 추출
    특정한 데이터만 추출. 원하는 위치의 인덱스 값 지정.
    - ex. array1[2]. array1[-1]=맨 뒤 값 (-2로 하면 맨 뒤에서 두 번째). 다차원은 array2d[2, 3]
  2. 슬라이싱
    연속된 인덱스상의 ndarray를 추출. 'start:end' (*start에서 end-1 위치에 있는 ndarray를 반환.)
    - ex. array1[1:3]. array[:3]. array[3:]. array1[:]
  3. 팬시 인덱싱
    일정한 인덱싱 집합을 리스트 또는 ndarray 형태로 지정해 해당 위치에 있는 ndarray 반환.
    - ex. array2d[[0, 1], 2]. array2d[[0, 1], 0:2]
  4. 불린 인덱싱
    특정 조건에 해당하는지 여부인 True/False 값 인덱싱 집합을 기반으로
    True에 해당하는 인덱스 위치에 있는 데이터의 ndarray를 반환.
    - ex. array1d[array1d > 5]
    <불린 인덱싱이 동작하는 단계>
    (1) array1d > 5와 같이 ndarray의 필터링 조건을 [ ] 안에 기재
    (2) False값은 무시하고 True값에 해당하는 인덱스값만 저장
    *유의해야 하는 사항: True값 자체인 1을 저장하는 것이 아니라 True값을 가진 인덱스를 저장.
    (3) 저장된 인덱스 데이터 세트로 ndarray 조회

3.6. 행렬의 정렬 - sort( )와 argsort( )

행렬 정렬

  • np.sort(ndarray): 인자로 행렬 대입. 원 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬을 반환.
    - ex. org_array = np.array([3, 1, 9, 5]); sort_array1 = np.sort(org_array) # sort_array1은 [1 3 5 9]
  • ndarray.sort(): 원 행렬 자체를 정렬된 형태로 바꿈, 반환 값은 None.
    - ex. sort_array2 = org_array.sort() # sort_array2는 None 반환.
  • np.argsort(ndarray): 정렬 행렬 원소들의 원본 행렬 인덱스를 ndarray형으로 반환.
    - ex. sort_indices = np.argsort(org_array)
    오름차순이 아닌 내림차순으로 정렬 시: np.argsort( )[::-1]
    - ex. sort_indices_desc = np.argsort(org_array)[::-1]

3.7. 선형대수 연산 - 행렬 내적과 전치 행렬 구하기

행렬 내적(행렬 곱) :  np.dot(_, _)
- ex. np.dot(A, B) : 두 행렬 A와 B의 내적. dot_product = np.dot(A, B)
전치 행렬 : np.transpose( )
 - ex. transpose_mat = np.transpose(A)


4. 판다스

판다스: 파이썬의 대표적인 데이터 핸들링 프레임워크. 고수준 API 제공.
*판다스의 핵심 객체: DataFrame.
    칼럼이 여러 개인 데이터 구조체. CSV 등의 파일을 DataFrame으로 변경 시 데이터의 가공/분석 편리.
*그 다음으로 중요한 객체: Index, Series
    Index:
개별 데이터를 고유하게 식별하는 Key값. Series와 DataFrame은 Index를 반드시 가짐.
    Series: 칼럼이 하나인 데이터 구조체.

4.1. 판다스 시작 - 파일을 DataFrame으로 로딩, 기본 API

import pandas as pd #판다스 모듈 임포트 (pandas를 pd로 alias함)
  • pd.read_csv(filepath_or_buffer, sep=',' , ...): 데이터 파일을 판다스의 DataFrame으로 로딩
    - ex. titanic_df = pd.read_csv('titanic_train.csv') # read_csv 주로 사용
  • DataFrame.head(N): 맨 앞에 있는 N개의 로우를 반환 (Default: 5개)
  • DataFrame.shape: DataFrame의 행과 열을 튜플 형태로 반환

DataFrame에서 메타 데이터 조회

(*메타 데이터: 데이터에 관한 구조화된 데이터, 다른 데이터를 설명해 주는 데이터)

  • DataFrame.info() : 총 데이터 건수, 데이터 타입, Null 건수 알 수 있음
  • DataFrame.describe(): 칼럼별 숫자형 데이터값의 n-percentile 분포도, 평균값, 최댓값, 최솟값 나타냄.
    (오직 숫자형 칼럼의 분포도만 조사 - percentile 값을 보고 해당 칼럼이 숫자형 카테고리 칼럼인지 판단 가능)
    (*카테고리 칼럼: 특정 범주에 속하는 값을 코드화한 칼럼. ex. '남'을 1, '여'를 2로 표현)

Series: Index와 단 하나의 칼럼으로 구성된 데이터 세트.

- DataFrame의 [ ] 연산자 내부에 칼럼명을 입력하면 Series 형태로 특정 칼럼 데이터 세트가 반환됨.


value_counts(): 해당 칼럼의 데이터값 건수, 칼럼 이름, 데이터값 유형을 반환. Series, DataFrame 모두 호출 가능.

- ex. DataFrame['칼럼명'].value_counts()

 

4.2. DataFrame과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환

(1) 리스트, 딕셔너리, ndarray를 판다스 DataFrame으로 변환

pd.DataFrame(원본 객체 data,  columns=칼럼명 리스트)

  • data: 리스트, 딕셔너리 또는 넘파이 ndarray 변수
  • columns: 칼럼명 리스트 변수. 일반적으로 DataFrame으로 변환 시 칼럼명을 지정해야 한다. (지정하지 않으면 자동으로 칼럼명 할당)

- DataFrame은 행과 열을 가지는 2차원 데이터여서, 2차원 이하의 데이터들만 DataFrame으로 변환될 수 있다.

- 딕셔너리 변환 시 Key가 칼럼명으로, Value가 칼럼 데이터로 매핑된다. (키: 문자열, 값: 리스트 또는 ndarray 형태)
  ex. dict = {'col1':[1, 11], 'col2':[2, 22], 'col3':[3, 33]}; df_dict = pd.DataFrame(dict)

 

(2) DataFrame을 ndarray, 리스트, 딕셔너리로 변환

  • ndarray로 변환: array3 = df_dict.values
  • 딕셔너리로 변환: dict3 = df_dict.to_dict('list') # value가 리스트 형
  • 리스트로 변환: list3 = df_dict.values.tolist()

4.3. DataFrame의 칼럼 데이터 세트 생성과 수정

DataFrame [ ] 내에 새로운 칼럼명을 입력하고 값을 할당해주면 새 칼럼이 생성된다.

 ex. titanic_df['Age_0']=0 와 같이 Series에 상수값을 할당하면 Series 모든 데이터 세트에 일괄 적용됨

기존 칼럼을 가공해 새로운 칼럼을 생성할 수 있다.

DataFrame 내의 기존 칼럼 값도 쉽게 일관적으로 업데이트할 수 있다. (업데이트를 원하는 Series를 DataFrame[ ] 내에 칼럼명으로 입력한 뒤에 값 할당)

4.4 DataFrame 데이터 삭제

drop() 메서드로 데이터 삭제

axis 0: row 방향 축 (세로 방향, row 수 증감하는)

axis 1: column 방향 축 (가로 방향, column 수 증감하는)

 

4.5. Index 객체

DF, Series의 레코드를 고유하게 색별하는 객체. .index 속성으로 추출 가능. Index 객체 함부로 변경 불가.

4.6. 데이터 셀렉션 및 필터링

~~~~

4.7. 정렬, Aggregation 함수, GroupBy 적용

DataFrame, Series: sort_values()

Aggregation 함수 적용

groupBy() 적용

4.8. 결손 데이터 처리하기

결손 데이터 판다스의  NaN으로 표시.

isna()로 확인, fillna()로 대체

4.9. apply lambda 식으로 데이터 가공

람다 식 적용해 데이터 가공
 

다음 글: https://hereishyun.tistory.com/116