해당 내용은 아래의 유튜브 강의 시리즈를 정리한 내용이다.
https://www.youtube.com/watch?v=vcCaSBJpsHk&list=PLS8gIc2q83OjStGjdTF2LZtc0vefCAbnX
1.1 파이썬 데이터 타입
list [ ]
- 다른 언어의 array와 비슷. 마이너스 인덱스를 지원하기 때문에 리스트의 역순부터 참조 가능하다.
A = [1,2,3,4,5]
다음과 같은 경우, A[0] = 1, A[-1] = 5이다.
- 리스트의 각 요소마다 데이터 타입을 다르게 생성할 수 있다
A = [1, 2, "hello", [True, 3]]
- 콜론 (:) 을 이용한 슬라이싱 기능이 존재
A = [1,2,3,4,5]
다음과 같은 리스트의 경우
* A[0:2] → [1,2]
* A[:3] → [1,2,3]
* A[:-2] → [1,2,3]
* A[:] → [1,2,3,4,5]
tuple ( )
리스트와 거의 비슷하지만 한번 생성된 튜플은 데이터를 변경할 수 없는 read-only 데이터 타입이다.
리스트와 동일하게 슬라이싱 등의 기능 사용 가능
dictionary { }
다른 언어의 해시, 맵 등과 구조가 비슷하다.
key-value 데이터 타입이고 데이터가 순차적으로 들어가지 않는다.
score = {"KIM" : 90, "LEE" : 85, "JUN" : 95}
- 딕셔너리 key, value 접근
keys(), values(), items() 메서드를 통해서 딕셔너리 값을 원하는 포맷으로 가져올 수 있다.
자주 사용하는 함수
* type(data) → data의 데이터 타입 반환
* len(data) → data의 요소의 개수(데이터길이) 반환
* size(data) → data의 모든 원소 개수 반환
⇒ A = [ [1,2], [3,4], [5,6] ]
다음과 같은 경우, len(A)는 3이지만 size(A)는 6이다. * list(data) → 입력 data를 리스트로 만들어서 반환
* str(data) → 입력 data 문자열 반환
* int(data) → 입력 data(문자열, 실수) 형태를 정수로 반환
1.2 파이썬 조건문, 반복문
파이썬은 코딩블럭을 표현하기 위해서 indentation을 사용 (공백 수가 동일해야함)
조건문
* if condition :
a=1
if a > 0:
do
elif a == 0:
do
else:
do
* if condition in list, dict :
list_data = [1,2,3,4,5]
dict_data = {'k1': 1, 'k2' : 2}
if 4 in list_data:
else:
if 'k1' in dict_data
else:
반복문
* for variable in range(...):
⇒ range(10) : 0~9
⇒ range(0,10) : 0~9
⇒ range(0,10,2) : 0,2,4,6,8
* for variable in list, dict:
⇒ 딕셔너리를 for문으로 표현할 때 다음과 같이 사용할 수 있다.
for key, value in dict_data.items():
* list comprehension (머신러닝에서 많이 사용되는 방법)
리스트의 [ ] 괄호 안에 for루프를 사용해서 반복표현으로 리스트 요소 정의
row_data = [ [1, 10], [2,15], [3,30], [4,55] ]
all_data = [x for x in raw_data ] => [ [1, 10], [2,15], [3,30], [4,55] ]
x_data = [x[0] for x in raw_data ] => [1,2,3,4]
y_data = [x[1] for x in raw_data ] => [10,15,30,55]
* while, break, continue
1.3 파이썬 함수, 람다
def 함수명 (입력1, 입력2...):
다음과 같이 정의해서 사용 → 입력 파라미터 데이터타입 기술 X
- 파이썬에서는 1개 이상의 함수 반환값을 받을 수 있다.
def multi_ret_func(x):
return x+1, x+2, x+3
x = 100
y1, y2, y3 = multi_ret_func(x) # 101, 102, 103
디폴트 파라미터, mutable, immutable 파라미터
숫자, 문자, tuple등 원래 immutable한 데이터 타입은 함수내에서 변형이 일어나지 않는다
#디폴트 파라미터
def print_name(name, count=2):
for i in range(count):
print(name)
print_name("DAVE") # count가 디폴트로 2로 초기화 되기 때문에 두번 출력
#mutable immutable 파라미터
def func(x, input_list):
x += 1
input_list.append(100)
x=1
test_list = [1,2,3]
func(x, test_list) # x는 변하지 않고, list는 100이 추가됌
람다 (익명함수)
한줄로 함수를 작성할 수 있다. 다른 함수의 파라미터로 함수값을 넣을때 주로 사용하며, 머신러닝에서는 미분을 계산하기 위해 필요한 수치 미분과 활성화 함수 등을 표현할 때 사용한다.
함수명 = lambda 입력1, 입력2... : 대체되는 표현식
⇒ 입력 값이 모두 대체되는 표현식에서 사용되지 않아도 된다.
f = lambda x : x+10
for i in range(3):
print(f(i)) # 10, 11, 12
1.4 파이썬 클래스
class 클래스명:
def __init__(self, 인수, ...): # 생성자
def 메서드명(self, 인수, ...): #메서드, 파이썬에서는 메서드 첫번째 인수로 self 필수!!
파이썬에서는 기본적으로 모든 메서드와 속성이 public이다.
파이썬에서는 기본적으로 멤버변수를 따로 선언하지 않는다.
클래스변수, 클래스 메서드
클래스 변수와 메서드는 해당 클래스로 생성된 모든 인스턴스가 공통적으로 사용
class Person:
count = 0 #클래스 변수 (클래스 내에서 선언과 초기화 작업)
@classmethod
def getCount(cls): #클래스 메서드 (인수로 self가 아니라 class를 나타내는 cls를 받는다)
return cls.count
파이썬에서의 멤버변수, 메서드 private 선언
기본적으로는 모두 public 접근자로 선언된다. 다만 멤버변수, 메서드 선언을 __멤버변수, __메서드 형태로 하면 private설정이 가능하다
class Test:
def __init(self, name1, name2):
self.name1 = name1
self.__name2 = name2
def getNames(self):
self.__printNames()
return self.name1, self.__name2
def __printNames(self):
print(self.name1, self.__name2)
#생성된 객체를 통해서 __printNames 메서드를 호출하려고 하면 error발생
외부함수명과 클래스 내부의 메서드명이 같은 경우
self의 유무에 따라서 호출되는 메서드가 달라진다.
def print_name(name):
print("OUTTER")
class Test:
def __init__(self):
pass
def print_name(self, name):
print_name("name") # 외부의 함수 호출
self.print_name("name") # 내부 메서드 호출
1.5 Numpy 라이브러리
import numpy as np
Numpy를 임포트해와서 사용하도록 한다. Numpy는 벡터(행과 열을 구분하지 않는 1차원 배열), 행렬 등의 표현, 연산을 할때 필요한 라이브러리이다.
np.array([1,2,3])
⇒ 해당 명령어는 list와 비슷해보이지만 다른 1차원 벡터를 생성한다.
A.shape
→ 해당 벡터, 행렬의 형상 출력 (3,)
A.ndim
→ 해당 벡터, 행렬의 차원 출력 1
A.reshape
→ 형 변환, 벡터를 행렬로 변경하거나 행렬을 다른 형상의 행렬로 변경하기 위해서 사용
행렬곱(dot product)
np.dot(A,B)
A의 열 벡터와 B의 행 벡터가 같아야 행렬곱을 수행할 수 있다. 같지 않다면 reshape()
혹은 transpose
를 사용해서 형 변환 이후에 행렬곱을 실행하면 된다.
A = np.array([ [1,2,3], [4,5,6] ]) # 2X3
B = np.array([ [-1,-2], [-3,-4], [-5,-6] ]) # 3X2
C = np.dot(A,B)
/*
[[-22 -28]
[-49 -64]]
*/
* 그렇다면 왜 행렬곱이 머신러닝, 이미지 프로세싱 분야에서 자주 사용되는가?

