본문 바로가기
소프트웨어/데이터 분석

실전 데이터 분석 2주차

by 도지선다형 2025. 4. 8.

13장 텍스트 유사성

 

자연어 처리

  • 빠른 텍스트 분석에 중점을 둔 데이터 과학의한 분야
  • 일반적으로 대량의 텍스트 데이터셋에 적용되는 편
  • 텍스트 간 유사점과 차이점을 분석하는 데 의존적이다.

 

 텍스트 비교

  • 텍스트 간 유사도를 비교하려면 텍스트 간 차이를 정량화 해야한다.
  • 기본 접근법 : 각 텍스트 쌍에 공유되는 단어 수를 단순히 계산하는 것.
  • 각 텍스트를 단어 단위로 분할하여 단어 리스트를 만들어야 한다.
  • 토큰화 : 텍스트를 개별 단어로 분할하는 과정

 

정확한 단어를 비교하는 것이 불가능한 이유

  1. 일관성 없는 대문자
  2. 일관성 없는 구두점(특수문자 등)

 

합집합 : 텍스트 간 겹치는 단어와 겹치지 않는 단어를 모두 결합할 때 사용

 

 

 

 

두 텍스트의 유사성을 평가하는 간단한 지표의 작동 방식( 자카드 유사도 혹은 자카드 지수 )

  1. 두 텍스트가 주어졌을 때 각 텍스트에서 단어 리스트를 추출한다.
  2. 텍스트 간 공유되는 고유 단어 수를 센다
  3. 공유 단어 수를 두 텍스트의 총 고유 단어 수로 나눈다.

자카드 유사도는 전체 단어 수에 대한 교집합 비율과 같다.

 

 

 

자카드 유사도가 텍스트의 유사성을 합리적으로 측정하는 척도인 이유

  1. 텍스트 간 겹치는 단어와 겹치지 않는 단어를 함께 고려한다.
  2. 항상 0과 1 사이로 표현되며 해석이 쉽다. 0 = 공유 단어 없음. 0.5 = 절반의 단어가 공유됨. 1 = 모든 단어가 공유됨.
  3. 쉽게 구현할 수 있다.

 

단어를 숫자 값으로 바꾸기

→ 단어와 숫자 값 간의 매핑 정ㅇ보는 파이썬의 딕셔너리로 저장할 수 있으며, 정보를 담은 딕셔너리를 어휘라고 한다.

 

텍스트의 합집합에 있는 모든 단어에 번호를 매길 때 임의의 단어를 꺼내서 번호를 할당한다. 이 기법을 '단어 가방 기법'이라함.

 

 

벡터 : 1차원 숫자 배열을 수학적으로.

텍스트의 벡터화 : 텍스트를 벡터로 변환하는 과정

 

텍스트를 벡터화 하는 가장 간단한 방법

  • 이진 요소로 구성된 벡터를 만드는 것
  • 이 벡터의 각 인덱스는 어휘 내 한 단어에 연결됨
  • 연결된 텍스트에서 일부 어휘 단어가 누락되더라도 벡터 크기는 어휘 크기와 같다.
  • i 인덱스의 단어가 텍스트에서 누락된 경우 벡터의 i번째 오소는 0으로 설정되며 그렇지 않다면 1로 설정된다.
  • 벡터 내 모든 단어에 대한 인덱스에는 0 또는 1값이 할당된다.

 

 

이진 벡터화로 모든 텍스트를 넘파이 배열로 변환.

시본 라이브러리를 활용해 테이블을 히트맵으로 시각화.

  • 테이블을 이용해 어떤 단어가 어떤 텍스트 간 공유되는지 쉽게 알 수 있다.
  • 이진 벡터 표현은 공유 단어를 숫자로 추출할 수 있게 해 준다.

내적 : 벡터의 요소별 곱을 모두 더하는 것

  • 내적을 이용해 공유된 단어 수를 구할 수 있다.
  • 교집합의 크기와 일치한다.

타니모토 유사도 : 벡터화된 텍스트로 자카드 유사도를 구현한 것

 

 

 

 

단어 수를 사용하여 텍스트 벡터화하기

두 텍스트가 있을 때 등장 횟수를 바탕으로 어떤 단어가 중요한지, 어떤 주장을 펼칠지 추측 가능하다.

 

용어 빈도 벡터(TF 벡터) : 단어 수 벡터

  • 이진 값을 단어 수로 바꾸면 유사도 출력을 크게 바꿀 수 있다.
  • TF 벡터화는 두 텍스트의 선호도를 더욱 뚜렷하게 만든다.
  • TF 벡터는 텍스트 간 단어 수 차이에 민감하기 때문에 향상된 비교 결과를 제공한다.
  • 길이가 다른 텍스트를 비교할 때는 불리할 수 있다 → 이를 정규화로 해결 가능하다..

 

 

 

 

 

정규화로 TF벡터 유사도 개선하기

  • 검색 엔진에선 크기 신호가 잘못된 순위로 이어질 수 있다.
  • 텍스트 크기가 순위 결과에 미치는 영향을 억제할 필요가 있다.
  • 한 가지 간단한 접근법 : title_a_vector 를 3으로 나누는 것이다.

 

 

