핍 값 계산 방법

마지막 업데이트: 2022년 1월 23일 | 0개 댓글
  • 네이버 블로그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 트위터 공유하기
  • 카카오스토리 공유하기
  1. [ 자재 ] > [ 프로세스 ] > [ ABC 분석 생성 ] 을 선택하십시오.
  2. 다음 정보를 명시하십시오.

핍 값 계산 방법

포럼에서 피드백 받고 내용 검증하느라 늦었습니다. 내용이 많은 만큼 최대한 핵심만 짚고 넘어갈게요. 제가 원래 썼던 글 중에 틀린 부분도 있고 한계점도 있는데 그에 대해 포럼에서 핍 값 계산 방법 알게된 부분들까지 제대로 다 설명해드리겠습니다. 바로 가보죠.

원래 이 글은 기병이 돈 값 하는지를 알아보기 위해 시작한 건데 결국 유로파 유닛과 전투 전반에 대한 분석이 되어버렸습니다.

분석에 들어가기에 앞서 유닛 데미지가 산출되는 공식을 살펴보시죠. 영어가 되시는분들은 읽어보시고, 대충 밑에 수식이 무슨 뜻이냐면

(15+5*(주사위 값 + 공격 장군 핍 - 방어 장군 핍 (장군 핍 차이는 음수가 될 수 없음) + 공격 유닛 공격 핍 - 방어 유닛 방어 핍 - 지형 페널티)) * 군사 기술로 얻는 사격/충격 값 * 유닛 병사 수/1000 * 규율 * 전투 능력 * 사격/충격 데미지 증가 * (1-적 사격/충격 데미지 감소) * (1+0.01*전투 지속 일 수) / 군사 전략

그냥 한 마디로 모든게 다 곱해진다고 보시면 됩니다. 마지막에 military tactics로 나누구요. 즉, 사격이나 충격 한 종류의 공격 방식에 보너스를 몰빵하는게 그 효과가 좋다는 뜻이기도 합니다. 근데 사격이 짱이에요. 이는 다른 모든 조건이 동일하다고 가정하고 순수하고 유닛끼리의 비교가 가능하다는 의미기도 합니다. 사기 데미지도 거의 같은 방식으로 계산됩니다. 즉, 핍 값 계산 방법 규율, 전투 능력, 사격 보너스, 등등의 모든 버프에 똑같이 영향 받습니다. 단지 유닛 핍에 사기 핍이 적용될 뿐이구요. 매일 기본 사기 데미지 0.03도 받구요. 그리고 중요한거, 앞열이 받는 사기 데미지를 뒷열이 똑같이 받습니다.

*수정: 사기 데미지 계산시에 사격/충격 데미지 버프는 적용되지 않습니다. 사기가 얼마나 중요한지 생각해보면 10%씩이나 되지만 결국 반쪽짜리만도 못한 모디파이어인 것이죠.

암튼 저 수식을 엑셀에 대입해서 사격/충격 페이즈 번갈아가는 전투 상황을 재현해봤습니다. 계산이 실제 게임 상 수치와 완전 일치하지는 않았지만 거의 비슷했고 대충 추이는 같았어요. 이렇게 유사 시뮬레이션을 만들 수 밖에 없던 이유는, 저 수식 계산해봤자 1일치 데미지 밖에 안 나오기 때문이죠. 그거 갖고 유닛 전투력 측정은 불가. 물론 이것도 완벽하진 않습니다. 한계점은 맨 마지막에 설명드림.

기병이 얼마나 쓸모 있는지 알려면 보병과 비교를 해야되고, 그럼 보병 대 기병 비교에서 어떤 유닛을 써야되는지를 알아야겠죠. 그러니 먼저 제일 좋은 보병/기병 유닛을 알아봅시다. 서로 싸움 붙여봤어요.

빨강: 사기 우위 파랑: 남은 병력 수 우위 보라: 둘 다 우위 맨 오른쪽 값이 양수: Unit A 우위 음수: Unit B 우위 (a):포병 지원

모든 전투가 사기가 바닥나서 끝납니다. 즉,

왜냐? 사격/충격은 다른 페이즈 때 안 쓰이지만 사기 핍은 전투 중 계속 쓰여요. 모든 전투는 사기가 0 돼서 끝나지 병력이 다 죽어서 끝나는 전투는 없구요. 부대 전멸은 12일이 지나기 전 적 사기가 바닥나고 병력 수 비율이 2:1 이하가 되면 전멸. 즉시 전멸은 10:1 이하. 단, 그렇다고 사기가 2배 더 중요하다는건 아닙니다. 왜냐? 물리 피해는 적 수를 직접 줄이고 물리/사기 데미지는 유닛 수에 비례하기 때문에 이는 적이 다음 턴에 주는 피해를 감소시켜요. 반면 사기는 0이 돼야 전투에 영향을 끼치구요. 그러나 사기가 제일 중요한건 변함없다.

다시 돌아와서, 유닛 선정 기준은 빨강, 즉 사기 우위, 즉 전투를 이긴 놈입니다. 킬뎃 좋은 놈을 선택하고 싶어하는 분들이 계실텐데요, 왜 그게 안 좋은지 간략히 설명드리겠습니다.

1. 전투 이기면 사기 절반 혹은 일정량 (위키에서도 설명이 갈림 ㅡㅡ) 회복

2. 전투를 이겨야 요새를 점령할 시간을 벌고, 요새를 점령해야 전쟁을 이김

3. 전투 이기면 뒤늦은 증원군 쉽게 자르는 등 온갖 전략적 이점이 있음

4. 소모전 양상으로 가려고 해도 결국 요충지 요새는 지킬 수 있어야 하고, 그러려면 전투에서 이겨야함

5. 위 수치를 확인해보면 40대40 전투에서 가장 차이가 극심한 경우 2000명 차이. 즉 연대 두 개 잘라먹으면 바로 본전. 단 보병끼리만 싸웠을 경우.

