본문 바로가기
파이썬/Pandas & Numpy

실습) 행렬 norm이란? 배워서 어디다 쓰게?

by Bentist 2020. 3. 12.

Norm (위키백과 정의)

: 벡터의 길이 혹은 벡터의 크기를 나타낸다. 이를 행렬로 확장하면 다음의 식으로 정의된다.

쉽게 말해서 행렬에서 크기를 구하는 방법 중 하나라고 생각하면 된다.

 

 

보통 p값으로 1 또는 2(프로베니우스 놈)을 가장 많이 사용하므로, 수식을 정의 한 뒤 실습을 진행해보겠다.

p = 1인 놈을 보통 L1 Norm, p = 2인 놈은 L2 Norm으로 쓴다. 

L2 Norm은 우리가 알고 있는 Euclidean Norm라고도 부르며, 두 점의 거리를 구할 때 제곱한 것을 다 더해서 루트를 씌워주었던 바로 그것이다. 프로베니우스 놈(Frobenius norm)은 vector L2 Norm을 행렬로 확장한 버전이다.

 

L1 Norm: 절대값의 합

L1 Norm 행렬에서의 계산 방식

L2 Norm: 원점과의 거리(피타고라스 정리를 이용하여 벡터의 길이를 구하는 기본적인 방법과 같음)

 

이제 numpy를 사용하여 주피터 노트북 환경에서 실습을 해보자.

L1 Norm : 숫자 상자를 던져, 계단 오르내리기 (-3부터 +3) 문제

1) -3이 나오면 아래로 3칸, +3이 나오면 위로 3칸 올라간다.

2) 총 3명의 사람이 상자를 던질 것이다. (행: 참여자)

3) 3번씩 던질 것이다. (열: 횟수)

 

아래 데이터프레임은 이해를 돕기 위해 만든 것이고, 실제 계산은 data 변수를 사용할 것이다.

1) 누가 많이 오르내렸을까?

이때 사용되는 개념이 L1 Norm 이다. (절대값의 합이기 때문에!) numpy의 linalg 패키지를 사용하여 계산을 진행한다.

아래는 np.linalg.norm(xord=Noneaxis=Nonekeepdims=False) 파라미터 설명

 

x : 배열을 입력한다. 만약 axis가 none이면 x는 1차원이나 2차원이다.

ord : N1 Norm: ord=1, N2 Norm: ord=2

axis : {정수, 정수의 2 튜플, None}, optional

axis가 정수이면, 벡터 노름을 계산할 x의 축을 지정한다. axis가 2-튜플이면 2차원 매트릭스를 유지하는 축을 지정하고, 이 매트릭스 노름이 계산된다. axis가 None면 벡터 노름(x가 1차원인 경우) 또는 매트릭스 노름(x가 2차원인 경우) 이 반환된다.

keepdims : (bool, optional) 만약 이 파라미터가 참이면, 표준화된 축이 1의 크기로 남는다. 이 옵션과 함께 결과는 오리지널 x에 따라 명확하게 반환된다.

 

첫번째 코드는 위의 L1 Norm 수식 정의대로, 열방향 절대값의 합 중에서 가장 큰 값을 하나 출력했다. 

그러나 우리는 참여자를 행에 두었기 때문에 axis=1을 써서 행방향 절대값의 합을 구해야 한다.

 

해석: Benn이 제일 많이 오르내림(총 6번)을 알 수 있다.


L2 Norm : (0, 0)에서 가장 가까운 점 찾기 문제

1) 원점(0, 0)과의 거리를 측정하기 위한 3명의 사용자 위치 정보가 있는 데이터프레임을 생성하였다. 

2) x, y의 좌표를 기준으로 시각화를 해보자. ( * scatter_kws={'s': 200}의 숫자 값이 커질수록, 점의 크기가 커짐 )

3) 계산을 용이하게 하기 위해서 데이터프레임 값을 array 배열로 변환 후,

   L2 Norm적용해보면 원점(0, 0)과의 거리가 계산되어 나오는 것을 볼 수 있다.

 

해석: 시각화에서처럼 (2, 6)이 6.32455로 제일 가깝고, (9, 6)이 10.81665제일 거리가 멀다.

 

정리하면, L2 Norm벡터의 길이(거리)를 의미하는 것으로 머신러닝에서는 유클리디언 디스턴스로 불리며,

KNN 알고리즘Kmeans 알고리즘에서 사용된다. 

위 두 개의 알고리즘은 데이터들을 벡터화시켜서 데이터들 사이의 거리를 측정해서 거리가 가까울수록 서로 유사하다고 보며, 유사한 데이터들끼리 묶어서 분류를 하는 방법이다.


보충) 벡터화한 A, B의 유사도 구하는 방법

Euclidean Norm(거리 기반) VS Cosine Similarity(각도 기반)

1) Euclidean Norm(거리 기반)

: 데이터들 사이의 거리가 가까우면 서로 유사하다고 판단.

2) Cosine Similarity(각도 기반)

: 기울기가 같은, 즉 방향이 같은 벡터들이 서로 유사하다고 판단.

 

그럼 어떤 걸 써야 유사도를 잘 나타낼 수 있을까?

· 벡터값의 차이가 크지 않다면, 거리 기반 유사도(유클리디안 유사도)

· 벡터값의 차이가 크다면, 각도 기반 유사도(코사인 유사도)

(1, 2)과 (0, 6)의 유사도가 더 높음에도 불구하고, 유클리디언에서는 (1, 2)과 (1, 0)의 유사도가 더 높다는 결과가 나오게 된다. 그래서 벡터의 크기가 커지게 되면 거리가 점점 더 늘어나기 때문에 크기를 무시하고, 벡터의 방향만 측정하는 방법인 코사인 유사도을 사용하게 된다.


유클리디안 유사도 실습

 

그럼 L2 Norm(유클리디안 유사도)을 활용하여 '유사한 게시물 찾기' (군집 만들기) 실습을 해보겠다.

(Building Machine Learning Systems with Python - Second Edition 서적 54p 참고)

1. 카운트 벡터 생성하기( 벡터화: 단어를 숫자로 바꿔주는 과정 )

군집을 만들기 위해 가장 적절한 방법은 게시물마다 등장하는 단어의 빈도수를 파악해 하나의 카운트 벡터로 만든다.

카운트 벡터 생성 후 해당 게시물과 다른 게시물 사이의 벡터 거리를 계산하여 게시물 사이의 유사도를 파악한다.

 

scikit-learn에서 단어를 token count matrix로 변환해주는 CountVectorizer함수를 import한다.

 

scikit-learn의 텍스트로부터 수치형 벡터 추출 과정

  • tokenizing : 문자나 숫자를 공백이나 기호로 구분하여 분리
  • counting : 각 문서에서 토큰의 발생을 카운트함
  • normalizing : 토큰의 발생횟수에 가중치를 부여
  • corpus(단어장)는 행렬에 숫자벡터로 표현된다.

함수의 매개변수 min_df 값은 해당 값보다 낮은 빈도수의 단어는 모두 무시한다는 뜻이다.

min_df = 1은 단어장(문서)에 1개 미만으로 나타나는 단어는 무시. 즉, 1개라도 있으면 토큰화 진행

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(min_df=1)

문서를 token count matrix로 변환해주는 vectorizer.fit_transform(list of str ) 기능을 잠깐 알아본다.

알아보기 쉽게 벡터화한 단어장으로 데이터프레임을 만들어보았다.

ex. vectorizer = CountVectorizer(min_df=2) 일 때, 빈도수가 2번 미만인 단어는 무시.

 

댓글