벡터를 선분으로 시각화하면?

  • 각 선분들은 기하학적인 길이를 가짐.
  • 모든 벡터가 기하학적인 길이를 가지며 이를 크기라고 함.
  • 크기를 유클리드 노름 또는 L2 노름이라고 함.

 

 

 

단위 벡터 : 크기가 1인 벡터

장점 : 비교가 쉽다. 단위 벡터 간 차이는 방향에 따라서만 결정된다.

 

정규화 : 어떤 벡터든 자기 자신의 크기로 나누는 것 

v / norm(v)를 사용해 크기가 1인 정규화된 벡터를 얻을 수 있다.

 

벡터 정규화는 타니모토 유사도를 더 효율적으로 개선시킬 수 있다.

 

 

두 벡터가 정규화되었다면 이들에 대한 타니모토 유사도는 유클리드 및 코사인 지표로 대체될 수 있다.

 타니모토 유사도와 유클리드 및 코사인 지표 측정값이 정규화된 내적과 매우 밀접히 관련되어 있기 때문이다.

 

 

 

 

단위 벡터 내적으로 관련성 지표 간 변환하기

기하학적으로 두 단위 벡터의 내적은 두 벡터 간 각도에 대한 코사인과 같다.

코사인 유사도 : 두 단위 벡터의 내적

코사인 유사도를 cs라고 했을 때, (2-2*cs) ** 0.5 와 cs / (2-cs) 를 계산하여 유클리드 거리와 타니모토 유사도로 변환할 수 있다.

 

 

 

 

 

정규화된 벡터 간 타니모토 유사도는 다른 유사도 또는 거리 지표로 변환될 수 있다. 이 변환이 유용한 이유는

  1. 타니모토 유사도를 유클리드 거리로 변환 시 텍스트 데이터에 대한 K-평균 클러스터링을 수행할 수 있다. 
  2. 타니모토 유사도를 코사인 유사도로 변환하면 계산을 간소화할 수 있다. 모든 계산이 간단한 내적 연산을로 축소된다.

 

 

 

 

정규화를 이용할 때 이점

  1. 텍스트 길이에 따른 차별성 제거
  2. 보다 효율적인 타니모토 유사도의 계산
  3. 모든 벡터 쌍들에 대한 보다 효율적인 유사도 계산

텍스트 간 유사도에 대한 테이블이 행렬 곱셈을 이용해 멋지게 계산될 수 있음!!

 

 

 

 

 

효율적인 유사도 계산을 위한 행렬 곱셈

 

어떤 텍스트 쌍이 가장 높은 유사도를 보이는지 즉시 알 수 있음.

중복된 연산을 행렬 곱셈을 이용해 제거하면 더 효율적임..

 

 

 

행렬 : 1차원 벡터를 2차원으로 확장한 것, 숫자를 테이블 형태로 표현한 것

 

 

 

 

 

 

 

행렬의 곱 : 벡터 내ㅐ적을 2차원으로 일반화한 것

 

 

 

 

 

 

전체 행렬에대한 유사도 계산하기

정규화된 단위 벡터와 그 단위벡터의 전치를 내적하면 단위 벡터스스로에 대한 코사인 유사도를 구할 수 있다. 물로 다 1로 채워짐...

이 코사인 값은 텍스트 사이의 단어 중복과 차이를 반영한 타니모토 값으로 변환될 수 있다.

 

 

타니모토 유사도 계산 일반화한 함수 구현

  1. 두 넘파이 배열을 입력받는다. 차원에 제한은 없다.
  2. 두 넘파이 배열에 @ 연산자를 적용한다. 두 배열이 행렬이라면 @ 연산자를 수행한 결과는 행렬 곱셈이 계산된 새로운 행렬을 반환한다.
  3. 산술 연산자로 행렬의 곱셈 결과를 수정한다. 산술 연산자는 숫자와 행렬 모두에 동일하게 적용될 수 있다.

 

 

행렬 곱셈의 계산 한계

행렬 곱셈의 계산 속도는 해애렬 크기에 따라 결정되므로 행렬이 커질수록 계산 시간도 매우 길어지게 된다.

그러므로, 어떻게든 실행 시간을 줄여야한다. 그 한 가지 접근법은 해ㅐㅇ렬 크기를 줄이는 것이다.

 

 

 

 

 

14 행렬 데이터의 차원 감소

차원 축소 : 데이터 정보 내용을 유지한 채 데이터를 축소하는 기술

 

차원 축소의 이점

  • 압축된 데이터는 전송과 저장이 더 쉽습니다.
  • 적은 데이터에 대한 알고리즘 수행 시간은 단축됩니다.
  • 데이터 그룹/클러스터를 파악하는 등 복잡한 작업에서 불필요한 노이즈 정보를 제거하여 복잡함을 간소화할 수 있습니다.

 

 

 

2D 데이터를 단일 차원으로 그룹화하기

  • 차원 축소는 클러스터링/그룹화를 보다 쉽게 해석하는 것을 포함해서 다양한 용도로 활용된다.
  • 클러스터링은 중심성 또는 평균까지 거리처럼 기술 개념에 의존할 수 없다.
  • 한 그림으로 설명할 수 있다면 가장 이상적일 것이다.
  • 차원축소는 이러한 수준의 단순성을 달성할 수 있게 해준다. 
  • 맷플롯립은 2D 축을 자동으로 조작해 그래프를 미적으로 보기 좋게 만듭니다.

 