그리고 무승부 나는 경우 공격/방어 상관 없이 사격/충격/사기 수치가 동일해서 그럽니다. 순수 1대1에서는 공격 핍이나 방어 핍이나 똑같은거에요. 공격 핍은 내가, 방어 핍은 적이 데미지 계산할 때 동일한 빈도로 사용되거든요. 그래서 공격/방어 배분 상관없이 그냥 사기 핍 많은 놈이 다 이기는거구요. 그 다음은 사격, 충격 순이겠네요. 왜냐하면 전투는 항상 사격 페이즈로 시작되고 유닛 데미지는 유닛 수에 비례하기 때문에 처음에 더 세게 핍 값 계산 방법 때린놈이 그만큼 다음 턴에 덜 맞는거죠. 그래서 첫 사격 페이즈 주사위가 겁나게 중요합니다. 그리고 실제 전투에선 보병/기병/포병한테 다굴 맞는게 보병이기 때문에 공격보단 방어 핍을 더 쳐주는거구요. 그럼 이제 테크 26만 빼고 나머지는 최고 유닛 고를 수 있게 되었고, 테크 26의 경우 블루 코트가 사기 방어 핍이 제일 많긴 하지만 레드 코트가 사격 방어 핍이 하나 많죠. 만약 포병끼고 싸웠을 때 사격 방어 핍이 더 중요하다면? 그래서 양쪽 포병낀 값 계산해봤는데 여전히 블루코트 승. 결론은 보병은 사기 방어 핍이 짱이다. 그 담엔 사격 방어, 그담엔 음. 모르겠네요. 사기 공격이나 충격 방어 정도가 아닐지?

Latin Medieval Infantry

기병도 똑같이 해봤는데 까다로운 케이스 2가지가 있었어요. 하나는 테크 23. 셋 다 총 사기 핍이 8개로 같죠. 그래서 대 보병, 포병 끼고 대 보병 테스트해보니 순수 기병 전은 후사르가 제일 약하지만 정말 미미한 차이고, 사격 병종 상대로 후사르가 사격 방어 2핍 땜에 제일 성능이 좋고 포병 끼면 역시 역전해서 후사르 골랐어요.

두번쨰는 테크 28인데 얘는 랜서가 사기 방어 핍이 하나 적긴 한데 2사격 방어에 6충격 공격으로 스탯이 깔끔하고 비록 전투는 아슬아슬하게 지지만 상대 기병한테 가장 많은 피해를 입히기도해서 더 실험해봤는데, 사격 병종 상대로 역시 제일 잘 싸우더라구요. 그래서 랜서 골랐습니다. 기병이 충격 병종이라 사격 방어 핍이 상당히 중요하네요. 다만 1선 유닛이기도 해서 사기 방어도 매우 중요할테구요. 기병 종류가 적어서 정확히는 판단이 안 되네요. 핍 중요도 아는 것보다 어떤 유닛 아는게 중요한거라.암튼 고래숴

Western Medieval Cavalry (개쓰레기 유닛)

Reformed Latin Hussars

포병 없는 버전이랑 포병 있는 버전 표입니다. 중반 이후엔 포병 있는 버전으로 보는게 맞겠죠.

음. 심지어 보병한테 1대1 지는 구간도 있죠 기병이? 여기서 또 중요! 기병은 보병보다 2.5배 강해야 되는게 아닙니다. 이 게임에서 유저의 전투력을 제한하는 요소가 총 4가지 있죠. 병력 상한, 전장 너비, 돈, 인력. 기병 하나가 보병 2.5개 값이라고 보병 2.5개 간다? 그건 돈이라는 자원은 같지만 나머지 세 자원을 더 쓰는 셈이죠. 초중후반 게임 상황에 따라 다르겠지만, 보통 유로파 뿐만 아니라 어느 게임이든 엘리트 유닛은 프리미엄이 붙기 마련이고 그래야 밸런스가 맞습니다. 승리의 대가가 꼭 가성비와 정비례하는건 아닌거죠. 아무튼, 본론으로 돌아와서. 그래서 기병이 돈 값 하느냐 안 하느냐? 그건 보병 자리에 대신 기병 넣을 경우 확실하게 이길 수 있다면 돈 값 한다고 볼 수 있습니다. 근데 여러가지 요인으로. 구려요.

1. 기병의 장점은 우회 공격, 즉 수적 우위를 점할 때 다구리 때릴 수 있는 능력입니다. 근데 보통 중후반엔 그럴 기회가 적죠

2. 가장 치명적인데, 충격 병종이라는 점입니다. 아 제가 깜빡하고 말 안 했는데 모든 실험은 양측 주사위 4.5를 가정하고 실험했어요. 근데 같은 주사위 값이라도 양측 다 첫 사격 페이즈에 9가 떴다? 이러면 보병+포병인 쪽은 데미지 승천하고 기병+포병인 쪽은 반대로 갈려나가는거죠. 같은 주사위 값인데도. 즉, 기병은 첫 사격 페이즈에서 적이 낮은 주사위 굴리고 이어지는 충격 페이즈에서 자기가 높은 주사위를 굴리길 바래야하는. 구조적으로 활약할 확률이 보병보다 떨어지는 병종입니다.

3. 위에 데미지 공식이 죄다 곱셈이라 같은 종류의 보너스 중첩해야 효과가 좋다고 한거 기억하시죠? 게임 내 1티어 이념들이 보통 사격/보병 버프를 많이 줍니다. 기병 버프는 유목민 폴란드 정도, 이념은 귀족 정도죠. 듣자하니 멀티에선 (이 정도의 효율 추구는 어차피 싱글에선 다 쓸데 없는거니 멀티 얘기를 하자면) 혁신, 경제, 종교, 질 같은 이념으로 군사 버프 주는 정책 찍는게 메타라고 하던데 그 메타 상대가 안되는거죠.

4. 3번에 이어지는건데, 기병 비율에 제한 받습니다. 아무리 내가 기병 써보겠다고 기병 버프 쌓아봤자, 보병 버프 쌓고 걍 100% 보병 가는 것 만큼 효율이 안 나올 수 밖에 없는거시에오 하와와

5. 걍 기본적으로 구림. 위에 보시면 아시겠지만 대놓고 1대1 지는 구간도 있잖아요.

6. 마지막으로 멀티에선 걍 보병 포병 단일화하는게 병력 운용이 훨씬 쉽다는 점. 굳이 기병을 섞어넣는 수고를 할만큼 기병이 좋지 않다는 점.

그렇지만. 그럼에도 불구하고 기병이 분명 강하고 쓸만한 구간이 있다 (적어도 서양 테크에선, 다른 테크는 상황이 어떨지 모르겠네요. 일단 유목민 1렙 기병은 초반 깡패인거야 뭐 워낙 유명한 사실이구요). 추려보면 대강 군사 테크 4, 11, 17~19, 23~26 정도입니다. 싱글에선 시간은 얼마든지 많으니 취향에 따라 사용하시면 되겠습니다.

이 표는 포병이 있고 없고 성능 차이가 얼마나 나냐인데, 맨 오른쪽 핍 값 계산 방법 보시면 포병이 추가되면 보병쪽으로 저만큼 이득이 생긴다는 뜻입니다. 사격 병종의 이점이 얼마나 큰지를 나타낸다고 보시면 되겠네요.

이건 뭐. 이미 다 설명해버린거긴 한데, 기병이 돈 값하는지의 척도를 1:2.5 가능한가로 보면 안된다 블라블라

