머신러닝

[1장] 파이썬 머신러닝 완벽 가이드_Numpy

zsun 2023. 4. 14. 16:22

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

 

머신러닝

  •  머신러닝 : 애플리케이션을 수행하지 않고도 데이터를 기반으로 학습하고 결과를 예측하는 알고리즘 기법
  • 머신러닝의 분류

    - 지도학습 : 분류, 회귀, 추천 시스템, 시각/음성 감지/인지, 텍스트 분석, NLP

    - 비지도학습 : 클러스터링, 차원축소, 강화학습

 

  • 머신러닝의 단점 

      : 데이터에 의존적임 - Garbage In, Garbage Out (좋은 품질의 데이터를 갖추지 못하면 머신러닝 수행 결과도 좋을 수 없음)

 

  • 최적의 알고리즘, 모델 파라미터 구축 능력과 더불어 데이터 이해를 바탕으로 한 데이터의 효율적인 가공, 처리, 추출을 통한 준비 능력 중요

 

 

 

넘파이

  • Numpy (Numerical Python) : 선형대수 기반의 프로그램을 쉽게 만들수 있도록 지원하는 대표 패키지

넘파이 ndarray 개요

# 넘파이 모듈 임포트
import numpy as np
  • 넘파이의 기반 데이터 타입 : ndarray
  • ndarray를 이용하여 넘파이에서 다차원 배열을 쉽게 생성하고 다양한 연산을 수행할 수 있음
  • 넘파이의 array 함수 : 파이썬의 리스트와 같은 다양한 인자를 입력받아서 ndarry로 변환하는 기능
  • 생성된 ndarray 배열의 shape 변수는 ndarray의 크기(행과 열의 수)를 튜플 형태로 가짐 : ndarray 배열의 차원을 알 수 있음

 

[넘파이 ndarray 배열의 차원]

array1 = np.array([1,2,3])
print('array1 type:', type(array1))
print('array1 array 형태:', array1.shape)

array2=np.array([[1,2,3],[2,3,4]])
print('array2 type:', type(array2))
print('array2 array 형태:', array2.shape)

array3=np.array([[1,2,3]])
print('array3 type:',type(array3))
print('array3 array 형태:', array3.shape)
더보기
array1 type: <class 'numpy.ndarray'>
array1 array 형태: (3,)
array2 type: <class 'numpy.ndarray'>
array2 array 형태: (2, 3)
array3 type: <class 'numpy.ndarray'>
array3 array 형태: (1, 3)

#array1,3은 동일한 데이터 건수를 가지고 있지만, array1은 명백하게 1차원임을 (3,)으로 표현
#array3은 2차원임을 (1,3)으로 표현

 

  •  각 array의 차원을 ndim을 이용하여 확인
print('array1 : {:0}차원, array2 : {:1}차원, array3 : {:2}차원'.format(array1.ndim,array2.ndim,array3.ndim))
더보기
array1 : 1차원, array2 : 2차원, array3 :  2차원

# array() 함수의 인자로는 파이썬의 리스트 객체가 주로 사용됨
# 리스트 []는 1차원이고, 리스트의 리스트 [[]]는 2차원과 같은 형태로 배열의 차원과 크기 표현 가능

 

 

ndarray의 데이터 타입

  • 서로 다른 데이터 타입을 가질 수 있는 리스트와는 다르게 ndarray 내의 데이터 타입은 같은 데이터 타입만 가능
list2 = [1, 2, 'test']
array2 = np.array(list2)
print(array2, array2.dtype)

list3 = [1, 2, 3.0]
array3 = np.array(list3)
print(array3, array3.dtype)

 

더보기
['1' '2' 'test'] <U21
[1. 2. 3.] float64

 

  • ndarray내 데이터값의 타입 변경은 astype() 메서드를 이용하여 가능
array_int = np.array([1, 2, 3])
array_float = array_int.astype('float64')
print(array_float, array_float.dtype)

array_int1= array_float.astype('int32')
print(array_int1, array_int1.dtype)

array_float1 = np.array([1.1, 2.1, 3.1])
array_int2= array_float1.astype('int32')
print(array_int2, array_int2.dtype)
더보기
[1. 2. 3.] float64
[1 2 3] int32
[1 2 3] int32

 

 

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

  • 특정 크기와 차원을 가진 ndarray를 연속값이나 0또는 1로 초기화해 생성해야 할 경우 arange(), zeros(), ones() 사용
  • 테스트용 데이터를 만들거나 대규모의 데이터를 일괄적으로 초기화해야 할 경우에 사용

 

- arange() : array를 range()로 표현 , 0부터 함수 인자 값 -1까지의 값을 순차적으로 ndarray의 데이터값으로 변환

- zeros() : 함수 인자로 튜플 형태의 shape 값을 입력하면 모든 값을 0으로 채운 해당 shape을 가진 ndarray 반환

               (*데이터 타입을 지정해 주지 않으면 default로 floaat64형의 데이터로 ndarray 채움)

- ones() : zeros()와 유사하게 모든 값을 1로 채운 ndarray 반환

 

 

 

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

  • reshape() 메서드는 ndarray를 특정 차원 및 크기로 반환
# 0~9까지의 1차원 ndarray를 2*5 / 5*2로 변환

array1 = np.arange(10)
print('array1:\n', array1)

array2 = array1.reshape(2,5)
print('array2:\n',array2)

array3 = array1.reshape(5,2)
print('array3:\n',array3)
더보기
array1:
 [0 1 2 3 4 5 6 7 8 9]