그룹/클러스터를 구하는 한 방법은 K-평균을 활용하는 것이다.

그 대신 그래프를 옆으로 기울이는 비교적 덜 기술적인 해결책도 있다.

그래프가 수평으로 배치되면 다음 그림과 같이 두 수직선으로 세 부분으로 분리할 수 있다.

 

 

회전으로 차원 줄이기

데이터를 뒤집으로면 두 가지 단계별로 실행되어야 한다.

  1. 좌표 (0,0)의 원점을 중심으로 모든 데이터를 이동시킨다. 그러면 X축 방향으로 더 쉽게 회전시킬 수 있다.
  2. 데이터에서 X축까지 총 거리가 최소화될 때까지 데이터를 회전한다.

원점에서 데이터의 중심을 잡는것은 간단하다. 모든 데이터셋의 중심점은 평균과 같기 때문이다.

따라서 좌표를 조정해 X 값의 평균 및 Y 값의 평균이 모두 0이 되도록 해야한다. 이는 데이터 좌표에서 현재 평균을 빼면 가능하다.

 

 

2D 그래프를 중심을 기준으로 회전하려면 회전 행렬을 사용해야한다

 

 

 

 

이 이동을 정량화할 방법이 필요하다. 이를 위해 데이터가 X축을 향해 회전함에 따라 감소하는 페널티 점수를 생성한다.

모든 Y축 값에 페널티를 적용한다. 페널티는 제곱 거리 개념을 기반으로 한다.

페널티 제곱은 rotated_data의 y값 제곱들 평균과 같다. y값은 x축까지 거리를 나타내므로, 페널티는 x축까지 평균 제곱 거리와 같다. 즉, 회전된 데이터셋이 x축에 가까워지면 평균 제곱 y값은 감소한다. 페널티를 잘 받게 되는 것이다.

 

 

 

데이터를 회전하면서 페널티 점수가 20배 이상 감소했다. 이 감소는 통계적 해석이 수반되며 다음을 고려하면 페널티 분산에 연관지을 수 있다.

  • 페널티 점수는 0에서 y_value 배열 내 모든 y 까지 거리를 제곱한 평균과 같다.
  • 페널티 제곱은 평균에서 y까지 거리를 제곱한 평균과 같다.
  • 평균에서 거리를 제곱한 평균은 분산과 같다.

 

페널티 점수가 y축 분산과 같다고 추론했다. 결과적으로 데이터 회전으로 y축의 분산이 20뱁 이상 감소한 것이다.

 

분산을 기반으로 하여 회전 점수를 매길 수 있다. 데이터를 x축 방향으로 회전하면 y축의 분산은 감소할 것이다.

 

회전이 x축의 분산에는 어떤 영향을 미칠까?

회전 후에도 총 분산은 변하지 않는다.

 

 

 

총 분산의 보존을 이용해 다음을 추론할 수 있다.

  • x축 분산과 y축 분산을 단일 백분율 점수로 결합할 수 잇다.
  • 데이터를 x축 방향으로 회전하면 x축 분산이 증가하고 y축 분산은 그에 상응하는 수준으로 감소한다. 수직분산을 p% 감소시키면 수평 분산이 p% 증가한다.

 

x축까지 거리는 다음 과정으로 최소화할 수 있다.

  • y축이 차지하는 총 분산 비율을 최소화한다. 그러면 수직 분산을 최소화할 수 있다.
  • x축이 차지하는 총 분산 비율을 최대화한다. 그러면 수평 분산을 최대화할 수 있다.

 

 

회전 각도에서 전체 분산의 99%가 x축에 분산된다면 회전 데이터는 대부분  1D축 선을 따라 놓일 것이다.

 

 

 

  • 데이터 분산이 가로 방향으로 최대화된다.
  • 많이 퍼진 데이터는 분리가 쉽다. 분리된 ㄷ데이터들은 서로 구별이 쉽다.
  • 수직 Y측을 따른 분산은 최소화되었기 때문에 세로 방향으로는 데이터를 구분하기 어럽다.
  • 정보 손실을 최소화하며 모든 Y축 좌표를 제거할 수 있다.
  • Y축 좌표를 제거하더라도 전체 분산의 1%미만만 영향을 받으므로 충분히 데이터를 그룹화할 수 있다.

 

 

 

임계값으로 그래프를 세로 분할하여 임계 값을 시각화할 수 있다. 두 임계 값은 그래프를 세 부분으로 나누고, 각 부분은 크기와 상관관계를 가진다.

 

 

제한된 데이터 품질을 측정하기 위해 시각화한 것.

  • 제한된 데이터는 centered_data의 산점도 중앙을 직접 가로지르는 선을 형성한다.
  • 이 선은 데이터의 분산을 최대화하는 선형 방향이 첫 번째 주방향을 나타낸다.
  • 대부분의 2D 데이터셋에는 주방향이 두 개 포함된다.
  • 두 번째 주방향은 첫 번째 방향과 수직을 이루며, 첫 번째 방향에 포함되지 않은 나머지 분산을 나타낸다.

 

 

 

 