기본적으로 사칙연산은 행렬의 원소의 개수가 같아야 연산이 가능한 반면에, 행렬곱은 A*B 연산 시, A의 열 벡터, B의 행 벡터가 같으면 연산이 가능하므로 위의 예시처럼 다양한 특성을 갖는 필터를 붙여 계산을 할 수 있다.
브로드캐스트
보통 행렬의 사칙연산은 두 행렬의 크기가 같은 경우에만 수행할 수 있지만 Numpy에서는 크기가 다른 두 행렬간에도 사칙연산을 수행할 수 있도록 지원한다. ⇒ 브로드캐스트
차원이 작은 쪽이 큰 쪽의 행 단위로 반복적으로 크기를 맞춘 후, 계산을 진행한다.
A = np.array([ [1,2], [3,4] ])
B = np.array([4,5])
b = 5
/* A+b
[[6 7]
[8 9]]
*/
/* A+B
[[5 7]
[7 9]]
*/
전치행렬(transpose)
원본 행렬의 열은 행으로, 행은 열로 바꾸는 연산
vector의 경우, transpose 연산이 불가능하므로 이를 matrix로 변경 후, 연산을 하도록 한다.
A = np.array([ [1,2], [3,4], [5,6] ])
B = A.T
/* B
[[1 3 5]
[2 4 6]]
*/
C = np.array([1,2,3]) #행렬이 아닌 벡터이다
C = C.reshape(1,3) #1X3 행렬로 변환
E = C.T
/*E
[[1]
[2]
[3]]
*/
행렬 인덱싱/슬라이싱
행렬의 원소에 명시적으로 접근하기 위해서는 list와 비슷하게 인덱싱/슬라이싱을 통해서 할 수 있다.
A가 np.array([1,2,3,4,5,6]).reshape(3,2)
연산의 결과라고 가정한다.
* A[0][0] → 1
* A[2][1] → 6
* A[0:-1 , 1:2] →
[ [2]
[4] ]
행렬 iterator
위의 인덱싱/슬라이싱을 통한 명시적 행렬 원소 접근 이외에 모든 원소를 액세스하는 경우에는 iterator를 사용할 수 있다.
A = np.array([[1,2,3,4],[5,6,7,8]])
#iterator 생성
it = np.nditer(A, flags=['multi_index'], op_flag=['readwrite'])
while not it.finished:
idx = it.multi_index
#A[idx]로 행렬 원소 액세스 가능
it. iternext()
concatenate 함수
행렬에 행, 열을 추가
⇒ 머신러닝의 regression코드 구현 시 가중치, bias를 별도로 구분하지 않고 하나의 행렬로 취급하기 위해서 사용한다.
A = np.array([[1,2,3],[4,5,6]])
row_add = np.array([7,8,9]).reshape(1,3) #추가하려는 행
col_add = np.array([11,22]).reshape(2,1) #추가하려는 열
B = np.concatenate((A, row_add), axis=0) #행 추가
C = np.concatenate((A, col_add), axis=1) #열 추가
유용한 함수(1) : loadtxt()
seperator로 구분된 파일에서 데이터를 읽기 위한 함수, ex) np.loadtxt("파일이름", seperator=",")
반환값이 행렬이기 때문에 인덱싱/슬라이싱을 통해서 원하는 데이터를 분리한다. 보통 머신러닝 구현 시, 입력데이터와 정답데이터 분리할 때 자주 사용한다.
# 25X4행렬로 가정
loaded_data = np.loadtxt('./data.csv', delimiter=',', dtype=np.float32)
x_data = loaded_data[ :, 0:-1] #모든 row의 0~ -2인덱스까지 (0,1,2)
t_data = loaded_data[ :, [-1]] #모든 row의 -1인덱스만 (3)
유용한 함수(2) : rand(), sum(), exp(), log()
* rand()
랜덤 값 발생. np.random.rand( shape값 넣는다 )
ex) np.random.rand(1,3)
→ 1X3행렬에 랜덤값 생성
* sum()
np.sum(X) → X의 모든 요소의 합 반환
유용한 함수(3) : max(), min(), argmax(), argmin()
min, max는 데이터가 벡터인 경우에 원소중 max,min값을 반환한다.
* argmax, argmin (이후 classification에서 사용)
벡터에서 최대, 최소값이 있는 곳의 인덱스를 리턴 해준다.
행렬에서는 최대, 최소값을 찾는 기준을 정해야 한다(행 → axis=1 or 열 → axis=0)
ex) np.argmax(X, axis=0)
유용한 함수(4) : ones(), zeros()
해당 함수들은 파라미터로 주어진 shape에 따라서 요소가 모두 1 혹은 0인 행렬을 만든다
ex) A = np.ones([3,3])
인 경우, 3X3의 요소가 모두 1인 행렬이 반환된다.
'머신러닝' 카테고리의 다른 글
[머신러닝/딥러닝] 0. 유튜브 강의 선택, 인트로 (0) | 2020.06.10 |
---|