아 이건 포병 전투력 측정하려는 시도였습니다. 보병 vs 보병 + 포병 하면 저래 되는데 앞서도 말했지만 저거 갖곤 포병이 얼마나 좋은건지 감이 안 잡혀요. 그래서 1대1 연속 2번, 이기면 3번 해본겁니다. 자 봐라, 니들이 빠는 포병도 돈값대로 하면 1:3 돼야 하는데 1:2하면 보통 퍼진다. 뭐 이런 뜻으로 한건데. 사실 이때 제가 포병은 모랄빵 나도 안 도망가고 계속 포 쏜다는걸 몰랐었습니다. 포병이랑 기병은. 비교가 안 돼요. 포병 차냥해

극후반 포병은 겁나 세다 뭐 대충 이렇게 보시면 됩니다

요거슨. 보병이 첫 주사위 9, 기병이 첫 주사위 0 굴리면 어떻게 되는가. 를 포병 없는 버전이랑 있는 버전으로 올린건데, 주사위가 저 모양임에도 불구하고 이긴 놈들, 즉 테크 5, 10, 11, 17~20, 23~28 (중반 이후론 포병 포함 버전을 봐야하기 때문에) 정도는 기병 쓰는게 완전 멍청한 짓은 아니다 정도 의미로 해석할 수 있습니다. 맨 밑에 표는. 그냥 포병 상대로 첫 주사위 망하면 답이 없구나 정도로 해석하시면 됩니다.

완전 날림이네요 ㅋㅋ 그럼 이 글이 비판 받은 부분이랑 그럼에도 갖는 의의 말씀드리겠습니다

1. 주사위가 00, 55, 99일 경우 결과가 다 다를 수 있고 게임 내 각종 버프들 다 고려하지 못함. 정확한 측정을 위해선 다 해야함

2. 포병의 전투력 자체는 테크 22부터 쓸만해지는건 사실 (동일 수의 올 보병 군대를 이기게 되는 시점). 근데 사기 데미지를 이중으로 받는걸 방지하는 매우 중요한 기능 때문에 테크 16부터 포병 풀로 채워야 하는걸 모르고 포병을 과소평가.

3. 1대1만을 측정했는데 실제 전투는 모랄빵 난 유닛들의 교체 과정에서 타게팅 문제 (공격자는 후퇴하는 적을 한 턴 더 공격한다고 함 위키에 따르면. 즉, 방어자는 이미 모랄빵 난 유닛으로 1턴의 데미지를 흡수하는 셈. 근데 간혹가다 그러는건지 항상 그러는건지는 모르겠네요.), 기병이 우회 공격할 수 있는 위치로 안 가고 가만히 노는 문제 (간혹 생기는거 같아요), 걍 다구리 등등 여러 요인으로 결과에 영향을 끼침.

1. 그럼에도 불구하고 신중하게 결론을 내린 덕에 상세한 내용 중에 오류가 있어도 큰 틀에서의 설명은 크게 틀린 부분은 없다.

대충 쓰느라고 글이 너무 개판인데, 이해 안 되시는 부분은 질문 주시면 성심성의껏 답변해드리겠습니다.

답댓글 작성자 비도 작성자 본인 여부 작성자 | 작성시간 20.03.06 같은 방식으로 적용됩니다. 사격/충격 계산식에 포병 사격/충격 계수를 대입해서요. 후열 포병 모디파이어라는 게임 스탯이 있는 것 같은데 아마 추측하신대로가 맞을 것 같네요. 앞 줄에 보너스 주는건 사격/충격 방어 핍의 절반 (내림)이라 유닛에 상관없이 받을거구요, 근데 포병이 전열로 가면 후열일 때 받는 공격력 50% 페널티는 사라지지만 대신 반대로 적으로부터 데미지를 2배로 받기 때문에 포병은 후열에서만 운용하는게 좋습니다ㅋㅋ 아니면 적 보병/포병한테 쌍으로 핍 값 계산 방법 2배 데미지 받아서 살살 녹아버려요.

답댓글 작성자 릴리슈슈의 모든 것 작성시간 20.03.06 비도 포병올인이 공격몰빵으로 유리대포이긴한데 재밌을 거 같아서 ㅋㅋ
후열포병 모디파이어는 혁명시대때 시대능력으로 열리는 거 말한 건데 포병전투력이랑 같은 게 맞나보네요
답변 감사합니다 ㅎㅎ

답댓글 작성자 비도 작성자 본인 여부 작성자 | 작성시간 20.03.06 릴리슈슈의 모든 것 엄밀히 따지면 포병 전투력이랑은 다른겁니다. 것보다 살짝 좋다고 생각하시면 되요.
예를 들어, 데미지가 10인데 포병 전투력 20%면 10*1.2*0.5 = 6이지만 같은 데미지에 후열 포병 데미지 20% 증가면 10*0.7 = 7입니다. 후열 포병 전투력이 더 높죠.
솔직히 제가 귀찮아서 제대로 생각 안 해보고 댓글 달았었는데 다시 읽어보니 같은 방식으로 적용되는게 아니네요 ㅎㅎ;

작성자 eatty 작성시간 20.04.03 궁금한게있는데요 유럽국가는 그럼 올보병뽑는게 낫나요? 효율따져봤을때요 만약 1500년대 초반인데 20연대를 뽑았다 그러면 기병을 안뽑아도 되나요?

답댓글 작성자 비도 작성자 본인 여부 작성자 | 작성시간 20.04.03 서구권은 테크 3~5, 10~13, 17~20, 23~26 구간은 기병을 쓰는게 좋고 그 외엔 올 보병이 낫습니다. 동구권은 테크 4, 5, 10~15, 17~26 구간에만 쓸만하구요. 다만 보병/기병 전투력에 따라 달라질 수는 있습니다.

R | python | 체계적위험 베타 자동 계산 | Valuation

Valuation | 엑셀로 블룸버그와 같은 베타 계산하기 에서 엑셀로 베타 계산하는 방법에 대해서 정리한 바 있다. 엑셀로 베타를 계산하기 위해서는 몇 차례 번거로운 수작업을 필요로 하므로 R을 활용하여 나의 손 대신 컴퓨터가 작업하도록 하는 방법을 알아보고자 한다.

베타 계수는 개별주식과 전체시장의 수익률의 공분산을 분산으로 나누는 식으로 계산할 수 있다.

$$ \beta = covariance(R_e, R_m) / variance(R_m) $$

Where,
Re: 개별주식 수익률
Rm: 전체시장 수익률
covariance: 개별주식 수익률의 변화가 전체시장 수익률의 변화에 관련 수준
variance: 시장의 데이터들이 평균에서 얼마나 분산되어 있는지의 수준

