변수의 특성
내용
변수의 종류
측정, 설문, 연구 등에 의해 생성되는 모든 자료들이 변수가 될 수 있으며 기계학습에서는 특징(feature)이라는 용어를 사용하기도 합니다. 데이터 셋에서 나타내는 모든 변수들을 포함하는 하나의 세트를 인스턴스 (instance) 또는 샘플(smaple)이라고 합니다. 예를 들어 표 1은 는 이름, 나이, 성별, 키(height)라는 4개의 변수와 3개의 사건 즉, 인스턴스들을 포함하고 있습니다. 일반적으로 통계분석을 위한 자료는 표 1의 형식과 같이 각 변수는 열(column), 인스턴스는 행(row)으로 구성됩니다. 이러한 자료들의 모음을 데이터 셋(data set)이라 합니다
이름 | 나이 | 성별 | 키 |
---|---|---|---|
철수 | 10 | 남 | 153 |
영희 | 15 | 여 | 161 |
길동 | 21 | 남 | 181 |
표 2에서 나타낸 것과 같이 모든 변수들은 목록변수와 양적변수로 구분하며 또한 측정 수준에 따라 명목형, 순위형, 이산형, 연속형로 구분합니다.
변수 | 내용 | 측정수준 |
---|---|---|
목록변수(Categorical variables) | 그룹/목록 표시 | 명목형(Nominal) |
순위형(Ordinal) | ||
양적변수(Quantitative variables) | 수량/크기 표시 | 이산형(Discrete) |
연속형(Continuous) |
목록변수(Categorical variables)중,
- 명목형(변수)은 논리적 순서가 없는 질적 분류만이 가능한 변수입니다. 예로서 사과, 배, 수박의 과일을 분류하기 위해 각각 1,2,3의 숫자를 지정할 수 있습니다. 그러나 이 숫자들은 정성적 또는 정량적인 순위의 의미를 가질 수 없습니다.
- 순위형 변수는 단지 순서를 부여하는 것만 가능합니다. 예로서 영화에 대한 순위는 일정한 범위 내에서 부여되는 평점 데이터를 사용하여 순위를 매겨질 수 있습니다. 그러나 평점은 주관적인 평가이고 각 평점 사이의 간격 역시 일정하다고 할 수 없습니다.
양적변수(Quantitative variables) 의 경우 측정 수준에는 고유한 순위가 존재하며 그 수준들 사이의 차이는 측정 가능하며 상호 관련성이 존재합니다. 또한 그 수치 자체가 의미를 가집니다. 그러므로 동일한 수준의 경우 동일한 의미를 갖습니다. 이러한 측정 수준의 경우 다음과 같이 구분할 수 있습니다.
- 이산형 변수: 셀수 있는 변수, 일정한 그룹에 속한 개체수 등과 같이 정수로 나타낼 수 있는 형태
- 연속형 변수: 셀수 없는 변수, 온도, 키, 몸무게 등과 같이 절대적인 기준에 대한 비율 형태
예 1.1)
다음 변수들의 측정수준을 결정해 봅니다.
- 나이: 이산형, 측정의 명확한 척도가 존재하며 나이 차이는 의미가 존재합니다.
- 정당이름: 명목형, 이 변수는 단지 분류를 위해 사용할 수 있습니다.
- 몸무게: 연속형, 일정한 값을 기준으로 그 값과의 비례 정도를 나타내는 것으로 간주할 수 있으며 값 자체에 대한 일정한 의미를 부여할 수 있습니다.
- 학생들을 세개의 그룹 A, B, C로 분류한 경우, 변수 '그룹': 명목형
- 게임 참가자 A, B, C가 각각 5, 2, 3단계에 참가하고 있는 경우, 변수 '단계': 순위형(ordinal). 이 변수의 경우 각 단계 내 또는 단계들 사이의 차이는 반드시 같지 않습니다.
- 영화에 대한 평가를 매우좋음, 좋음,... 등 5점 척도로 조사하였습니다. 이 조사 결과에 대한 변수의 수준: 순위형(ordianl). 이 조사에서 순위는 중요한 의미를 갖습니다. 그러나 그 구간 사이의 차이는 같지 않습니다.
- 도시 이름: 명목형, 도시에 이름을 부여 할 수 있으나 순위(ordinal)를 지정할 수 없습니다.
- 사람들의 은행 잔고: 연속형, 각 값들 사이의 차이는 동일하며, 값 자체가 의미를 가집니다.
테이블 구조
테이블 형식의 데이터는 일반적으로 다음과 같이 행과 열로 구성되어 있으며 각 행은 여러가지 속성(attribute)들에 대응하는 값들을 포함합니다.
key ↓ | feature ↓ | feature ↓ | feature ↓ | label ↓ | |
---|---|---|---|---|---|
사용자ID | 속성1 | 속성2 | 속성3 | 라벨 | |
1 | 6.5 | Male | 12 | 120 | ← 샘플(인스턴스)1 |
4 | 4.2 | Female | 17 | 270 | ← 샘플(인스턴스)2 |
7 | 5.7 | Male | 3 | 75 | ← 샘플(인스턴스)3 |
8 | 5.8 | Female | 8 | 60 | ← 샘플(인스턴스)4 |
- 테이블: 데이터 셋트
- key: 각 행의 ID로서 index가 됨
- 열: 변수가 되며 각 열의 값으로 다른 열을 추정하기 위한 설정의 경우 설명변수(feature, predictors)와 반응변수(label, target)로 구분
- 행: 변수들에 대한 관측값으로 1개의 행은 인스턴스(instance) 또는 샘플(sample)이 됨
위 테이블의 경우 속성1, 3, 그리고 라벨의 경우는 양적변수(quantitative variable)이고 속성 2는 목록변수(categorical variable)입니다. 일반적으로 통계분석과 기계학습에서 목록변수는 직접적으로 적용하기 어려운 점이 존재합니다. 그러므로 원-핫 코딩(one-hot encoding)등의 방법으로 양적변수로 전환할 필요가 있습니다.
기술통계량 찾기
데이터 셋의 기술 통계량을 보기 위해 numpy와 pandas의 여러 메서드 또는 함수를 적용할 수 있습니다. 그러기 위해서는 그 패키지에서 사용되는 자료형으로 전환할 필요가 있습니다. 다음은 위 데이터 셋트를 pandas의 DataFrame 형으로 나타내면 다음과 같습니다.
import numpy as np import pandas as pd x=pd.DataFrame([[1,6.5,'Male',12,120],[4,4.2,'Female',17,270],[7,5.7,'Male',3,75],[8,5.8,'Female',8,60]], columns=['사용자ID','속성1','속성2','속성3','라벨']) x
사용자ID | 속성1 | 속성2 | 속성3 | 라벨 | |
---|---|---|---|---|---|
0 | 1 | 6.5 | Male | 12 | 120 |
1 | 4 | 4.2 | Female | 17 | 270 |
2 | 7 | 5.7 | Male | 3 | 75 |
3 | 8 | 5.8 | Female | 8 | 60 |
위 객체의 평균 등의 기술 통계량을 계산하기 위해 pandas객체.describe()
메서드를 적용할 수 있습니다. 목록변수인 '속성2'의 기술통계량에 어떤 의미를 부여할 수 없으므로 이 열을 제외한 결과는 다음과 같습니다.
x1=x.iloc[:, [0, 1, 3, 4]] x1.describe()
사용자ID | 속성1 | 속성3 | 라벨 | |
---|---|---|---|---|
count | 4.000000 | 4.000000 | 4.000000 | 4.000000 |
mean | 5.000000 | 5.550000 | 10.000000 | 131.250000 |
std | 3.162278 | 0.967815 | 5.944185 | 95.949205 |
min | 1.000000 | 4.200000 | 3.000000 | 60.000000 |
25% | 3.250000 | 5.325000 | 6.750000 | 71.250000 |
50% | 5.500000 | 5.750000 | 10.000000 | 97.500000 |
75% | 7.250000 | 5.975000 | 13.250000 | 157.500000 |
max | 8.000000 | 6.500000 | 17.000000 | 270.000000 |
위 결과는 .count(), .max(), .min(), .mean(), std(), .quntile()
의 메서드로 계산할 수 있습니다. 이 메서드들은 매개변수로 axis를 가지며 그 인수를 조정하여 행 또는 열에 대해 각각을 계산할 수 있습니다. 위 객체 x의 행 단위로 통계량을 계산해 봅니다.
def DesStatistic(x, ax=1): cnt=x.count(axis=ax) mn=x.min(axis=ax) mx=x.max(axis=ax) mu=x.mean(axis=ax) sd=x.std(axis=ax) return(pd.DataFrame([cnt,mn, mx, mu,sd], index=['dount','min','max','mean','std'])) DesStatistic(x1)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
dount | 4.000000 | 4.00000 | 4.000000 | 4.000000 |
min | 1.000000 | 4.00000 | 3.000000 | 5.800000 |
max | 120.000000 | 270.00000 | 75.000000 | 60.000000 |
mean | 34.875000 | 73.80000 | 22.675000 | 20.450000 |
std | 56.927403 | 130.94131 | 34.923094 | 26.387055 |
x1.quantile([0, 0.25, 0.5, 0.75, 1], axis=1)
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0.00 | 1.000 | 4.00 | 3.000 | 5.80 |
0.25 | 5.125 | 4.15 | 5.025 | 7.45 |
0.50 | 9.250 | 10.60 | 6.350 | 8.00 |
0.75 | 39.000 | 80.25 | 24.000 | 21.00 |
1.00 | 120.000 | 270.00 | 75.000 | 60.00 |
위 결과는 객체 x1의 전치한 객체에 대한 .describe() 메서드를 적용한 것과 동일합니다.
(x1.T).describe()
0 | 1 | 2 | 3 | |
---|---|---|---|---|
count | 4.000000 | 4.00000 | 4.000000 | 4.000000 |
mean | 34.875000 | 73.80000 | 22.675000 | 20.450000 |
std | 56.927403 | 130.94131 | 34.923094 | 26.387055 |
min | 1.000000 | 4.00000 | 3.000000 | 5.800000 |
25% | 5.125000 | 4.15000 | 5.025000 | 7.450000 |
50% | 9.250000 | 10.60000 | 6.350000 | 8.000000 |
75% | 39.000000 | 80.25000 | 24.000000 | 21.000000 |
max | 120.000000 | 270.00000 | 75.000000 | 60.000000 |
목록변수의 인코딩(encoding)
문자열로 이루어진 목록변수는 분석을 위해서 컴퓨터가 연산할 수 있는 자료형태로 전환시켜야 합니다. 이 전환에 의한 변수는 결국 양적변수가 됩니다. 이 과정을 인코딩(encoding)이라하며 다양한 방법을 적용할 수 있습니다. 객체 x의 목록변수인 경우 두 그룹만이 존재하므로 라벨 인코딩(label encoding)을 적용할 수 있습니다. sklearn.preprocessing.LabelEncoder()
클래스를 적용할 수 있습니다.
from sklearn.preprocessing import LabelEncoder
x2=x.iloc[:,2] enc=LabelEncoder().fit(x2) enc.classes_
array(['Female', 'Male'], dtype=object)
attr2Enc=enc.transform(x2) attr2Enc
array([1, 0, 1, 0])
enc.inverse_transform(attr2Enc)
array(['Male', 'Female', 'Male', 'Female'], dtype=object)
위 목록변수를 원-핫 인코딩의 경우 pd.get_dummies() 함수 또는 sklearn.preprocessing.OneHotEncoder() 클래스를 사용할 수 있습니다. OneHotEncoder()의 경우 전달하는 인수는 2차원이어야 합니다.
pd.get_dummies(x2)
Female | Male | |
---|---|---|
0 | 0 | 1 |
1 | 1 | 0 |
2 | 0 | 1 |
3 | 1 | 0 |
from sklearn.preprocessing import OneHotEncoder
oneHot=OneHotEncoder().fit(pd.DataFrame(x2)) oneHot.categories_
[array(['Female', 'Male'], dtype=object)]
x2oh=oneHot.transform(pd.DataFrame(x2)).toarray() x2oh
array([[0., 1.], [1., 0.], [0., 1.], [1., 0.]])
oneHot.inverse_transform(x2oh)
array([['Male'], ['Female'], ['Male'], ['Female']], dtype=object)
비율
절대 비율과 상대 비율로 구분합니다.
- 절대 비율: 전체의 일부
- 상대 비율: 다른 비율에 비해 증가 또는 감소
한 도시에 범죄의 증가로 안전하지 않다는 소식의 근거는 증가율일 것입니다. 이 소식에 "살인율 50% 증가"의 정보가 추가된다면 악화된다는 소식의 근거를 주지만 여전히 불완전합니다. 그 불완전함은 사건 2건 에서 3건으로 증가 또는 10건에서 4건의 증가와 같이 비교되는 사건의 수에 대한 정보가 결핍되었기 때문입니다. 즉 50%의 증가는 과거의 사건의 수에 비한 증가에 대한 것입니다. 완전한 정보를 위해서는 이전의 수치가 필요합니다. 이 경우 50%는 상대비율로 이 소식의 완전한 이해를 위해서는 절대비율에 대한 정보가 필요합니다. 예를들어 100000명의 인구를 가진 도시에서 직전 년에 2건의 사건의 발생에 대비해 3건이 발생했다면 50%의 증가율을 보이지만 절대적으로 0.2%에서 0.3%의 증가로 그 부정적인 소식의 근거를 상당히 약하게 만들 것입니다. 이와 같이 상대비율과 절대비율의 의미는 매우 중요하며 상대비율만 보고하는 것은 지양되어야 합니다.
다음은 서울과 수도권의 인구밀도의 변화를 나타낸 것으로 위의 경우와는 다르게 상대비율에 의해 의해 명확한 경향을 나타내는 경우 입니다.
서울 | 수도권 | |||
---|---|---|---|---|
연도 | 인구밀도 | 상대빈도(%) | 인구밀도 | 상대빈도(%) |
2016 | 16263 | - | 25350 | - |
2017 | 16136 | -0.78 | 25476 | 0.50 |
2018 | 16034 | -0.63 | 25675 | 0.78 |
2019 | 15964 | -0.44 | 25844 | 0.66 |
댓글
댓글 쓰기