아카이브/통계학

[통계학] 변수와 줄기잎그림, Variable and StemPlot (R, C++)

될성부른떡잎 2015. 11. 4. 15:26


[통계학] 변수와 줄기잎그림, Variable and StemPlot


변수 (Variable)

조사 대상의 관심이 되는 특성 혹은 결과 요소의 개별 값. 키, 몸무게, 매출액 등은 모두 변수이다. 변수는 질적 변수(qualitative variable)양적 변수(quantitative variable)로 분류된다. 

양적 변수(quantitative variable)는 결과가 숫자로 표현되는 값이다. 몸무게, 키, 전기 요금 등이 있다. 양적 변수는 연속 변수(continuous variable)이산 변수(discrete variable)로 나뉘는데, 연속 변수는 무게, 높이, 시간 등 변수가 취할 수 있는 값이 셀 수 없이 많다. 반면 이산 변수는 인원 수, 월급 등 변수가 취할 수 있는 값을 셀 수 있다.

질적 변수(qualitative variable)는 결과가 숫자로 표현되지 않는 값이다. 물체의 색, 좋다 싫다, 하나의 동전을 던졌을 때의 결과 등이다. 하지만 동전을 던졌을 때 앞면을 0, 뒷면을 1이라고 한다면 이 변수는 양적 변수에 속하게 된다.


줄기 잎 그림(Stem Plot)

줄기 잎 그림은 데이터를 시각적으로 표현하는 기본적인 방법이다. R과 C++을 이용해서 줄기 잎 그림을 그려보도록 하겠다. 그 전에 줄기 잎 그림의 장단점과 그리는 방법에 대해서 간략하게 알아보도록 하겠다.


장점

   - 자료가 크기 순서로 나열되어, 사분위수나 중간 값을 쉽게 알 수 있다.

    - 분포의 전체적인 모양을 한눈에 볼 수 있다. 봉우리의 개수, 대칭 분포 혹은 치우친 방향 등을 쉽게 알 수 있다.

    - 이상치(outlier, 다른 값에 비해 특히 크거나 작은 값)가 있는지 쉽게 알 수 있다.


단점

    - 자료가 많은 경우에는 부적합하다.(자료가 많은 경우에는 히스토그램이 더 적합하다.)


그리는 방법

1. 관측 값을 줄기(stem)과 잎(leaf) 두 부분으로 나눈다. 일반적으로 줄기는 두 자리 수 이상이 될 수 있지만 잎은 한자리 수여야 한다. 잎은 일의 자리 숫자로 하고 줄기는 나머지 값으로 한다.

2. 왼 쪽에 열을 맞추어 줄기 값을 작은 수부터 쓰고 줄기 옆에 직선을 긋는다.

3. 십의 자리의 숫자 각각에 해당하는 일의 자리 숫자를 잎으로 해서 세로 줄의 오른쪽에 가로로 나열한다. 중복된 값은 중복된 횟수만큼 나열한다.


데이터

데이터는 메모장에 입력하고 저장하면 된다.

아래 데이터는 50대 남성 35명의 체중이라고 가정하고 진행하겠다.


R Code

- 데이터 불러오기(or 입력 받기)

    1. 파일 입력. (unlist 함수를 이용해서 테이블의 원소를 분리 시켜 주어야 한다.)

    2. 콘솔 입력.

    3. scan 명령어로 하나하나 입력.


- 줄기 잎 그림 그리기

R은 줄기 잎 그림을 그리는 stem()함수를 제공한다. 읽을 때는 줄기에 잎을 더해서 읽으면 된다. 첫 줄은 56, 57, 58, 59이다. 데이터가 많은 경우에는 줄기 값 6처럼 두 개로 사용하기도 한다. 60~64가 윗 줄, 65~69가 아랫 줄이다. R은 다양한 데이터 분석 함수를 지원하고 있어서, 간단하게 데이터 분석이 가능하다.


C++ Code

하지만 C++는 기본적으로 제공하지 않기 때문에 만들어 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
 
// 데이터 파일에서 데이터를 읽는 함수
void generateDataSet(std::vector<int> &v, std::ifstream &in, int size);
// 줄기 잎 그림을 그리는 함수
void printStemAndLeaf(std::vector<int> &v, int size);
 
int main() {
    std::ifstream inStream;
    inStream.open("data.txt");
 
    // 데이터 파일의 제일 첫 줄에 데이터 개수를 추가해 준다.
    // 이번 예제는 35명의 데이터이므로 35를 맨 앞부분에 추가해 준다.
    int size;
    inStream >> size;
 
    // 데이터 파일의 데이터 수 만큼 벡터에 저장
    std::vector<int> dataVec;
    generateDataSet(dataVec, inStream, size);
 
    // 벡터 안의 데이터를 오름차순으로 정렬
    std::sort(dataVec.begin(), dataVec.end());
 
    // 줄기 잎 그림 출력
    printStemAndLeaf(dataVec, size);
 
    inStream.close();
    return 0;
}
 
void generateDataSet(std::vector<int> &v, std::ifstream &in, int size)
{
    int tmp;
    // 파일 입출력으로 size 만큼 읽고 벡터에 추가
    for (int i=0; i<size++i)
    {
        in >> tmp;
        v.push_back(tmp);
    }
}
 
void printStemAndLeaf(std::vector<int> &v, int size)
{
    // stem : v[i]의 줄기 값, leaf : v[i]의 잎 값
    // prevStem : 줄기 값이 바뀌는 부분을 알기 위해 사용한 변수
    // divider : 잎 값의 범위를 위해 사용하는 변수
    std::cout << "--- Stem-And-Leaf Plot ---" << std:: endl;
    int stem, leaf, prevStem=-1, divider=10;
    for (int i=0; i<size++i)
    {
        stem = v[i]/divider;
        leaf = v[i]%divider;
        // v[i]의 줄기 값(stem)과 이전 줄기 값(prevStem)이 달라지면 줄 바꾸고 바뀐 줄기 값 출력
        // prevStem에 바뀐 줄기 값 저장
        if (stem != prevStem) {
            std::cout << std::endl << stem << " | ";
            prevStem = stem;
        }
        std::cout << leaf << " ";
    }
}
cs



정리

결과를 보면 비교적 대칭인 분포를 하고 있고 중앙 값은 74kg인 것을 알 수 있다. 그리고 특별하게 크거나 작은 이상치도 없는 걸 알 수 있다.

R로 한 줄이면 되는 걸 굳이 C++로 구현한 것은 실행 속도 때문이다. 데이터가 많아지는 경우 C++가 R에 비해서 속도 면에서 월등하다고 한다. 또한 만들어진 함수를 사용하더라도 구현 방식을 알고 사용 하는 것이 중요하다고 생각한다.

줄기 잎 그림 중에는 두 개의 줄기 잎 그림을 동일한 줄기를 중심으로 좌우로 나열한 서로 맞댄 줄기 잎 그림(back-to-back stem plot)이 있다. back-to-back 줄기 잎 그림은 다음 번에 포스팅 하도록 하겠다.


'아카이브 > 통계학' 카테고리의 다른 글

[통계학 개요] 통계학이란..  (0) 2015.10.31