메뉴
brunch
매거진
빅데이터 분석 기사 자격증 도전기
실행
신고
라이킷
9
댓글
공유
닫기
You can make anything
by writing
C.S.Lewis
브런치스토리 시작하기
브런치스토리 홈
브런치스토리 나우
브런치스토리 책방
계정을 잊어버리셨나요?
by
첨물
May 19. 2021
빅분기 실기 연습(8)
R프로그램_파생변수/지터함수
지난번에 했던 iris 데이터의 군집화, Kmeans를 이용한 분류가 영 찝찝하다. Setosa는 100% 제대로 분류가 되었는데, versicolor는 2/50개, virginica는 14/50개가 오분류되었다.
> table(iris$Species,kc$cluster)
1 2 3
setosa 50 0 0
versicolor 0 48 2
virginica 0 14 36
어떻게 하면 좀 분류가 잘 되도록 만들 수 있을까?
Kmeans의 변숫값이 꽃잎의 길이, 너비, 꽃받임의 길이, 너비로만 되어 있었는데 좀 더 변수를 만들어서 넣으면 오분류를 줄일 수 있지 않을까? 이때 나온 개념이 파생변수이다.
이때 유용한 패키지가 dplyr이다. 여기엔 유용한 함수 5개가 있다.
IRIS의 4개의 변수 조합을 만들어서 열추가 해보려고 한다. 이때 필요한 함수는 mutate()
일단 IRIS 데이터를 한 화면에 정리를 해 보고 생각해보자. 매번 head() 함수를 썼는데, 이번엔 tbl_df()라는 함수를 써서 정리했다.
iris_df<-tbl_df(iris) #자료를 한 화면에 정리
iris_df
> iris_df
# A tibble: 150 x 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fct>
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
7 4.6 3.4 1.4 0.3 setosa
8 5 3.4 1.5 0.2 setosa
9 4.4 2.9 1.4 0.2 setosa
10 4.9 3.1 1.5 0.1 setosa
# ... with 140 more rows
다음엔 mutate() 함수를 써서 꽃받임의 길이/너비 비율과 꽃잎의 길이/너비 비율을 가지고 새로운 변수를 만들어 넣어보자. 그러면 새로운 열인 Sepal.Ratio와 Petal.Ratio가 생겼음을 알 수 있다.
aa<-mutate(iris_df, Sepal.Ratio=Sepal.Length/Sepal.Width,Petal.Ratio=Petal.Length/Petal.Width)
colnames(aa)
> colnames(aa)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species" "Sepal.Ratio" "Petal.Ratio"
다음엔 이걸로 Kmeans 분류를 해보자. 오히려 악영향을 주었다. setosa도 분류를 완전히 못하고, 나머지 두종도 한종으로만 분류함.
aa$Species = NULL
kc1<-kmeans(aa,3) #종류가 3개인 군집분석 (비지도 학습)
table(iris$Species,kc1$cluster)
> table(iris$Species,kc1$cluster)
1 2 3
setosa 31 19 0
versicolor 0 0 50
virginica 0 0 50
그러면 꽃잎은 길이*너비로 새로운 변수를 넣어보자.
aa<-mutate(iris_df, Petal.multiply=Petal.Width*Petal.Length)
> table(iris$Species,kc1$cluster)
1 2 3
setosa 0 50 0
versicolor 0 0 50
virginica 42 0
8
versicolor는 100% 제대로 분류를 했고, virginica는 8/42 개 오분류가 되었다.
이 정도면 꽤 잘 분류를 한 게 아닐까, 파생변수 하나를 넣어서 확실히 좋은 결과물을 낼 정도면...
다른 조합도 해 보았지만 이 정도로 좋아지지 않았다.
그러면 이전 변수 4개만 한 것과 비교해서 새로운 파생변수로 분류한 것을 산점도로 나타내 보자. 오른쪽 위 두 그룹 경계면이 파생변수 넣었을 때가 좀 더 잘 분류됨을 알 수 있다.
plot(aa[c("Petal.Length", "Petal.Width")], col=kc1$cluster)
파생변수 넣어서 분류(좌), 기존 변수로 분류(우)
뭔가 제대로 분류되었다는 걸 다른 방식으로 보여줄 수는 없을까?
R의 강점을 살려서 한 걸음 더 나아가보자.
t<-as.factor(kc1$cluster)
tt<-iris$Species
plot(tt,t)
음. setosa와 versicolor는 잘 분류가 되었는데, vierginica가 일부 오분류가 된 듯한 느낌이 든다. x, y 모두factor로 되어 있을 때 plot으로 그리면 이렇게 나온다.
그럼 다른 방식으로 약간 변형해 보자. 3종의 꽃을 1~3으로 분류한 것을 나타낸다.
y<-as.integer(t)
x<-as.integer(tt)
plot(tt,y)
그런데 뭔가 아쉽다. virginica의 동떨어진 한점이 몇개의 데이터인지 알고 싶다 이때 필요한 것이 jitter()함수, 약간의 noise를 주는 것이다.
y1<-jitter(as.integer(t))
plot(tt,y1)
y값에 약간의 노이즈를 주니, 뜬금없이 boxplot이 그려진다. 그래서 viginica 윗쪽에 찍힌 점의 숫자가 대략 8개가 됨을 알 수 있다. 위 파생변수를 넣어서 분류한 결과이다.
x 값에도 jittter를 넣어서 마지막으로 그려보자.
x1<-jitter(as.integer(tt))
plot(x1,y1,xlab="iris$Species", ylab="kmeans$Classification")
keyword
파생변수
빅데이터
머신러닝
브런치는 최신 브라우저에 최적화 되어있습니다.
IE
chrome
safari