정리하자면

  • 데이터를 뒤집어 2D 고객 측정값 배열을 1차원으로 줄일 수 있다.
  • 가로 x축 값만으로도 충분히 데이터를 나눌 수 있다.
  • 분산이 최대화되는 주방향을 알면 데이터를 뒤집기가 더 쉽다.
  • 첫 번째 주방향이 주어지면 고객 데이터를 차원 축소해 더 쉽게 그룹화할 수 있다.

 

데이터 회전을 통해 분산을 최대화해 첫 번째 주방향을 추출하는 기법은 더 높은 차원에 적용되지 못한다.

주성분 분석이라는 확장 가능한 알고리즘을 적용하면 모든 주방향을 추출하기 쉽다.

 

 

PCA와 사이킷런으로 차원 감소시키기

PCA알고리즘은 데이터셋의 축을 조정해 분산 대부분이 소수의 차원에 분산되도록한다.

데이터를 구분하는 데 모든 차원이 피룡하지 않기 때문이다.

데이터 구분을 단순화할 수 있다면 그룹화 문제도 단순화할 수 있다.

 

  • 2D 데이터셋에 대해 PCA를 실행하면 데이터가 뒤집혀 X축에 수평으로 놓인다. 그러나 데이터의 투영은 특정한 방향으로만 제한되는 것은 아니다.
  • 데이터 방향은 다르지만, X축을 따라 분산된 범위는 이전과 일관되게 유지되어야 한다.

 

첫 번째 주성분이라는 벡터는 첫 번째 주방향이  원점에서 커지는 선분을 의미

첫 번째 주성분은 원점에서 한 단위 길이만큼 늘어나는 크기가 1.0인 단위 벡터

  • 대부분의 2D 데이터셋은 주방향을 두 개 포함한다.
  • 두 번째 주방향은 첫 번째 방향과 수직을 이루는 특성이 있다.
  • 이를 벡터로 표현한 것을 두 번째 주성분이라 한다.

 

데이터 총 분산의 1% 미만만 포함하는 두 번째 주성분에 관심 가져야하는 이유?

첫 번째 두번째 주성분 모두 데이터의 X축 및 Y축과 특별한 관계를 공유한다. 이 관계를 시각화하면 PCA보다 쉽게 이해할 수 있기 때문이다.

그래프를 보면 주방향 두 개는 본질적으로 X축과 Y축의 회전 버전이다.

축 스압 = 투영이라한다. 두 축을 주방향으로 바꾸는 것을 주방향에 대한 투영이라고 한다.

 

PCA의 방향이 변경된 출력은 투영에 따라 달라진다. 일반적인 PCA 알고리즘은 다음과 같이 작동한다.

  1. 각 데이터 포인트에서 평균을 빼서 입력 데이터를 중앙 집중화한다.
  2. 데이터셋의 주성분을 계산한다. 자세한 계산 내용은 이 절의 뒷부분에서 설명한다.
  3. 중앙 집중식 데이터와 주요 컴포넌트 사이의 행렬 곱을 구한다. 이렇게 하면 데이터의 표준 축이 주방향으로 바뀐다.

일반적으로 N차원 데이터셋에는 주방향이 N개가 있다. K번째 주방향은 첫 번째 K-1 방향이 포함하지 않는 분산을 최대화한다. 따라서 4D 데이터셋은 주방향을 네 개 갖는다. 첫 번째 주방향은 단방향 분산을 최대화하고, 두 번째 방향은 첫 번째 방향에 포함되지 않은 모든 단방향 분산을 최대화하며, 마지막 두 방향은 나머지 모든 분산을 포함한다.

 

 

 

 

4D 데이터를 2차원으로 그룹화하기

  • 데이터를 2차원으로 축소하려면 데이터를 첫 번째ㅐ와 두 번째 주방향에 투영해야한다.
  • 나머지 두 방향은 버릴 수 있기에 분석에는 두 주성분만 필요ㅏ다.
  • 사이킷런을 사용하면 PCA 분석을 상위 두 주성분으로 제한할 수 있다.
  • PCA(n_components = 2)처럼 PCA객체를 생성해 주면 된다.
  • 초기화된 객체는 입력된 데이터를 2차원에 투영하여 축소한다.

 

 

 

특정 게열 꽃(setosa)을 감지하는 간단한 함수를 만든다고 할때,

함수는 꽃잎 측정값 네 개를 담은 flower_sample이라는 네 가지 요소로 구성된 배열을 입력받는다 할 때 다음을 수행한다.

  • flower_sample에서 flower_measurements 값의 평균을 빼어 표본을 중심화한다. 해당 평균은 pca_object_2D 객체의 mean_이라는 속성에 저장되어 있으므로 pca_object_2D.mean_처럼 접근할 수 있다.
  • 중심화된 표본을 첫 번째 주성분과 내적해 첫 번째 주방향에 투영한다. 
  • 예상 값이 -2 보다 작은지 확인한다. 그렇다면 해당 flower_sample은 setosa의 유형일 확률이 높다고 판단한다.

 

 

간단한 임계 값 분석으로 꽃 샘ㅁ플이 setosa인지 확인할 수 있었는데 이것이 가능했던 것은 바로 PCA 덕분이다.

