💡 머신러닝의 주요 알고리즘은 선형대수와 통계 등에 기반한다

  • Numpy파이썬에서 선형대수 기반의 프로그램을 쉽게 만들 수 있도록 지원하는 대표적인 패키지
    • 루프를 사용하지 않고 대량 데이터의 배열 연산을 가능하게 하므로 빠른 배열 연산 속도를 보장
    • C/C++과 같은 저수준 언어 기반의 호환 API 제공
  • 넘파이를 이해하는 것은 파이썬 기반의 머신러닝에서 매우 중요
    • 많은 머신러닝 알고리즘이 넘파이 기반으로 작성돼 있음은 물론이고, 이들 알고리즘의 입력 데이터와 출력 데이터를 넘파이 배열 타입으로 사용
  • Numpy API
    • Numpy 라이브러리의 기능(예: 배열 생성, 연산, 통계 계산 등)을 사용할 수 있게 해주는 함수와 클래스, 메서드들의 집합
    • 쉽게 말해, Numpy가 제공하는 도구들이 바로 Numpy API
    • 하지만, 넘파이는 판다스에 비해서 친절한 API를 제공하지 않음
      • 2차원의 데이터라면 데이터 가공을 위해서 넘파이보다는 판다스를 이용하는 것이 효율적!

▫︎ 1. 넘파이 ndarray 개요

💡 ndarray : 넘파이의 기반 데이터 타입
ndarray를 이용해 넘파이에서 다차원(Multi-dimension) 배열을 쉽게 생성하고 다양한 연산 수행 가능

  • np.array() 메서드 : 파이썬의 리스트와 같은 다양한 인자를 입력받아서 ndarray로 변환하는 기능 수행
    • 생성된 ndarray 배열의 shape변수는 ndarray의 크기, 즉 행과 열의 수를 tuple 형태로 가지고 있으며 이를 통해 ndarray 배열의 차원까지 알 수 있음
		array1 type: <class 'numpy.ndarray'>
		array1 array 형태: (3,) # 1차원 데이터 (3개 데이터)
		array2 type: <class 'numpy.ndarray'>
    	array2 array 형태: (2, 3) # 2행 3열의 2차원 데이터 (6개 데이터)
		array3 type: <class 'numpy.ndarray'>
		array3 array 형태: (1, 3) # 1행 3열의 2차원 데이터 (3개 데이터)
  • ndarray 객체의 속성(attribute)
    • ndarray.shape : 배열의 모양(각 차원의 크기)을 tuple로 반환
    • ndarray.ndim : 배열의 차원 수 반환
    • ndarray.size : 배열의 전체 원소 개수 반환
    • ndarray.dtype : 배열 원소의 데이터 타입
    • ndarray.itemsize : 배열의 각 원소가 메모리에서 차지하는 바이트(byte) 크기 반환
    • ndarray.nbytes : 배열의 전체 데이터가 차지하는 메모리 크기(byte) 반환
    • ndarray.T : 배열의 전치(transpose) 반환

▫︎ 2. ndarray의 데이터 타입

💡 ndarray 내의 데이터값숫자 값, 문자열 값, 불 값 등이 모두 가능

  • ndarray 내의 데이터 타입은 그 연산의 특성상 같은 데이터 타입만 가능

    • 즉, 한 개의 ndarray 객체에 int와 float가 함께 있을 수 없음!
    • 만약 다른 데이터 유형이 섞여 있는 리스트를 ndarray로 변경하면 데이터 크기가 더 큰 데이터 타입으로 형 변환을 일괄 적용
  • ndarray.astype() 메서드 : ndarray 내 데이터값의 타입 변경

    • astype()인자로 원하는 타입을 문자열로 지정

▫︎ 3. ndarray를 편리하게 생성하기 - arange, zeros, ones

💡 특정 크기와 차원을 가진 ndarray를 연속값이나 0 또는 1로 초기화해 쉽게 생성해야 할 필요가 있는 경우가 발생할 수 있음

  • 주로 테스트용으로 데이터를 만들거나 대규모의 데이터를 일괄적으로 초기화해야 할 경우에 사용
  • np.arange()

    • 파이썬 표준 함수인 range()와 유사한 기능
    • 쉽게 생각하면 array를 range()로 표현하는 것!
    • 0부터 함수 인자 값 -1까지의 값을 순차적으로 ndarray의 데이터값으로 변환
    • np.arange(start, stop, step) : step에서는 소수점 간격도 가능!
  • np.zeros()

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

    • 함수 인자로 튜플 형태의 shape 값을 입력하면 모든 값을 1로 채운 해당 shape을 가진 ndarray를 반환

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

💡 reshape()

  • ndarray를 특정 차원 및 크기로 변환
  • 변환을 원하는 크기를 함수 인자로 부여
  • reshape()를 실전에서 더욱 효율적으로 사용하는 경우는 인자로 -1을 적용하는 경우!

    • row인자와 column인자 중 하나를 -1로 두면 지정한 다른 인자에 맞춰 자동으로 새롭게 생성해 변환하라는 의미
  • -1 인자reshape(-1, 1)와 같은 형태로 자주 사용됨
    - reshape(-1, 1)은 원본 ndarray가 어떤 형태라도 2차원이고, 여러 개의 로우를 가지되 반드시 1개의 column을 가진 ndarray로 변환됨을 보장!

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

  1. 특정한 데이터만 추출
    • 원하는 위치의 인덱스 값을 지정하면 해당 위치의 데이터가 반환
  2. 슬라이싱(Slicing)
    • 연속된 인덱스상의 ndarray를 추출하는 방식
    • ‘:’ 기호 사이에 시작 인덱스와 종료 인덱스를 표시하면 시작 인덱스에서 종료 인덱스-1 위치에 있는 데이터의 ndarray 반환
  3. 팬시 인덱싱(Fancy Indexing)
    • 일정한 인덱싱 집합을 리스트 또는 ndarray 형태로 지정해 해당 위치에 있는 데이터의 ndarray 반환
  4. 불린 인덱싱(Boolean Indexing)
    • 특정 조건에 해당하는지 여부인 True/False 값 인덱싱 집합을 기반으로 True에 해당하는 인덱스 위치에 있는 데이터의 ndarray 반환