array2:
 [[0 1 2 3 4]
 [5 6 7 8 9]]
array3:
 [[0 1]
 [2 3]
 [4 5]
 [6 7]
 [8 9]]
  • ndarray는 tolist() 메서드를 이용해 리스트 자료형으로 변환 가능
array1 = np.arange(8)
array3d = array1.reshape((2,2,2))
print('array3d:\n',array3d.tolist())

# 3차원 ndarray를 2차원 ndarray로 변환
array5 = array3d.reshape(-1,1)
print('array5:\n',array5.tolist())
print('array5 shape:',array5.shape)

# 1차원 ndarray를 2차원 ndarray로 변환
array6 = array1.reshape(-1,1)
print('array6:\n',array6.tolist())
print('array6 shape:',array6.shape)
더보기
array3d:
 [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
array5:
 [[0], [1], [2], [3], [4], [5], [6], [7]]
array5 shape: (8, 1)
array6:
 [[0], [1], [2], [3], [4], [5], [6], [7]]
array6 shape: (8, 1)

 

 

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

(1) 단일값 추출

: 원하는 위치의 인덱스 값을 지정하며 해당 위치의 데이터 반환

 

(2) 슬라이싱(Slicing)

: 연속된 인덱스상의 ndarray를 추출하는 방식

: [시작 인덱스 : 종료 인덱스] -> 시작 인덱스에서 종료 인덱스-1 위치에 있는 ndarray를 반환

 

(3) 팬시 인덱싱(Fancy Indexing)

: 일정한 인덱싱 집합을 리스트 또는 ndarray 형태로 지정해 해당 위치에 있는 ndarray를 반환

 

(4) 불린 인덱싱(Boolean Indexing)

: 특정 조건에 해당하는지 여부인 True/False값 인덱싱 집합을 기반으로 True에 해당하는 인덱스위치에 있는 ndarray를 반환

 

  • 단일데이터값을 제외하고 슬라이싱,팬시인덱싱,불린인덱싱으로 추출된 데이터셋은 모두 ndarry 타입

 

 

(1) 단일값 추출

 

1차원 ndarray 에서의 단일값 추출

 

넘파이 ndarray에서는 row와 column은 사용하지 않지만, axis=0, axis=1, axis=3(행, 열, 높이 라고 이해하는 것이 편함)

 

2차원 ndarray에서의 단일값 추출

 


(2) 슬라이싱

 

  • 1차원 ndarray에서의 슬라이싱

 

array1 = np.arange(start=1, stop=10)
array4 = array1[:3]
print(array4)

array5 = array1[3:]
print(array5)

array6 = array1[:]
print(array6)

코드 실행 결과의 시각화

 

  • 2차원 ndarray에서의 슬라이싱
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print('array2d:\n',array2d)

print('array2d[0:2, 0:2] \n', array2d[0:2, 0:2])
print('array2d[1:3, 0:3] \n', array2d[1:3, 0:3])
print('array2d[1:3, :] \n', array2d[1:3, :])
print('array2d[:, :] \n', array2d[:, :])
print('array2d[:2, 1:] \n', array2d[:2, 1:])
print('array2d[:2, 0] \n', array2d[:2, 0])

코드 실행 결과의 시각화


 

(3) 팬시 인덱싱 (Fancy Indexing)

 

  • 1차원 ndarray 팬시 인덱싱

 

  • 2차원 ndarray 팬시 인덱싱


(4) 불린 인덱싱 (Boolean Indexing)

  • 조건 필터링과 검색을 동시에 할 수 있어서 자주 사용됨
array1d = np.arange(start=1, stop=10)
# [ ] 안에 array1d > 5 Boolean indexing을 적용 
array3 = array1d[array1d > 5]
print('array1d > 5 불린 인덱싱 결과 값 :', array3)

array1d > 5
더보기
array1d > 5 불린 인덱싱 결과 값 : [6 7 8 9]

array([False, False, False, False, False,  True,  True,  True,  True])

코드 실행 결과 추가 설명 및 시각화


 

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

sort()
  • np.sort( ) : 원 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬 반환
  • ndarray.sort( )로 정렬 : 원 행렬 자체를 정렬한 형태로 변환하고, 반환 값은 None
  • np.sort(), ndarray.sort() 둘 다 기본 오름차순
  • 내림차순 하고 싶을 경우, np.sort()[::-1]
  • 행렬이 2차원 이상일 경우에 axis 축 값 설정을 통해 로우(axis=0), 컬럼(axis=1) 방향으로 정렬 수행 가능 

 

argsort()
  • 정렬 행렬의 인덱스 반환
  • 원본 행렬이 정렬되었을때 기존 원본 행렬의 원소에 대한 인덱스를 필요로 할 때 np.argsort() 사용
  • np.argsort()는 정렬 행렬의 원본 행렬 인덱스를 ndarray 형으로 반환

 

 

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

 

  • 행렬내적
A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([[7, 8],
              [9, 10],
              [11, 12]])

dot_product = np.dot(A, B)
print('행렬 내적 결과:\n', dot_product)
더보기
행렬 내적 결과:
 [[ 58  64]
 [139 154]]

 

  • 전치 행렬
A = np.array([[1, 2],
              [3, 4]])
transpose_mat = np.transpose(A)
print('A의 전치 행렬:\n', transpose_mat)
더보기
A의 전치 행렬:
 [[1 3]
 [2 4]]