PCA를 사용했을 때 얻는 이점은 다음과 같다.

  • 복잡한 데이터 시각화
  • 간소화된 데이터 분류 및 그룹화
  • 간소화된 분류
  • 메모리 사용량 감소
  • 더 빠른 계산

 

PCA의 제한 사항

PCA는 측정 단위에 지나치게 민감하다.

 

만약 축 단위를 변경하고, 차원 축소를 진행한다면 이전과 분산이 다른 경우가 발생할 수 있다.

이는 데이터에 오류가 발생한 것이다.

이를 해결하기 위한 해결책은 모든 축이 동일한 측정단위를 공유하도록 하는 것이다. 그러나 측정 단위를 사용할 수 없는 경우가 있다. 축이 서로 다른 측정 유형을 사용하는 경우에는 단위가 호환되지 않는 경우가 있기 때문이다. 이땐 어떻게 해야할까?

축 분산 차이는 값 크기의 차이 때문에 발생한다. 그러므로 정규화를 통해 모든 축이 동일한 바운더리의 값을 가지도록 바꿔주면 될 것이다.

 

 

정리하자면

정규화로 기존에 그룹으로 분리된 것은 그대로 유지하면서 단위 차이로 인한 오차를 제거하는 것이다.

그러나 정규화는 의도치 않은 결과를 초래할 수 있다. 정규화된 축 값은 이제 0~1 사이에 있으므로 각 축의 평균도 마찬가지로 0~1 사이에 있다. 모든 값이 평균에서 1단위 미만이다. 이때 부동 소수점의 오류 때문에 데이터를 중심화할 수 없는 상황이 있다. 이때는 실제 평균이 0이 되지 않는다.

 

 

그렇다면 정규화된 데이터에 PCA를 안정적으로 실행할 수 없다면 어떻게 해야할까?

회전 없이 밑바닥에서부터 주성분을 계산하는 방법을 배워야한다.

특이 값 분해로 알려진 이 알고리즘을 사용하면 텍스트 데이터를 효율적으로 그룹화할 수 있을 것이다.

 

 

 

회전 없이 주성분 계산하기

centralized_data : 중심화된 측정 데이터셋

first_pc : 측정 데이터셋의 첫 번째 주성분

 

  • first_pc 는 첫 번째 주방향을 가리키는 단위 벡터다. 이 방향은 데이터의 분산을 최대화한다.
  • 중요한 점은 모든 분산을 행렬에 저장하면 회전 없이도 주성분을 추출할 수 있다는 것이다.
  • 행렬에 전치된 행렬을 곱하고, 데이터 크기로 나누면 공분산 행렬을 만들수있다.
  • 공분산 행렬의 대각선에는 각 축에 따른 분산이 담긴다.
  • 공분산 행렬과 주성분의 정규화된 곱은 해당 주성분과 동일하다.
  • 행렬의 고유 벡터는 행렬과 고유 벡터의 곱이 고유 벡터와 같은 방향을 가리킨다는 특수 속성을 만족한다.
  • 행렬과 고유 베터의 곱은 고유 벡터의 방향을 유지한다. 그러나 대부분의 경우 고유 벡터의 크기가 변경된다.

 

 

요약

  • 첫 번째 주성분은 공분산 행렬의 고유 벡터이다.
  • 연관된 고윳값은 첫 번째 주방향에 다른 분산과 같다.
  • 데이터셋의 주성분은 데이터셋 공분산 행렬의 정규화된 고유 벡터와 같다.
  • 주방향에 다른 분산은 연관된 주성분의 고윳값과 같다.

 

따라서 첫 번째 주성분을 발견하려면

  1. 공분산 행렬을 계산한다.
  2. 행렬의 고윳값이 가장 큰 행렬의 고유 벡터를 구한다. 이 고유 벡터는 분산 범위가 가장 큰 방향에 해당한다.

거듭제곱 반복이라는 간단한 알고리즘을 사용해 고윳값이 가장 큰 고유 벡터를 추출할 수도 있다.

 

 

거듭제곱 반복으로 고유 벡터 추출하기

고유벡터 감지를 위한 간단한 알고리즘인 거듭제곱 반복은 다음과 같이 작동한다.

  1. 임의의 단위 벡터를 생성한다.
  2. 벡터에 행렬을 곱하고 결과를 정규화한다. 단위 벡터가 회전한다.
  3. 단위 벡터가 더 이상 회전하지 않는 고착될 때까지 이전 단계를 반복한다. 그러면 정의상 고유 벡터가 된다.

거듭제곱 반복은 고유 벡터에 수렴하도록 보장된다.

결과로 생성되는 고유 벡터는 행렬의 다른 고유벡터에 비해 가능한 가장 큰 고윳값을 갖는다.

❗일부 행렬에는 음의 고윳값을 갖는 고유 벡터가 있다. 이 경우 거듭제곱 반복은 절대 고윳값이 가장 큰 고유 벡터를 반환한다.

 

두 번째 고유 벡터를 추출하려면 cov_matrix에서 첫 번째 고유 벡터의 흔적을 모두 제거해야하 한다. 이 과정을 행렬 수축이라 한다.

 

기본적으로 모든 행의 평균이 0인 행렬에서 상위 주성분 K개를 추출하는 알고리즘을 만들었다.