1. 단일 값 추출

  • 1개의 데이터값을 선택하려면 ndarray 객체에 해당하는 위치의 인덱스 값을 [] 안에 입력
  • 다차원 ndarray에서 단일 값 추출

<axis 축 이해하기>

numpy에서의 ‘차원’은 axis의 개수를 의미!
쉽게 이해하자면 axis‘너의 상위 배열이 몇 개?’

ex) [[1, 2, 3], [4, 5, 6]]

  • [1, 2, 3]의 경우 상위 배열인 [[1, 2, 3], [4, 5, 6]]이 있으므로 [1, 2, 3]axis = 1
  • 따라서 axis = 1로 sum을 하면 [1, 2, 3]에 해당하는 배열의 합을 의미
  • 즉, axis = 0 (수직 연산) axis = 1 (수평 연산)
  • axis 연산
    - axis = 0 : row 방향 축 (행 방향으로 동작)
    - 책을 위로 쌓아 정리하는 것과 같음
    - np.sum(ary, axis = 0)
    - axis = 1 : column 방향 축 (열 방향으로 동작)
    - 책을 옆으로 정리하는 것과 같음
    - np.sum(ary, axis = 1)
  • 3차원 배열에서의 axis 개념
    • 3차원 이상의 배열에서는 축이 추가

2. 슬라이싱

  • :’ 기호를 이용해 연속한 데이터를 슬라이싱해서 추출
  • 단일 데이터값 추출을 제외하고 슬라이싱, 팬시 인덱싱, 불린 인덱싱으로 추출된 데이터 세트는 모두 ndarray 타입
    이미지1 이미지2

  • 2차원 ndarray에서 뒤에 오는 인덱스를 없애면 1차원 ndarray 반환

3. 팬시 인덱싱

  • 리스트나 ndarray로 인덱스 집합을 지정하면 해당 위치의 인덱스에 해당하는 ndarray 반환

    이미지1 이미지2
  • array2d[ [0, 1] , 2 ] → 인덱스가 (0, 2), (1, 2)에 해당하는 [3, 6] 반환

  • array2d[ [0, 1] , 0:2 ] → 인덱스가 (0, 0), (0, 1), (1, 0), (1, 1)에 해당하는 [[1, 2], [4, 5]] 반환

  • array2d[ [0, 1] ] → ((0, :), (1, :)) 인덱싱이 적용돼 [[1, 2, 3], [4, 5, 6]] 반환 (생략되면 : 에 해당함)

4. 불린 인덱싱

  • 조건 필터링검색동시에 가능하기 때문에 매우 자주 사용
  • 1차원 ndarray [1, 2, 3, 4, 5, 6, 7, 8, 9]에서 데이터값이 5보다 큰 데이터만 추출하려면?
    이미지1 이미지2
  • 불린 인덱싱이 동작하는 단계

▫︎ 6. 행렬의 정렬 - sort()와 argsort()

numpy에서 행렬 정렬

  • np.sort()
    • 넘파이에서 sort()를 호출하는 방식
    • 원 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬 반환
  • ndarray.sort()
    • 행렬 자체에서 sort()를 호출하는 방식
    • 원 행렬 자체를 정렬한 형태로 변환하며 반환 값은 None
이미지1 이미지2
  • np.sort()ndarray.sort() 모두 기본적으로 오름차순으로 행렬 내 원소 정렬
    • 내림차순으로 정렬하기 위해서는 [::-1] 적용
    • np.sort()[::-1]
  • 행렬이 2차원 이상일 경우에 axis 축 값 설정을 통해 row 방향, column 방향으로 정렬 수행 가능!
  • 정렬된 행렬의 인덱스 반환
    • np.argsort
    • 원본 행렬이 정렬되었을 때 기존 원본 행렬의 원소에 대한 인덱스를 필요로 할 때 사용
    • 즉, 정렬된 행렬의 원본 인덱스를 반환하는 것!
      마찬가지로 내림차순 정렬 시에 원본 행렬 인덱스를 구하는 것도 np.argsort()[::-1] 사용
      이미지1 이미지2
    • np.argsort() 활용
      - 시험 성적순으로 학생 이름 출력
      이미지1 이미지2

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

행렬 내적 (행렬 곱)

  • 행렬 내적은 행렬 곱이며, 두 행렬 A와 B의 내적은 np.dot()을 이용

전치 행렬

  • 원 행렬에서 행과 열의 위치를 교환한 원소로 구성한 행렬
  • np.transpose() 이용
  • 2차원에서는 ndarray.T로 사용 가능

본 글은 <파이썬 머신러닝 완벽 가이드>를 기반으로 작성되었습니다.

profile
DataScience

0개의 댓글