그러나, Valuation | 엑셀로 블룸버그와 같은 베타 계산하기 에서와 같이 회귀분석 기능이 있는 프로그램(엑셀 또는 R)이 있다면 공분산과 분산을 계산하여 나누는 산식을 만들지 않아도 회귀분석 결과의 Coefficient를 알아낼 수 있으므로 이 방법을 적용해 보고자 한다. R은 태생이 통계 프로그램으로 탄생하였다는 것에 걸맞게 놀라울 정도로 너무나도 간단하게 회귀분석의 결과를 알 수 있는 lm 함수를 가지고 있다.

lm함수로 수익률 벡터 두 개를 ~ 물결 표시로 단순하게 이어주기만 하면 회귀분석의 결과가 산출된다.

주가 데이터를 다운로드 받고 재구성하는 과정을 모두 코드로 구현하고자 하다 보니 주가지수 데이터와 개별주가 데이터를 가져오는 것에 대하여 문제가 생겼다.

R의 주가 데이터를 수집하는 package로 quantmod가 있다. 문제는 이 패키지가 yahoo finance에서 주가 및 주가지수 데이터를 가져오는데 yahoo가 우리나라에서 떠나버려서인지 코스피지수 또는 주식 등의 데이터가 완전하게 수집되지가 않고 코스닥 주식의 경우에는 전혀 되지 않는 등 불안하게 동작한다.

그렇다면 크롤링을 해서 해결해야 하는데 그래서인지 검색엔진에 “R 주가 크롤링"을 검색하면 이에 관련한 내용이 많이 나온다. ‘R로 주가를 가져오고자 하는 사람들은 대부분 크롤링으로 해결하나?’ 하는 생각이 든다.

하지만 크롤링은 하기 싫고 패키지를 사용해서 짧고 강한 코드를 쓰고 싶다.

python의 모듈을 사용해서 주가 데이터를 가져와 보는 것을 생각했다. python에는 finance-datareader 1 라는 모듈이 있는데 잘 동작해 줄 것으로 기대한다.

R에서 python의 패키지를 사용할 수 있다. R의 reticulate 패키지를 사용하면 마치 R의 함수를 사용하듯이 python의 함수를 사용할 수도 있고 python의 REPL을 작동할 수도 있으며 py 스크립트를 실행 할 수도 있다.

R에서 python을 구동하는 패키지 reticulate 은 https://rstudio.github.io/reticulate/ 사이트에 설명이 있다.

R도 잘 배워서 능숙하게 사용하고 python도 역시 잘 사용할 수 있게 되고자 하면 둘 다 제대로 사용하지 못할 것 같다는 생각에 R을 주로 사용해야겠다고 생각했었다. 실제로 python은 생각보다 많이 어렵다. python을 쉽게 생각했다가 한도 끝도 없이 깊어지는 것을 풍자하는 그림 같은 것들이 웹에 떠다니기도 한다. 그러나 python에 구현되어 있는 좋은 기능이 있으면 가져다 쓰면 R이 포함하지 못하는 것까지 구현이 가능하다. 완벽한 프로그램은 없다. R도 python도 무료 오픈소스 프로그램이므로 공짜로 유연하게 사용할 수 있는 것 자체로 감사하다.

시작 일자와 마지막 일자를 문자열 객체 변수로 할당해 준다. 또한 코스피 코드와 주식 코드를 문자열 객체 변수로 할당한다.

코스피 지수와 삼성전자의 2016년부터 2020년까지의 5년 동안의 주가지수와 개별주가를 가져와서 회귀분석의 결과를 나타낸다.

주가지수와 개별주식을 끌어 오는 것은 python의 finance-datareader가 맡고 회귀분석은 R의 lm() 함수가 맡는다.

python의 모듈 기능을 사용해서 주가를 가져와서 R의 lm 함수로 회귀분석을 하고 그 결과 중 기울기에 해당하는 베타 값을 뽑아 내는 코드가 단 몇줄로 해결할 수 있게 되었다. 여기에 반복문을 사용하면 여러 개의 회사에 대한 베타를 한번에 뽑아 내는 것도 쉽게 구현할 수 있을 것 같다.

finance-datareader는 conda로 설치 할 수 없으므로 R에서 reticulate::py_install() 함수로 설치할 수가 없는 것이 조금 아쉽다. shell에서 python의 pip를 사용하여 설치해야 한다. pip install -U finance-datareader ↩︎

ABC 분석 생성하기

참조용 ABC 분석 보고서 작성 및/또는 부품에 대한 클래스 배정을 업데이트하기 위한 ABC 분석을 생성 하십시오.

ABC 재고 분석은 재고 품목을 A, B, 그리고 C의 3개 그룹이나 클래스로 나눌 수 있도록 해주는 재고조사 방법입니다. A, B 및 C. ABC 클래스 배정은 EOQ 계산, 재고품 보충, 수리할 수 있는 예비품 및 실지 재고 수 세기 등 여러가지 자재 관리 기능을 위한 선택 기준으로 사용됩니다.

ABC 분석을 생성하려면, 세 클래스 각각의 컷오프 지점으로서 백분율 값을 명시하십시오. 그러면 시스템이 해당 부품의 가치를 다른 부품들의 가치와 비교하여 ABC 클래스들 중 하나에 부품을 배정합니다. 클래스 A에 배정된 부품은 총 재고 가치 중 최대 백분율을 지닌 부품을 나타냅니다. 클래스 B에 배정된 부품은 총 재고 가치 중 중간 백분율을 지닌 부품을 나타냅니다. 클래스 C에 배정된 부품은 총 재고 가치 중 작은 백분율을 지닌 부품을 나타냅니다.

사용자의 선호도에 따라, 시스템은 부품 가치나 부품 사용량 가치를 기준으로 부품의 ABC 클래스를 결정합니다. 시스템은 부품을 그 가치가 큰 것부터 배열하므로 [ 가치 백분율 ]이 가장 큰 것이 맨 앞에 오고 나머지 부품들이 [ 가치 백분율 ]에 따라 내림차순으로 배열됩니다. 그리고나서 시스템은 [ A 컷오프 지점 % ], [ B 컷오프 지점 % ], 그리고 [ C 컷오프 지점 % ]에 대해 명시된 백분율에 근거하여 각 부품에 클래스를 배정합니다.

Note: 시스템은 각 부품에 대해 명시된 [ 가격 유형 ]을 사용해서 부품 가치 백분율을 결정합니다. 시스템은 저장고 부품의 현 클래스 배정에 영향을 주지 않고 참조용으로 ABC 분석을 실시할 수 있게 해줍니다. 아니면 [ ABC 클래스 업데이트 ]를 클릭하여 부품 ABC 클래스를 자동 업데이트할 수 있습니다.

  1. [ 자재 ] > [ 프로세스 ] > [ ABC 분석 생성 ] 을 선택하십시오.
  2. 다음 정보를 명시하십시오.