centered_matrix 같은 행렬이 주어졌을 때 알고리즘은 다음과 같이 작동한다.

  1. centered_matrix를 centered_matrix.T로 centered_matrix의 공분산 행렬을 계산
  2. 공분산 행렬에 power_iteration을 실행, 이 함수는 공분산 행렬의 고유 벡터를 반환하며, 이는 가능한 최대 고윳값에 해당한다. 이 고유벡터는 첫 번째 주성분과 같다.
  3. 행렬에 고윳값*np.outer(고유벡터,고유벡터)를 빼 행렬을 수축한다. 수축된 행렬에 power_iteration을 실행하면 그 다음 주성분을 추출할 수 있다.
  4. 이전 단계를 K - 2번 더 반복해 상위 주성분을 K개 추출한다.

 

 

데이터셋에서 상위 주성분을 K개 추출하는 함수를 정의했다. 이것으로 데이터셋을 상위 주방향 K개에 투영할 수 있으며 해당 방향은 K축을 따라 데이터 분산을 극대화한다. 나머지 데이터 축은 무시할 수 있으므로 좌표 열 크기를 K로 축소할 수 있고, 결과적으로 모든 데이터셋을 K차원으로 줄일 수 있다.

 

이젠 사이킷런 없이도 PCA를 실행할 수 있다. PCA를 사용하면 N차원 데이터셋을 K차원으로 줄일 수 있다. 알고리즘은 다음 단계를 거쳐 실행된다.

  1. 데이터셋의 각 축을 따라 평균을 계산한다.
  2. 모든 축에서 평균을 빼서 데이터셋의 원점 중앙에 맞춘다.
  3. find_top_pricipal_components 함수로 중심 데이터셋의 상위 주성분을 K개 추출한다.
  4. 주성분과 중심 데이터셋 사이의 행렬 곱을 구한다.

 

정규화된 데이터에서는 중심화를 안정적으로 수행할 수 없다 이때 대안은 centralize_data = False 파리미터 값을 입력해 중심화를 우회하는 것이다. 

 

 

중심화 없이 값을 줄이면?

 

위와 같이 중심화 없이 줄일 수 있다. 하지만 이건 특이 값 분해라고 하는 다른 이름으로 불린다.

 

 

 

 

 

 

SVD 및 사이킷런으로 효율적인 차원 축소하기

 

사이킷런의 최적화된 SVD로 수십 테라바이트에 달하는 데이터를 수백 또는 수십 개 차원으로 축소할 수 있다. 축소된 데이터는 예측 알고리즘을 이용해 좀 더 효율적으로 저장, 전송, 처리될 수 있다. 많은 실제 데이터 작업에서 분석에 앞서 데이터 축소하는 데 SVD를 사용한다. SVD를 사용하면 대부분의 분산은 유지하면서 텍스트 행렬의 열 수를 줄일 수 있으므로, 대규모 텍스트 유사도를 적시에 계산할 수 있다. 그다음 이렇게 계산된 텍스트 유사도로 문서를 그룹화할 수 있다.

 

 

 

15장 대용량 텍스트에 대한 자연어 처리 분석

이 장에서는 대규 텍스트 데이터셋에 대해 자연어 처리를 적용해본다.

 

글의 내용을 주제별로 어떻게 묶을 수 있을까? 다음은 한 가지 접근법을 보여 준다.

  1. 13장에서 설명한 기법으로 모든 토론 텍스트를 단어 수의 행렬로 변환한다.
  2. 특이 값 분해(SVD)로 단어 수 행렬을 차원 축소한다. 이렇게 하면 행렬 곱셈으로 모든 텍스트의 유사성을 효율적으로 계산할 수 있다.
  3. 텍스트 유사성 행렬을 활용하여 토론을 주제별로 묶는다.
  4. 주제 그룹을 탐색해 마케팅 캠페인에 유용한 주제를 파악한다.

 

 

사이킷런으로 웹 토론 포럼 데이터셋 불러오기

  • 사이킷런은 잘 알려진 웹 토론 포럼인 Usenet의 데이터를 제공한다.
  • 이 포럼을 뉴스 그룹이라 한다.
  • 게시글의 다양성과 다양한 길이 모두 자연어 처리 기술을 확장할 기회를 제공한다.
  • 데이터셋에는 게시글이 1만 1,000개 이상 포함되어 있다. 우리 목표는 이 게시글을 주제별로 그룹화하는 것이지만, 이 정도 규모의 텍스트를 그룹화하려면 계산이 효율적으로 수행될 수 있어야한다.
  • 텍스트 데이터를 행렬로 표현해 뉴스 그룹 게시글의 유사성을 효율적으로 계산해야한다.
  • 이를 위해서는 각 뉴스 그룹 게시글을 용어 빈도 벡터로 변환해야 한다.

 

 

 

사이킷런으로 문서 벡터화하기

사이킷런은 입력 텍스트를 TF 벡터로 변환하는 CountVectorizer라는 내장 클래스를 제공한다.

CountVectorizer를 초기화하면 텍스트를 벡터화할 수 있는 Vectorizer 객첵가 생성된다.

 

사용법은 단순히 Vectorizer를 호출하기만 하면 된다.

이 호출은 벡터화된 뉴스 그룹 게시글에 해당하는 TF 행렬을 반환한다.

