rm(list = ls())
# SOM자기조직화지도
# 패키지설치(처음한번만실행)
# install.packages("kohonen") # SOM은 코호넨이 만들었음
# 패키지불러오기
library(kohonen)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# 1.데이터준비
data(iris)
iris_data <- iris[, 1:4] # 수치형변수만사용
# 범주형변수 SOM은 가능하지 않음
iris_labels <- iris$Species
# 2.데이터정규화(SOM은거리기반이므로스케일중요)
iris_scaled<- scale(iris_data)
# 3. SOM격자구성(예: 5x5격자)
set.seed(42)
som_grid <- somgrid(xdim=5, ydim=5, topo= "rectangular")
# 25개뉴런(바둑판)
# 25개(5x5)는 단지 예시일 뿐, 꼭고정할필요없습니다.
# 데이터크기와목적(빠른시각화vs정교한군집화)에 따라
# 격자크기를조절하세요
# 4. SOM학습(반복학습포함)
iris_som <- som(iris_scaled,
grid= som_grid,
rlen= 100, # 반복횟수(Epoch수)
alpha=c(0.05, 0.01), # 학습률시작 → 끝, 큰 수에서 작은 수로
keep.data=TRUE) # SOM학습에사용한데이터를결과객체에 함께 저장
#5. 시각화군집구조및차원축소결과
plot(iris_som, type= "codes",main= "SOM코드북벡터")

# 녹색 부채꼴이크면 → 해당 변수값이 크다
# 갈색 부채꼴이작으면 → 해당 변수값이 작다
# 예:왼쪽위에 있는 원들은 Sepal.Length와Petal.Length가 큼
# 아래쪽중앙의원들은Petal.Length가작고Sepal.Width가큼
# 꽃종류를 미리 몰라도 비슷한것끼리 자동으로군집됨
plot(iris_som, type= "changes",main= "학습오차변화")

# 그래프가 점점 내려간다 → 좋은학습
# 학습이 반복 될수록 뉴런들이 입력데이터를 더 잘반영하고 있다는뜻입니다
plot(iris_som, type= "count",main= "각 뉴런에 매핑된 데이터 수")

# SOM격자판에 데이터가 얼마나 몰려있는지 보여주는 히트맵 느낌의 지도
# 고객군집분석 : 어떤그룹이 큰 군집인지 확인 가능
# 이상치탐지 : 거의 안쓰이는 뉴런(빈칸)에 매핑된 데이터는 이상치일 가능성
plot(iris_som, type= "dist.neighbours",main= "이웃 뉴런간 거리")

# SOM격자에서 서로 이웃한 뉴런들 사이의 거리(차이)를
# 색으로 표현한 지도입니다
# 주황 ~ 빨강 영역
# → 이웃한뉴런들이비슷한데이터를대표
#→즉,같은군집안에있음가능성높음
#노랑~흰색영역
#→이웃한뉴런들끼리값이많이다름
#→즉,서로다른군집의경계
plot(iris_som, type = "mapping", main = "데이터분포(클래스별)",
labels = as.integer(iris_labels))

# 각 점 위에 1, 2, 3숫자가 찍혀서
# 어떤클래스가 어느 뉴런에 모였는지 보여줍니다.
# 2, 3번은 겹쳐있는게 있고 1번은 겹쳐있는것이 없음.
# -> 1번은 확실한 하나의 품종이다라고 판단할 수 있음.
iris %>% count(Species)
## Species n
## 1 setosa 50
## 2 versicolor 50
## 3 virginica 50