Note: 데이터를 생성하기 위해 필요한 [ 저장고 ] 필드에 와일드카드를 입력할 수도 있습니다. 오직 한 글자만 알고 있는 경우, 그 아는 글자를 기입하고 알지 못하는 글자를 "_"로 대체할 수 있습니다. 매개변수의 한 부분만을 알고 있는 경우에는 그 아는 부분을 기입하고 나머지 부분을 %로 대체할 수 있습니다. 예를 들어 [ 저장고 ] 필드에 P%를 기입하면, 시스템은 글자 "P"로 시작하는 저장고를 모두 검색해 옵니다. [ 저장고 ] 필드에 %PIP%를 기입하면, 시스템은 글자 "PIP"가 포함된 코드가 있는 저장고를 모두 검색해 옵니다.

A 컷오프 지점 % A 에 대한 컷오프 지점 값을 명시하십시오. 시스템이 자동으로 70을 기본 값으로 명시합니다. B 컷오프 지점 % B 에 대한 컷오프 지점 값을 명시하십시오. 시스템이 자동으로 20을 기본 값으로 명시합니다. C 컷오프 지점 % C 에 대한 컷오프 지점 값을 명시하십시오. 시스템이 자동으로 10을 기본 값으로 명시합니다.

Note: [ A 컷오프 지점 % ], [ B 컷오프 지점 % ], 그리고 [ C 컷오프 지점 % ]에 대해 명시된 값의 합계가 반드시 100%가 되어야 하며, 이 세 지점의 값을 모두 명시해야 합니다.

텐서 플로우 블로그 (Tensor ≈ Blog)

머신러닝(Machine Learning), 딥러닝(Deep Learning) 그리고 텐서(Tensor) 또 파이썬(Python)

2.3 데이터 가져오기

이제 직접 키보드를 두드릴 차례입니다. 노트북을 꺼내서 주피터 노트북에 있는 다음 코드 예제를 따라 해보세요. 전체 주피터 노트북은 https://github.com/rickiepark/handson-ml 6 에 있습니다.

2.3.1 작업환경 만들기

먼저 파이썬이 설치되어 있어야 합니다. 여러분 컴퓨터에는 이미 설치되어 있을 것입니다. 그렇지 않다면 http://www.python.org/ 에서 내려받을 수 있습니다. 7

그다음엔 머신러닝 코드와 데이터셋을 저장할 작업 디렉터리를 만듭니다. 터미널을 열고 다음 명령을 실행합니다($ 프롬프트 다음이 명령입니다).

필요한 파이썬 패키지가 많이 있습니다. 주피터, 넘파이, 판다스, 맷플롯립, 사이킷런입니다. 이미 이 패키지들을 설치했다면 2.3.2절 ‘데이터 다운로드’로 건너뛰어도 됩니다. 아직 이 패키지들이 없다면 (의존성이 있는 다른 패키지도 포함해서) 설치할 수 있는 방법은 여러 가지입니다. 시스템의 패키징 도구를 사용할 수 있고(예를 들면 우분투의 apt-get, macOS의 맥포츠 MacPorts 나 홈브류 Homebrew ), 아나콘다 같은 과학 파이썬 배포판을 설치하고 딸려오는 패키징 도구 8 를 사용하거나, 그냥 파이썬 바이너리 인스톨러에 (파이썬 2.7.9부터) 기본으로 포함된 자체 패키징 도구인 pip를 사용할 수도 있습니다. 9 시스템에 pip가 설치되어 있는지 다음 명령으로 확인합니다.

최신 버전의 pip가 설치되어 있는지 확인해야 합니다. 바이너리 패키지(휠 wheel 이라고도 합니다) 설치를 지원하기 위해 최소한 1.4 버전보다 높아야 합니다. pip 패키지를 업그레이드하려면 다음 명령을 실행합니다. 10

독립적인 환경 만들기

독립된 개발 환경(다른 프로젝트의 라이브러리 버전과 충돌하는 것을 피하기 위해 권장하는 방법입니다)을 선호한다면 다음 pip 명령으로 virtualenv를 설치하세요.

그런 다음 독립적인 파이썬 환경을 다음과 같이 만들 수 있습니다.

이 환경을 활성화하려면 터미널을 열고 다음 명령을 입력합니다.

환경이 활성화되면 pip 명령으로 설치하는 어떤 패키지든 독립된 이 환경에 설치되고 파이썬은 이 패키지만 사용하게 됩니다(시스템에 설치된 패키지를 사용하고 싶다면 virtualenv 환경을 만들 때 –system-site-packages 옵션을 사용해야 합니다). 더 자세한 정보는 virtualenv 문서를 참고하세요. 11

이제 다음 pip 명령으로 필요한 패키지와 의존성으로 연결된 다른 패키지를 모두 설치합니다.

설치된 것을 확인하려면 다음과 같이 패키지를 모두 임포트해보세요.

어떤 에러나 메시지도 출력되지 않아야 합니다. 이제 다음 명령으로 주피터를 실행합니다.

주피터 서버가 터미널에서 실행되었고 포트 8888번에 대기 중입니다. 웹 브라우저를 사용해 http://localhost:8888/ 주소로 서버에 접근할 수 있습니다(보통 서버가 시작될 때 자동으로 브라우저를 띄워 연결해줍니다). 현재 작업공간 디렉터리가 보일 것입니다(virtualenv 설정을 그대로 따라했다면 env 디렉터리만 있습니다).

New 버튼을 클릭하고 적절한 파이썬 버전을 선택해 새로운 주피터 노트북 12 을 만듭니다(그림2-3).

이 과정에서 세 가지 작업이 일어납니다. 첫째, 작업공간 안에 Untitled.ipynb라는 이름의 새로운 노트북 파일을 만듭니다. 둘째, 이 노트북을 실행하기 위한 주피터 파이썬 커널을 구동시킵니다. 셋째, 새로운 브라우저 탭에서 이 노트북을 엽니다. 시작하기 전에 이 노트북의 Untitled를 클릭해서 이름을 ‘Housing’으로 바꿉니다(이렇게 하면 자동으로 파일 이름이 Housing.ipynb로 변경됩니다).

노트북은 여러 셀 cell 을 포함합니다. 각 셀에는 실행 코드나 포맷된 텍스트를 넣을 수 있습니다. 처음엔 노트북에 ‘In [1]:’이라고 이름이 붙은 빈 코드 셀 하나만 있습니다. 셀에p rint(“Hello world!”)라고 입력하고 play 버튼이나 Shift-Enter 키를 눌러보세요. 이 명령은 현재 셀의 내용을 파이썬 커널에 보내 실행하고 그 결과를 돌려받습니다. 결과가 셀의 아래에 표시되고 노트북의 마지막 셀에 다다랐으므로 새로운 셀이 자동으로 생성됩니다. 주피터의 Help 메뉴에서 User Interface Tour를 사용해 기본 사용법을 익혀보세요.