참고로 TF행렬은 모든 텍스트(행)에 포함된 단어 수(열)을 저장한다.

 

 

해당 행렬은 csr_matrix라는 사이파이의 객체이다.

CSR

  • 압축된 희소 행의 약어
  • 대부분 비어 있는(0) 이러한 행렬을 희소 행렬이라고 한다.
  • 0이 아닌 요소만 저장하여 공간을 효율적으로 만들 수 있으며, 이는 곧 보다 효율적인 메모리 사용과 빠른  계산으로 이어진다.
  • 대규모 텍스트 기반 행렬은 일반적으로 단일 문서에 전체 어휘의 극히 일부만 포함되기 때문에 매우 희소하다고 볼 수 있다.
  • 따라서 사이킷런은 벡터화된 텍스트를 CSR 형식으로 자동 변환한다.
  • 이 변환은 사이파이의 csr_matrix 클래스로 수행된다.

 

주의

넘파이 배열과 CSR 행렬은 일부 속성을 공유하지만 모든 속성을 공유하지는 않기 때문에 초보자에게 혼란스러울 수 있다.

또 CSR 행렬은 넘파이가 제공하는 일부 함수에 호환되지만 모든 함수와 호환되지는 않는다.

따라서 tf_matrix 를 2D 넘파이 배열로 변환하여 혼란을 최소화.

 

 

각 행렬 요소는 게시글에 포함된 단어 수를 표현한다. 행은 게시글을, 열은 개별 단어를 나타내는 식이다.

따라서 총 열 개수는 데이터셋의 어휘 크기와 같다.

 

 

 

 

자연어 처리 실무자들은 잡음이 많은 단어를 중지 단어라고 한다. 중요한 단어가 벡터화된 결과에 나타나지 않도록 차단하기 때문이다. 중지단어는 일반적으로 벡터화되기 전 삭제된다.

 

 

관련성 기준으로 단어 순위를 매길 땐 게시글의 빈도와 횟수를 모두 활용해야 한다. 두 단어의 등장 횟수가 같다면 그때는 게시글 빈도로 순위를 매겨야 한다.

 

 

 

게시글 빈도 및 개수로 단어의 순위 매기기

df.Word의 단어 34개는 각각 뉴스 그룹 게시글에서 특정 비율로 나타난다.

자연어 처리에선 이 비율을 단어의 문서 빈도라고 한다.

 

 

단어 수와 문서 빈도를 점수 하나로 결합해 과정을 단순화할 수 있을 것이다. 어떻게 하면 될까?

한 가지 접근법은 각 단어 수를 관련 문서 빈도로 나누는 것이다. 다음 중 하나에 해당하면 결과 값이 증가한다.

  • 단어 수가 증가한다.
  • 문서 빈도가 줄어든다.

단어 수와 문서 빈도를 단일 점수로 합쳐 보겠습니다. 먼저 1 / document_frequencies를 계산한다. 이렇게 하면 역문서 빈도 (IDF)배열이 생성된다.

 

역문서 빈도는 쉽게 말하면 자주 등장하지 않는 단어일수록 더 중요한 단어를 의미한다.

 

 

IDF 값을 작게 만들어야할 때 데이터 값을 축소하는 한 방법은 로그 함수를 적용하는 것이다.

 

단어 빈도-역문서 빈도(TFIDF)를 사용하면 자주나오지만 관련성 없는 단어를 지우고 정말 중요한 단어들을 뽑아낼 수 있다.

  • TFIDF는 TF(단어 수)와 IDF의 로그 곱을 취하여 계산할 수 있다.
  • TFIDF는 문서에서 단어 순위를 매기는 간단하지만 강력한 지표이다.
  • 이 지표는 해당 문서가 더 큰 문서 그룹의 일부일 때만 관련이 있다. 그렇지 않으면 계산된 TFIDF값은 모두 0이 된다.
  • 유사한 테스트의 소규모 컬렉션에 적용될 때 그 효과를 잃게 된다.
  • 그럼에도 대부분의 실제 텍스트 데이터셋의 경우 TFIDF는 좋은 순위 결과를 산출한다.
  • 문서에서 단어를 벡터화하는 데 활용할 수도 있다.

TF 벡터를 더 복잡한 TFIDF벡터로 변환하면 이점이 있을까?

그렇다. 더 큰 텍스트 데이터셋에서 TFIDF벡터는 텍스트의 유사성과 차이에 대한 더 큰 신호를 제공한다.

 

 

 

 

사이킷런으로 TFIDF 벡터 계산하기

직접 계산한 Combined 열의 상위 열 개 값은 모두 1보다 크지만 사이킷런으로 계산한 TFIDF 열의 값은 모두 1보다 작다.

이는 사이킷런이 TFIDF 벡터를 자동으로 정규화하기 때문이다. df. TFIDF 열의 모든 값을 더했을 대 1이되도록 수정한 것이다.

 

사이킷런이 벡터를 자동으로 정규화하는 이유는 무엇일까?

모든 벡터의  크기를 더한 값이 1이면 텍스트 벡터 유사도를 더 쉽게 계산할 수 있다. 따라서 정규화된 TFIDF 행렬은 유사도 분석을 위한 준비까지 자동으로 해 준 셈이다.

 

 

