ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 03-4 중심경향의 지표 : 최빈값
    데이터 분석/파이썬으로 배우는 데이터 분석을 위한 통계학 2022. 3. 16. 00:20

     다음으로는 최빈값에 대해 살펴볼게.

     최빈값(mode)은 점수치들 중에서 가장 빈번하게 나타나는 놈을 뜻 해. 만약 점수치들이 '1, 2, 2, 3, 3, 3, 4, 4, 4, 4'와 같다면? 1이 한 개, 2가 두 개, 3이 세 개, 4가 네 개로 4가 가장 많이 등장하는 것을 알 수 있어. 그럼 4가 이 점수치들의 최빈값이 되는거야. 진짜 쉽지?

     

     어? 그런데 만약 최빈값이 둘 이라면?

     만약 점수치들이 '5, 6, 6, 7, 7, 7, 8, 8, 8'과 같다면 7과 8이 각각 세 번씩 등장하기 때문에 동률이 돼. 그럼 이 때 어떤 놈을 최빈값으로 해야 될까? 중앙값을 구했던 때 처럼 둘의 평균을 최빈값으로 할까?

     

     안돼! 멈춰! 동률인 최빈값이 관측되었다면, 따로 무슨 짓을 하지 않아도 돼. 둘 다 최빈값이기 때문이야. 둘 이상의 최빈값이 관측되어도 그놈들 전부 최빈값이 되는거야. 위와 같은 점수치들에서는 7과 8 둘 다 최빈값이 되는거지. 최빈값이 둘 이라면 양봉적(bimodal), 둘 이상이라면 다봉적(multimodal)이라고 할 수 있어.

     

     최빈값은 따로 구하는 공식이 없기 때문에 눈으로 세야만 해. 점수치가 많으면 굉장히 곤란하겠지?

     하지만 파이썬을 사용하면 쉽게 최빈값을 구할 수 있어!

     

    -

     

     만약 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 이라는 숫자들이 있다면 최빈값은 4가 될거야. 4가 가장 많이 등장하니까. 그치? nums 라는 리스트를 만들어서 이 숫자들을 담아볼게.

     

    nums = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

     

     그리고 nums에서 가장 많이 등장하는 4를 뽑아내고 싶은데.. 어떻게 하면 좋을까?

     많은 방법들이 있겠지만 이번에 소개할 방법은 파이썬이 아닌 다른 프로그래밍 언어에서도 쓸 수 있는 범용적이고 정석적인 방법으로 소개할거야. 그리고 파이썬에서 쉽게 구할 수 있는 방법은 나중에 다시 다룰게.

     

     최빈값을 구하는 방법을 배우려면 '반복문 (loop statement)'에 대해 알아야 돼.

     반복문에는 크게 두 가지 반복문이 있어. '포(for)문'과 '와일(while)문'이야. 어디서 한 번 쯤은 들어 봤지?

     

     for문은 주로 반복 횟수가 정해져 있을 때 사용하면 좋아. while문은 주로 반복 조건이 정해져 있을 때 사용하면 좋고. 예를 들어볼까?

     

     엄마가 학성이 방을 보더니, "학성아! 방바닥이 너무 드럽구나!" 라고 하셨어 그리곤

     "방바닥 걸레질을 100번 하거라!" 라고 하셨다면 이 명령은 for문으로 처리될 수 있어. 반복 횟수가 정해져 있으니까.

     그런데 만약, "방바닥이 반짝거릴 때 까지 걸레질을 하거라!" 라고 하셨다면? 이 명령은 while문으로 처리될 수 있어. '반짝거릴 때 까지'라는 조건이 정해져 있으니까.

     

     우리는 두 가지 반복문 중에 for문을 먼저 배워 볼 거야. while문에 대해 배우는 것은 다음 기회로 미뤄 놓자구!

     

     for에서 가장 중요한 것은 반복 횟수야. 특히 파이썬에서는 반복 횟수만 정해주면 쉽게 for문을 사용할 수 있어. 문법은 아래와 같아.

     

    for 반복에 사용되는 것 in 반복가능한 것:
     반복할 내용

     

     이렇게 보면 잘 모르겠지? 아래의 코드를 실행시켜볼까?

     

     

     코드를 보면 for문을 통해 반복하도록 되어있어. 반복할 땐 nums라는 리스트에서 항목(item)을 사용해 반복하기로 했어. 그리고 각각의 항목을 출력하도록 반복 내용을 정해주었지. 어때? 코드 실행 버튼을 눌러보면 정말로 nums의 항목들이 하나씩 출력되는게 보이지?

     

     이게 파이썬에서 리스트를 활용해 for문을 사용하는 방법이야. 참 쉽지?

     

     다음으로는 리스트를 활용하지 않고 내가 원하는 횟수만큼 반복하도록 하는 for문을 만들어 볼게. 이 때 필요한 내장 함수가 있는데 'range()'라는 함수야. range() 함수는 말 그대로 내가 원하는 만큼의 범위를 만들어 낼 수 있는 함수야. 소괄호() 안에 내가 만들어 내고자 하는 범위를 정해주면 되는데, 우리는 쉽게 자연수 하나만 입력해서 범위를 정해 줄 거야. 예를 들어 range(10) 이라면 0부터 10까지의 범위를 만든다는 것이지! 다만 0부터 10까지의 범위라는 것에서 10은 포함하지 않아.

     

     그리고 for문에 range()함수를 사용할건데 in 뒤에 range()함수를 붙여주면 돼. 이번에는 반복자를 뜻하는 i를 range()의 범위 만큼 출력하도록 하는 코드를 만들어서 실행시켜 볼거야.

     

     

    위의 코드를 실행시켜 보면 0부터 9까지 출력되는 것을 볼 수 있어. 왜? range(10) 함수가 0부터 10까지의 범위를 만들었기 때문이지. 10이 포함되지 않는 이유는 위에서 설명 했지? range() 함수가 마지막 숫자를 포함하지 않기 때문이야.

     

     range() 함수는 리스트와 궁합이 잘 맞아. 리스트의 가장 첫 번째 항목의 인덱스가 0부터 시작하고, range() 함수도 0부터 범위를 만들어 내니까! 그래서 리스트와 for문을 배울 때 range() 함수도 같이 배우고 기억하면 훨씬 활용하기 쉬울거야.

     

     만약 0부터 시작하는게 싫거나, 1씩 증가하는게 싫다면 아래와 같이 사용할 수도 있어.

     

    range(끝) # 0부터 끝 숫자 까지의 범위 (단, 끝 숫자는 포함하지 않음)
    range(시작, 끝) # 시작 숫자 부터 끝 까지의 범위 (단, 끝 숫자는 포함하지 않음)
    range(시작, 끝, 간격) # 시작 부터 끝 까지의 범위를 간격 숫자 만큼으로 (단, 끝 숫자는 포함하지 않음)

     

     내가 시작 숫자와 끝 숫자 혹은 간격을 정해 줄 수 있다는 것이지! 아래의 코드를 실행해 보면 이해하기 쉬울거야.

     

     

     중요한 것은 끝 숫자가 포함되지 않는다는거! 기억해!

     

     이제 우리가 배운 range() 함수와 for문을 사용해서 새로운 리스트를 만들거야. 여태까지는 처음부터 리스트에 여러가지 항목들을 직접 입력해서 선언했다면, 이번에는 for문을 사용해서 리스트의 항목들을 직접 만드는거야. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]과 같은 리스트 말야. 숫자가 10개 밖에 없으니까 직접 입력하는것도 어렵지 않겠지? 하지만 숫자가 백 개, 천 개, 만 개가 넘어가면 직접 입력해서 만드는 일은 불가능 하겠지. 하지만 for문이 있다면 할~ 수 있어~

     

     그 전에! 리스트에서 사용될 함수 하나만 배우고 갈게. append()라는 함수야. 소괄호 안에 리스트에 추가할 내용을 정해주면 돼. 대신 append()라는 함수는 단독으로 사용할 수는 없어. 리스트와 같이 사용해야 돼.

     

    리스트이름.append(추가할 항목)

     

     만약 '유재석', '정형돈', '노홍철'이라는 항목이 담겨있는 'mudo'라는 리스트가 있다고 해 볼게.

     

    mudo = ['유재석', '정형돈', '노홍철']

     

     이 mudo라는 리스트에 '김태호'라는 항목을 추가하고 싶다면? 간단해! mudo.append('김태호') 라는 코드를 작성하기만 하면 되지!

     

     

     위 코드를 실행해 보면 mudo라는 리스트에 '김태호'라는 항목이 추가된 것을 볼 수 있어. 참 쉽지?

     

     이제 append() 함수를 사용해서 1부터 100까지 숫자를 리스트에 담아 볼 거야. 재밌겠다!

     먼저 '몇 번이나 반복할 것이가?' 부터 생각해야 돼. for문의 핵심은 반복 횟수에 있으니까. 1부터 100까지의 숫자는 총 100개이기 때문에 100번 반복하면 될거야. 100번 반복하려면 range() 함수에 100을 넣어주면 되겠지? 그럼 0부터 100까지의 범위를 만들거야! 그리고 range() 함수의 숫자들을 아무것도 들어있지 않은 빈 리스트에 append() 함수를 사용해서 하나씩 추가해주면 되는거지. 아래의 코드처럼!

     

     

     어 그런데 우리가 원하는 것은 1부터 100까지의 숫자인데, 리스트에는 0부터 99까지의 숫자가 들어가 있어. 왜지?

     range() 함수는 0부터 마지막 숫자까지의 범위인데! 마지막 숫자를 포함하지 않기 때문이야! 사실 0부터 99인 것이지! 그럼 이 문제를 해결하기 위해 두 가지 방법으로 접근할 수 있을거야.

     

     ⓐ range() 함수의 범위를 range(1, 101)로 정하기

     ⓑ 0부터 99니까 각각의 숫자를 1씩 더해서 리스트에 추가하기

     

     위의 방법들로 코드를 수정해 볼까? 먼저 ⓐ 방법 부터 볼게.

     

     

     짜잔! 우리가 원하던 대로 1부터 100까지의 숫자가 리스트에 담겼어. 됐지? 이제 다른 방법, ⓑ로 작성된 코드를 볼게.

     

     

    짜잔! 이 방법 역시 우리가 원하던대로 1부터 100까지의 숫자가 리스트에 담겼어. 

     

    어떤 방법이든 결과는 똑같아. 어느 방법이 더 좋다, 나쁘다 라고도 할 수 없고 말야. 하지만 난 코드의 범용성과 파이썬이라는 언어의 특성을 생각하면 ⓑ의 방법을 선호하는 편이야. 여러분들은 여러분들이 마음에 드는 방법을 선택하면 돼!

     

     마지막으로 max()라는 내장 함수에 대해 살펴볼건데, 얘는 참 쉬워 말 그대로 제일 큰 숫자를 돌려주는 함수거든. 아래의 코드를 보면 바로 이해가 될거야.

     

     

     max() 함수를 출력했더니 1, 3, 5, 7, 9 중에서 가장 큰 숫자를 출력해 주는 모습을 볼 수 있어. 참 쉽지?

     

    -

     

     이제 본격적으로 최빈값을 구해볼까?

     

     최빈값을 구하려면 우선 주어진 숫자들의 리스트를 사용해서 새로운 리스트를 만들거야. 새로운 리스트로 최빈값을 구해 볼거거든. 방법은 쉬워. 반장(회장) 선거를 떠올려 보면 돼.

     

     선거 투표가 끝나면 모든 투표 용지를 회수한 다음 어느 후보가 몇 표나 얻었는지 기록하잖아? 그 과정과 마찬가지야. 기존의 리스트에 있는 숫자를 새로운 리스트에 하나씩 추가해 나가는거지. 이 때 활용하는 놈이 인덱스야. 기존의 리스트의 항목을 인덱스로 가지고 있는 새로운 리스트에 항목에 1씩 추가해 나가는거야.

      기존 리스트의 항목들로 반복해 나가면서 새로운 리스트의 항목을 채워 나가는거지. 그렇다보면 기존 리스트에서 등장하는 숫자들의 몇 번이나 등장했는지 알아낼 수 있을거야. 말이 어렵지? 코드로 만들어 가면서 같이 살펴볼까?

     

     

     위 코드의 for문을 보면 nums 리스트가 가지고 있는 가장 큰 숫자를 사용해서 range() 함수로 범위를 만들었어. 다만 우리가 필요한 것은 nums 리스트의 항목을 가지고 인덱스에 활용하고 싶기 때문에 1을 더해 주었어. 그래야 가장 큰 숫자인 4를 인덱스로 하는 방을 frequency 리스트에 만들어 줄 수 있잖아. 각각의 인덱스의 방에는 0이라는 항목들을 append() 함수로 넣어주었고 말야.

     

     이제 0으로 초기화 된 frequency 리스트에 빈도를 구해주기만 하면 돼. nums 리스트의 항목을 인덱스로 하는 방에 1씩 추가만 해주면 돼. 코드로 보면,

     

     

    위와 같이 나타낼 수 있어. frequency 리스트에 [0, 1, 2, 3, 4]가 출력된 것을 볼 수 있는데, 이 뜻은 각각의 인덱스의 item이 nums에 등장하는 빈도라는 뜻이야. frequency 리스트의 인덱스가 4인 놈의 항목이 4인 것은, nums 리스트에 4가 4번 등장한다는 뜻이지. 여러분들은 코드에서 nums의 숫자들을 바꿔 가면서 코드를 실행해 봐! 그럼 결과값이 달라지는 것을 확인할 수 있을거야.

     

     이제 최종적으로 빈도가 제일 높은 놈을 찾아 내서 출력할건데, 이를 위해선 리스트에서 사용되는 index()라는 함수에 대해 알아야 돼. index()라는 함수는 말 그대로 리스트에서 항목의 인덱스를 돌려주는 함수야.

     

    리스트이름.index(항목)

     

     만약 mudo = ['유재석', '정형돈', '노홍철'] 라는 리스트가 있다면 mudo.index('정형돈')은 1을 반환할거야. 왜? mudo 리스트에서 '정형돈'의 인덱스는 1이니까!

     

     이 index() 함수를 사용하면 최빈값을 구할 수 있어. 아래의 코드를 볼까?

     

     

     mode라는 변수에 frequency 리스트에서 가장 큰 값을 항목으로 갖고 있는 인덱스를 담아 주었어. 그리고 출력해 보니 4가 출력되네? 최빈값이 4라는 뜻이지!

     

     여러분들은 nums의 숫자들을 바꿔가면서 코드가 어떻게 동작하는지 잘 살펴봤음 좋겠네!

     

    -

     

     중심경향의 지표인 평균과 중앙값 그리고 최빈값에 대해 배워봤어. 어때? 각자의 개성이 있지?

     점수치들이 어떻게 구성되어있느냐에 따라서 집단을 대표하는 중심경향에 평균이 적합할 수도 있고, 중앙값이 적합할 수도 있고, 최빈값이 적합할수도 있어. 만약 분포가 아래와 같다고 해볼게.

     

    분포 평균 중앙값 최빈값
    1, 3, 5, 7, 9 5 5 1, 3, 5, 7, 9
    1, 3, 5, 7, 99 23 5 1, 3, 5, 7, 99
    1, 3, 5, 7, 999 203 5 1, 3, 5, 7, 999

     

     위와 같이 평균은 어느 한 점수치에 의해 영향을 굉장히 많이 받을 수 있어. 반면 중앙값은 그렇지 않지. 그리고 최빈값은.. 사실 특정한 상황 외에는 별 쓸모가 없어. 딱 봐도 그렇지?

     

     물론 평균이나 중앙값 그리고 최빈값이 같을수도 있어. 점수치들이 '1, 2, 2, 3'과 같다면 그렇게 되겠지? 그림으로 살펴볼게.

     

    평은 평균, 중은 중앙값 그리고 최는 최빈값

     위와 같은 분포를 나타내고 있다면 평균과 중앙값 그리고 최빈값이 같을 수 있지. 우리가 배우게 될 인간과 관련된 점수치들은 주로 위와 같이 나타나게 될거야. 신장(키)이라던가 분당 맥박수, 눈 깜빡임 횟수 등 여러가지 것들이 이런 분포를 보일거야. 그런 것들은 나중에 살펴보기로 하자구!

     다음으로는

     

    평은 평균, 중은 중앙값 그리고 최는 최빈값

     위와 같은 분포를 보일수도 있어. 남성과 여성의 신장등이 위와 같은 분포를 가질 수 있을거야. 점수치가 낮은 최빈치는 여성의 신장, 점수치가 높은 최빈치는 남성의 신장이 될 수 있겠지? 그리고 평군과 중앙치가 같을수도 있을것이고.

     다음으로는

     

     위와 같은 분포를 보일수도 있는데, 이 분포는 부적 편포도라고도 해. 기억나지?

     암튼 우와 같은 분포에서는 평균과 중앙값 그리고 최빈값이 모두 다른 상황이야. 저번에 시험 점수 가지고 빈도분포표 만들었을 때 이와 같은 모습의 분포를 볼 수 있었을거야. 시험이 쉬워서 대부분의 학생들이 좋은 점수를 받는다면 이런 분포를 볼 수 있지!

     

     이렇듯 분포에 따라 집단을 대표하는 집중경향의 지표를 어떤 것으로 해야하는지 고민이 생길 수 있어. 집중경향에 대해 공부하기 전에 평균만 알고 있었던 때가 더 좋았던 것 같기도 해. 아는게 평균밖에 없으니 고민하지 않아도 되니까. 하핫! 그래도 너무 걱정은 하지마! 우리가 다룰 사화과학, 과학분야에서는 대부분의 상황에서 평균을 집중경향의 측정치로 사용하니까! 평균을 집중경향의 측정치로 사용하는 여러가지 이유가 있겠지만 가장 중요한 이유는 많은 다른 통계 절차에 평균이 요구되기 때문이야.

     그래도 중앙값이나 최빈값도 상황에 따라 쓰일 수 있다는 것은 잊지 말구! 특히 변산성이 큰 경우에는 평균의 힘이 약해질 수 있겠지? 마이클 조던의 일화처럼 말야! 많은 경제학자들은 경제적 지표와 같이 극단의 차이가 많이 나는 경우에는 평균보다는 중앙값이 더 적절한 집중경향의 지표라고들 말해.

     

     앞으로는 평균만 생각하지 말고 우리가 배운 집중경향의 지표들을 적절하게 생각하면서 살았으면 좋겠어! 안녕~!

Designed by Tistory.