그림 2-4 Hello world 주피터 노트북

2.3.2 데이터 다운로드

일반적으로 여러분이 다룰 데이터는 관계형 데이터베이스(또는 다른 데이터 저장소)에 들어있고 여러 테이블, 문서, 파일로 나뉘어 있을 것입니다. 이런 데이터에 접근하려면 먼저 보안 자격과 접근 핍 값 계산 방법 권한이 있어야 하고 13 그 데이터의 구조를 잘 알고 있어야 합니다. 하지만 이 프로젝트는 간단합니다. 모든 데이터가 들어 있는 CSV comma-separated value 파일인 housing.csv를 압축한 housing.tgz 파일을 내려받기만 하면 됩니다

웹 브라우저를 사용해 이 파일을 내려받고 tar xzf housing.tgz 명령을 실행해서 압축을 풀어 CSV 파일을 얻을 수 있지만, 간단한 함수를 만들어 사용하면 더 편합니다. 특히 데이터가 정기적으로 변경되면 최근 데이터가 필요할 때마다 스크립트를 실행하면 되니 유용합니다(또는 스케줄링하여 주기적으로 자동 실행할 수도 있습니다). 데이터를 내려받는 일을 자동화하면 여러 기기에 데이터셋을 설치해야 할 때도 편리합니다.

다음 코드가 데이터를 추출하는 함수입니다. 14

fetch_housing_data ( )를 호출하면 작업공간에 datasets/housing 디렉터리를 만들고 housing.tgz 파일을 내려받고 핍 값 계산 방법 같은 디렉터리에 압축을 풀어 housing.csv 파일을 만듭니다.

이제 판다스를 사용하여 데이터를 읽어 들이겠습니다. 데이터를 읽어 들이는 간단한 함수도 하나 만듭니다.

이 함수는 모든 데이터를 담은 판다스의 데이터프레임 객체를 반환합니다.

2.3.3 데이터 구조 훑어보기

DataFrame의 head() 메서드를 사용해 처음 다섯 행을 확인해보겠습니다(그림 2-5).

그림 2-5 데이터셋의 처음 다섯 행

각 행은 하나의 구역을 나타냅니다. 특성은 longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, median_house_value, ocean_proximity 등 10개입니다(그림에는 6개만 보입니다).

info() 메서드는 데이터에 대한 간략한 설명과 특히 전체 행 수, 각 특성의 데이터 타입과 널 null 이 아닌 값의 개수를 확인하는 데 유용합니다(그림 2-6).

그림 2-6 housing.info() 결과

데이터셋에 20,640개의 샘플이 들어 있습니다. 머신러닝 프로젝트치고는 상당히 작은 편이지만, 처음 시작하기에는 적당한 크기입니다. total_bedrooms 특성은 20,433개만 널 값이 아닙니다. 207개의 구역은 이 특성을 가지고 있지 않다는 것을 뜻합니다. 나중에 이 문제를 적절히 처리하겠습니다.

ocean_proximity 필드만 빼고 모든 특성이 숫자형입니다. ocean_proximity 필드의 데이터 타입이 object이므로 어떤 파이썬 객체도 될 수 있지만, 데이터를 CSV 파일에서 읽어 들였기 때문에 텍스트 특성일 것입니다. 처음 다섯 행을 출력했을 때 ocean_proximity 열의 값이 반복되는 것으로 보아서 15 이 특성은 아마도 범주형 categorical 일 것입니다. 어떤 카테고리가 있고 각 카테고리마다 얼마나 많은 구역이 있는지 value_counts() 메서드로 확인합니다.

다른 필드도 살펴보겠습니다. describe() 메서드는 숫자형 특성의 요약 정보를 보여줍니다(그림 2-7).

그림 2-7 숫자형 특성의 요약 정보

count, mean, min, max 행이 의미하는 바는 쉽게 알 수 있습니다. 널 값이 제외된 것을 볼 수 있습니다(예를 들어 total_bedrooms의 count는 20,640이 아니고 20,433입니다). std 행은 값이 퍼져 있는 정도를 측정하는 표준편차를 나타냅니다. 16 25%, 50%, 75% 행은 백분위수 percentile 를 나타냅니다. 백분위수는 전체 관측값에서 주어진 백분율이 속하는 하위 부분의 값을 나타냅니다. 예를 들어 25%의 구역은 housing_median_age가 18보다 작고, 50%는 29보다 작고, 75%는 37보다 작습니다. 이를 25번째 백분위수(또는 제1사분위수), 중간값, 75번째 백분위수(또는 제3사분위수)라고도 합니다.

데이터의 형태를 빠르게 검토하는 다른 방법은 각 숫자형 특성을 히스토그램으로 그려보는 것 입니다. 히스토그램은 주어진 값의 핍 값 계산 방법 범위(수평축)에 속한 샘플 수(수직축)를 나타냅니다. 특성마다 따로 히스토그램을 그릴 수도 있고 전체 데이터셋에 대해 hist() 메서드를 호출하면 모든 숫자형 특성에 대한 히스토그램을 출력합니다(그림 2-8). 예를 들어 median_house_value가 약 $100,000인 구역은 800개가 조금 넘는 것을 볼 수 있습니다.

NOTE_ hist() 메서드는 맷플롯립을 사용하고 결국 화면에 그래프를 그리기 위해 사용자 컴퓨터의 그래픽 백엔드를 필요로 합니다. 그래서 그래프를 그리기 전에 맷플롯립이 사용할 백엔드를 지정해줘야 합니다. 주피터의 매직 명령 %matplotlib inline을 사용하면 편리합니다. 이 명령은 맷플롯립이 주피터 자체의 백엔드를 사용하도록 설정합니다. 그러면 그래프는 노트북 안에 그려지게 됩니다. 17 주피터 노트북에서 그래프를 그릴 때 show() 메서드를 호출하는 것은 선택사항입니다. 주피터는 셀이 실행될 때 자동으로 그래프를 그려 줍니다.

그림 2-8 모든 숫자형 특성에 대한 히스토그램