대규모 문서 데이터셋의 유사성 계산하기

뉴스 그룹의 게시글 중 newgroups.post[0]와 가장 유사한 것은 무엇일까?

코사인 유사도를 계산하면 답을 구할 수 있다. 행렬의 모든 행 크기가 1이기 때문에 행렬과 벡터 간 단순 곱셈으로 충분하다.

 

 

전체 코사인 유사도 행렬은 어떻게 계산할 수 있을까?

가장 간단한 접근은 tfidff_np_matrix에 스스로를 전치한 행렬을 곱하는 것이다.

하지만 행렬 곱셈은 효율적이지 않기에 행렬 곱셈 전에 먼저 행렬 크기를 줄어야한다.

대부분의 자연어 처리 실무자들은 n_components = 100으로 설정되었을 때, 유용한 열 정보를 유지하면서 TFIDF 행렬을 효율적인 크기로 줄인다는 데 동의한다.

 

 

 

 

 

 

주제별로 텍스트 그룹화하기

K-평균은 유클리드 거리로 그룹화가 가능한 반면, DBSCAN은 모든 거리 지표를 기반으로 그룹화가 가능하다.

코사인 거리를 예로 들 수 있다. 코사인 거리는 1에서 코사인 유사도를 뺀 값이다.

코사인 거리는 일반적으로 DBSCAN과 함께 사용된다. 그렇기에 사이킷러너이 제공하는 DBSCAN 구현체를 사용하면, 객체르 ㄹ초기화할 때 코사인 거리를 지표로서 직접 지정할 수 있다.

 

 

연구에 따르면 K-평균은 텍스트 데이터를 합리적으로 세분화할 수 있다. 하지만 데이터 과학에서 올바른 알고리즘을 선태개하는 것은 문제 도메인에 따라 다르다. 단일 알고리즘으로 모든 유형의 문제를 해결하는 것은 불가능에 가깝다.

 

 

K-평균이 실행되는 시간은 어떻게 단축시킬 수 있을까?

한 방법은 방대한 데이터셋을 임의로 샘플링하는 것이다.

K-평균의 중심이 계산되는 동안 임의로 게시글을 1000개 선택, 또 다른 임의의 게시글을 1000개 선택해 그룹의 중심을 갱신하는 방법이다. 이 방식으로 반복적으로 중심을 추정할 수 있다.

이 방식을 미니배치 K-평균이라 한다.

 

 

미니배치 K-평균은 일반 K-평균보다 약 10배 빠르다.

이  실행 시간 단축은 약간의 희생을 수반한다. 미니배치는 약간 낮은 품질의 그룹화 결과를 생성하기 때문이다.

그러나 그룹화 품질이 아니라 K 파라미터 값을 추정하기 위해 1~60 범위의 엘보 플롯을 만드는 데 관심이 있다. 

추정 도구로 미니배치 K-평균의 역할은 충분하다.

 

 

K = 20 이후로 어딘가에서 곡선이 평평해지기 시작하지만, 팔꿈치가 갑자기 구부러지는 특정 위치는 없다. 즉, 완벽한 K 값은 없는 것으로 보인다. 왜그럴까?

우선 현실의 텍스트는 매우 지저분하며 차이가 매우 미묘할 수 있어서 정확한 범주의 경계를 명확히 세울 수 있지 않기 때문이다.

 

 

 

 

 

게시글들의 관련성을 어떻게 평가할 수 있을까?

모든 게시글에서 상위로 순위가 매겨진 단어를 표시해 콘텐츠를 집계하는 방법을 활용할 수 있다.

각 인덱스에서 각 단어의 TFIDF를 합산하여 순위를 매긴다. 그다음 집계된 TFIDF를 기준으로 단어를 정렬한다.

상위 열 개 단어를 출력하면 콘텐츠가 어떤 콘텐츠와 관련이 있는지 판단하는 데 도움이 된다.

 

 

상위 키워드를 조사함으로써 클러스터로 묶인 게시글을 일일이 읽지 않고도 그룹의 유효성을 검사할 수 있었다..

 

 

 

텍스트 클러스터 시각화하기

우리 목표는 여러 텍스트 클러스터에 걸쳐 순위가 매겨진 키워드를 시각화하는 것이다.

단일 클러스터에서 중요한 키워드를 어떻게 시각화할 것인가라는 간단한 문제를 먼저 해결해야한다.

한 가지 방법은 키워드를 중요도 순서대로 출력하는 것이다. 안타깝게도 이 정렬 방식은 상대적 중요도에 대한 감각이 부족하다.

 

상대적 중요도를 시각화에 어떻게 통합할 수 있을까?

글꼴 크기로 중요성을 나타낼 수 있다. 글꼴의 크기가 너무 작을 땐, TFIDF 중요도 점수의 합계를 2배로 늘리면 글꼴 크기를 더 크게 만들 수 있다.

 

또한 맷플롯립의 plt.text 함수를 이용하면 단어 크기가 중요도에 비례하는 2D 격자에서 단어를 시각화할 수 있다.

이러한 유형의 시각화를 워드 클라우드라고 한다.

 

 

 

 

'소프트웨어 > 데이터 분석' 카테고리의 다른 글

실전 데이터분석 1주차  (0) 2025.04.02