이 히스토그램에서 몇 가지 사항을 확인할 수 있습니다.

  1. 먼저 중간 소득 median income 특성이 US 달러로 표현되어 있지 않은 것 같습니다. 18 데이터를 취합한 팀에 확인해보니 스케일을 조정하고, 상한이 15(실제로는 15.0001), 하한이 0.5(실제로는 0.4999)가 되도록 만들었다고 합니다. 머신러닝에서는 전처리된 데이터를 다루는 경우가 흔하고 이것이 문제가 되지는 않지만 데이터가 어떻게 계산된 것인지 반드시 이해하고 있어야 합니다.
  2. 중간 주택 연도 housing median age 와 중간 주택 가격 median house value 역시 최댓값과 최솟값을 한정했습니다. 19 중간 주택 가격의 경우는 타깃 속성(레이블)으로 사용되기 때문에 심각한 문제가 될 수 있습니다. 가격이 한곗값을 넘어가지 않도록 머신러닝 알고리즘이 학습될지도 모릅니다. 이것이 문제가 될지 안 될지는 클라이언트 팀(이 시스템의 출력을 사용할 팀)과 함께 검토하는 것이 좋습니다. 만약 그 팀에서 $500,000를 넘어가더라도 정확한 예측값이 필요하다고 한다면 우리가 선택할 수 있는 방법은 두 가지입니다.
    • 한곗값 밖의 구역에 대한 정확한 레이블을 구합니다.
    • 훈련 세트에서 이런 구역을 제거합니다($500,000가 넘는 값에 대한 예측은 평가 결과가 매우 나쁠 것이므로 테스트 세트에서도 제거합니다).
  3. 특성들의 스케일이 서로 많이 다릅니다. 특성 스케일링에 대해서는 이 장의 뒷부분에서 살펴보겠습니다.
  4. 마지막으로 많은 히스토그램의 꼬리가 두껍습니다. 가운데에서 왼쪽보다 오른쪽으로 더 멀리 뻗어 있습니다. 이런 형태는 일부 머신러닝 알고리즘에서 패턴을 찾기 어렵게 만듭니다. 나중에 이런 특성들을 좀 더 종 모양의 분포가 되도록 변형시키겠습니다.

이제 우리가 다룰 데이터를 많이 이해하게 되었습니다.

2.3.4 테스트 세트 만들기

이 단계에서 데이터 일부를 자진해서 떼어놓으라는 것이 이상하게 들릴지 모르겠습니다. 지금까지 데이터를 잠시 살펴봤을 뿐이고 어떤 알고리즘을 사용할지 정하기 전에 전체 데이터를 자세히 파악해야 하지 않을까요? 사실 맞습니다. 하지만 우리 뇌는 매우 과대적합되기 쉬운 엄청난 패턴 감지 시스템입니다. 만약 테스트 세트를 들여다본다면 테스트 세트에서 겉으로 드러난 어떤 패턴에 속아 특정 머신러닝 모델을 선택하게 될지도 모릅니다. 이 테스트 세트로 일반화 오차를 추정하면 매우 낙관적인 추정이 되며 시스템을 론칭했을 때 기대한 성능이 나오지 않을 것입니다. 이를 데이터 스누핑 data snooping 편향이라고 합니다.

테스트 세트를 생성하는 일은 이론적으로 매우 간단합니다. 그냥 무작위로 어떤 샘플을 선택해서 데이터셋의 20% 정도를 떼어놓으면 됩니다.

이 함수를 다음과 같이 사용할 수 있습니다.

좋네요. 이것도 괜찮지만 완벽하지는 않습니다. 프로그램을 다시 실행하면 다른 테스트 세트가 생성됩니다! 여러 번 계속하면 우리는(또는 우리 머신러닝 알고리즘이) 전체 데이터셋을 보는 셈이므로 이런 상황은 피해야 합니다.

한 가지 해결책은 처음 실행에서 테스트 세트를 저장하고 다음번 실행에서 이를 불러들이는 것입니다. 또 다른 방법은 항상 같은 난수 인덱스가 생성되도록 np.random.permutation()을 호출하기 전에 난수 발생기의 초깃값을 지정하는 것입니다(예를 들면 np.random.seed(42) 20 ).

하지만 이 두 해법 모두 다음번에 업데이트된 데이터셋을 사용하려면 문제가 됩니다. 일반적인 해결책은 샘플의 식별자를 사용하여 테스트 세트로 보낼지 말지 정하는 것입니다(샘플이 고유하고 변경 불가능한 식별자를 가지고 있다고 가정합니다). 예를 들어 각 샘플마다 식별자의 해시값을 계산하여 해시의 마지막 바이트의 값이 51(256의 20% 정도)보다 작거나 같은 샘플만 테스트 세트로 보낼 핍 값 계산 방법 수 있습니다. 이렇게 하면 여러 번 반복 실행되면서 데이터셋이 갱신되더라도 테스트 세트가 동일하게 유지됩니다. 새로운 테스트 세트는 새 샘플의 20%를 갖게 되지만 이전에 훈련 세트에 있던 샘플은 포함시키지 않을 것입니다. 다음은 이를 구현한 코드입니다. †

안타깝게도 주택 데이터셋에는 식별자 컬럼이 없습니다. 대신 행의 인덱스를 ID로 사용하면 간단히 해결됩니다.

housing_with_id = housing.reset_index() # ‘index’ 열이 추가된 데이터프레임이 반환됩니다.
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "index")

행의 인덱스를 고유 식별자로 사용할 때 새 데이터는 데이터셋의 끝에 추가되어야 하고 어떤 행도 삭제되지 않아야 합니다. 이것이 불가능할 땐 고유 식별자를 만드는 데 안전한 특성을 사용해야 합니다. 예를 들어 구역의 위도와 경도는 몇백 년 후까지 안정적이라고 보장할 수 있으므로 두 값을 연결하여 다음과 같이 ID를 만들 수 있습니다. 21

사이킷런은 데이터셋을 여러 서브셋으로 나누는 다양한 방법을 제공합니다. 가장 간단한 함수는 train_test_split으로, 앞서 우리가 만든 split_train_test와 아주 비슷하지만 두 가지 특징이 더 있습니다. 첫째 앞서 설명한 난수 초깃값을 지정할 수 있는 random_state 매개변수가 있고, 둘째 행의 개수가 같은 여러 개의 데이터셋을 넘겨서 같은 인덱스를 기반으로 나눌 수 있습니다(이는 예를 들어 데이터프레임이 레이블에 따라 여러 개로 나뉘어 있을 때 매우 유용합니다). 22

지금까지는 순수한 무작위 샘플링 방식을 보았습니다. 데이터셋이 충분히 크다면(특히 특성 수에 비해) 일반적으로 괜찮지만, 그렇지 않다면 샘플링 편향이 생길 가능성이 큽니다. 설문조사 기관에서 1,000명에게 질문 몇 개를 하려 할 때 그냥 전화번호부에서 1,000명을 무작위로 뽑는 것이 아닙니다. 전체 인구를 대표할 수 있는 1,000명을 선택하기 위해 노력합니다. 미국 인구의 51.3%가 여성이고 48.7%가 남성이라면, 잘 구성된 설문조사는 샘플에서도 이 비율을 유지해야 합니다. 즉, 여성은 513명, 남성은 487명이어야 합니다. 이를 계층적 샘플링 stratified sampling 이라고 합니다. 전체 모수는 계층 strata 이라는 동질의 그룹으로 나뉘고, 테스트 세트가 전체 모수를 대표하도록 각 계층에서 올바른 수의 샘플을 추출합니다. 기본 무작위 샘플링을 사용하면 49%보다 적거나 54%보다 많은 여성이 테스트 세트에 들어갈 확률이 약 12%입니다. 23 어느 방법을 사용하든 설문조사 결과를 크게 편향시키게 됩니다.

전문가가 중간 소득이 중간 주택 가격을 예측하는 데 매우 중요하다고 이야기해주었다고 가정합시다. 이 경우 테스트 세트가 전체 데이터셋에 있는 여러 소득 카테고리를 잘 대표해야 합니다. 중간 소득이 연속적인 숫자형 특성이므로 소득에 대한 카테고리 특성을 만들어야 합니다. 중간 소득의 히스토그램을 조금 더 자세히 살펴보겠습니다([그림 2-8] 참조). 중간 소득 대부분은 $20,000~$50,000 사이에 모여 있지만 일부는 $60,000를 넘기도 합니다. 계층별로 데이터셋에 충분한 샘플 수가 있어야 합니다. 그렇지 않으면 계층의 중요도를 추정하는 데 편향이 발생할 것입니다. 이 말은 너무 많은 계층으로 나누면 안 된다는 뜻이고 각 계층이 충분히 커야 합니다. 다음 코드는 중간 소득을 1.5로 나누고(소득의 카테고리 수를 제한하기 위해), ceil 함수를 사용하여 올림해서 소득 카테고리 특성을 만들고(이산적인 카테고리를 만들기 위해), 5보다 큰 카테고리는 5로 합칩니다.

[그림 2-9]는 이 소득 카테고리의 히스토그램입니다.

그림 2-9 소득 카테고리의 히스토그램

이제 소득 카테고리를 기반으로 계층 샘플링을 할 준비가 되었습니다. 사이킷런의 StratifiedShuffleSplit를 사용할 수 있습니다. 24

의도대로 되었는지 살펴보겠습니다. 전체 주택 데이터셋에서 소득 카테고리의 비율을 먼저 살펴보겠습니다.

비슷한 코드로 테스트 세트에 있는 소득 카테고리의 비율을 측정합니다. [그림 2-10]은 전체 데이터셋과 계층 샘플링으로 만든 테스트 세트에서 소득 카테고리 비율을 비교한 것입니다. 그림에서 보듯이 계층 샘플링을 사용해 만든 테스트 세트가 전체 데이터셋에 있는 소득 카테고리의 비율과 거의 같습니다. 반면 일반 무작위 샘플링으로 만든 테스트 세트는 비율이 많이 달라졌습니다.

그림 2-10 계층 샘플링과 순수한 무작위 샘플링의 샘플링 편향 비교

이제 income_cat 특성을 삭제해서 데이터를 원래 상태로 되돌리겠습니다. 25

테스트 세트 생성에 대해 자세히 설명한 데는 그럴 만한 이유가 있습니다. 종종 등한시되기도 하지만 머신러닝 프로젝트에서 아주 중요한 부분이기 때문입니다. 게다가 이런 아이디어들은 나중에 교차 검증에 대해 이야기할 때 도움이 됩니다. 이제 데이터를 탐색하는 다음 단계로 넘어갑시다.

[머신러닝] 클러스터링 평가지표 - 실루엣 계수 (1)

군집 안에 있는 데이터들은 잘 모여있는지, 군집끼리는 서로 잘 구분되는지 클러스터링을 평가하는 척도로 활용된다.

* 참고한 논문의 표현을 빌리자면, 군집 비유사성('within' dissimilarities)은 작고, 군집 비유사성('between' dissimilarities)은 커야 생성된 클러스터의 품질이 좋다고 할 수 있다.

이번 포스팅에서는 실루엣 계수를 구하는 방법과 평가 지표로써의 장단점에 대해 알아보고자 한다.

실루엣 계수 구하는 방법

왼쪽 그림처럼 어떠한 클러스터링 기법에 의해 총 10개의 데이터 포인트들이 3개의 군집으로 나눠졌다고 하자.

클러스터 A의 데이터 포인트 i를 선택하고, 데이터 포인트 i의 실루엣 계수를 구할 것이다.

우선 데이터 포인트 i가 속한 클러스터 A 안에 있는 다른 데이터 포인트들과의 거리 평균을 구한다.

그리고, 데이터 포인트 i가 속하지 않은 클러스터 B의 데이터 포인트들과 거리 평균을 구하고, 마찬가지로 클러스터 C의 데이터 포인트들과 거리 평균을 구한다.

클러스터 B와 C 중 데이터 포인트 i와 가까운 클러스터(=이웃 클러스터)는 B이므로 \(b(i)\) 값은 5.3이 되며, \(a(i)\), \(b(i)\) 값으로 데이터 포인트 i의 실루엣 계수 \(s(i)\) 값을 구한다.

* 실루엣 계수 계산식의 분모는 두 군집 간 거리를 정규화하는 스케일러의 역할을 한다.

* 동일한 클러스터 내에 있더라도 데이터 포인트마다 이웃 클러스터는 다를 수 있다.

* 만일 클러스터 안에 1개의 데이터 포인트만 존재하는 경우, 해당 데이터 포인트의 실루엣 계수는 0으로 본다.

위 그림처럼 모든 데이터 포인트들에 대해 실루엣 계수를 계산했다면, 실루엣 계수들의 평균값(overall average silhouette width)을 계산해준다. 만일 클러스터 개수별로 여러 번 군집화를 수행했거나, 여러 클러스터링 기법으로 여러 번 군집화를 수행한 경우 실루엣 계수의 평균값을 비교하여, 클러스터 개수를 몇 개로 할 것인지, 혹은 어떤 클러스터 기법을 선택할 것인지 판단할 수 있다.

* 실루엣 계수의 평균값이 1에 가까울수록 군집화가 잘 되었다고 생각할 수 있다.

* 각 클러스터 내의 데이터 포인트들의 실루엣 계수 평균값을 구하여, 각 클러스터별 평균값도 구할 수 있다. 1에 가까운 평균값을 가지는 클러스터는 'clear-cut' 클러스터, 0에 가까운 값을 가지는 클러스터는 'weak' 클러스터로 표현된다.


0 개 댓글

답장을 남겨주세요