728x90
반응형

중심경향치(Center Tendency)


◎ 중심경향치: 관찰된 자료들이 어디에 집중되어 있는지를 나타낸다.


 통계학은 기본적으로 데이터가 어디에 모이고, 얼마나 흩어지는지를 통해서 데이터의 성격을 파악한다. 중심경향치는 데이터가 어디에 모이는지를 보는 것으로, 최빈값, 중앙값, 평균 등의 다양한 지표를 이용하여, 데이터가 모인 곳을 찾아낸다.

 그렇다면, 그 데이터가 모이고 흩어진다는 것이 대체 무슨 말일까? 이를 알기 위해, 이전 포스트에서 학습했던 내용을 바탕으로 이를 눈으로 확인해보자.

 

 

 

 

0. 데이터가 모이고 흩어진다는 것은 무엇일까?

  • 이전 포스트에서 사용했던 데이터를 가지고 오고, 모든 변수들을 히스토그램으로 시각화해보자.

Data_for_study.csv
3.39MB

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Rawdata = pd.read_csv("Data_for_study.csv")
plt.rc('font', family='NanumGothic')
Rawdata.hist(figsize=(16,25), layout=(5,3), grid=False,density=True)

plt.show()

  • 위 코드는 pandas와 matplotlib.pyplot 두 가지를 사용하여, DataFrame 내에 있는 변수들을 시각화해주며, 히스토그램은 그 변수가 무엇이든 간에, 그 변수의 빈도를 이용해 그래프를 그린다. 또한, bins 파라미터를 통해, 키, 몸무게 같은 비율 척도는 실제 형태보다 단순화시켜, 모든 변수들의 추이를 쉽게 파악할 수 있다.
  • 위 히스토그램들을 보면, "주중_인터넷이용시간"은 주로 0 ~ 100 사이에 가장 많은 데이터가 모여 있으며, 흩어진 정도는 그리 크지 않다는 것을 알 수 있다.
  • 이러한 변수별 데이터가 어디에 모여있는지를 하나의 값으로 확인할 수 있는 방법이 바로 중심경향치다.

 

 

 

 

1. 최빈값(Mode)


◎ 최빈값(Mode): 빈도수가 가장 큰 관찰값


  • 도수분포표에서 가장 값이 많이 모여 있는 관찰 값을 의미한다.
  • 양적 자료, 질적 자료에서 모두 사용되나, 일반적으로 질적 자료에서 더 자주 사용된다.
  • 위에서 불러온 데이터에서 명목변수: "흡연경험", 등간변수(리커트 5점 척도): "스트레스인지", 비율 변수: "몸무게"에 대하여 최빈값을 구해보자.

 

1.1. 도수분포표를 사용하여 최빈값 구하기

  • 최빈값을 구하는 방법은 도수분포표를 구하고, 가장 빈도수가 높은 관찰 값을 선택하는 방법이 있다.
  • 연속형 변수를 구간 화하는 것은 꽤 귀찮은 일이므로, 20개 이상의 관찰 값을 갖는 경우, 10개의 구간을 갖는 변수로 변환하여 도수분포표를 출력하는 함수를 만들었다.
def make_freq_table(data, column):
    """
    -------------------------------------------------------------------------------
    지정된 변수의 관찰값이 20개보다 많은 경우, 10개의 등급을 가진 데이터를 반환한다.
    -------------------------------------------------------------------------------
    Input: DataFrame, str
    Output: DataFrame
    """
    # array 생성
    target_array = data[column].to_numpy()

    # class의 수가 20개보다 많은 경우 10개로 줄인다.
    class_array = np.unique(target_array)

    if len(class_array) > 20:

        min_key = class_array.min()
        max_key = class_array.max()
        split_key = np.linspace(min_key, max_key, 10)

        a0 = str(round(split_key[0], 2)) + " 이하"
        a1 = str(round(split_key[0], 2)) + " ~ " + str(round(split_key[1], 2))
        a2 = str(round(split_key[1], 2)) + " ~ " + str(round(split_key[2], 2))
        a3 = str(round(split_key[2], 2)) + " ~ " + str(round(split_key[3], 2))
        a4 = str(round(split_key[3], 2)) + " ~ " + str(round(split_key[4], 2))
        a5 = str(round(split_key[4], 2)) + " ~ " + str(round(split_key[5], 2))
        a6 = str(round(split_key[5], 2)) + " ~ " + str(round(split_key[6], 2))
        a7 = str(round(split_key[6], 2)) + " ~ " + str(round(split_key[7], 2))
        a8 = str(round(split_key[7], 2)) + " ~ " + str(round(split_key[8], 2))
        a9 = str(round(split_key[8], 2)) + " 이상"
        new_index = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]


        target_array= np.where(target_array <= split_key[0], 0,
                               np.where((target_array > split_key[0]) & (target_array <= split_key[1]), 1,
                                        np.where((target_array > split_key[1]) & (target_array <= split_key[2]), 2,
                                                 np.where((target_array > split_key[2]) & (target_array <= split_key[3]), 3,
                                                          np.where((target_array > split_key[3]) & (target_array <= split_key[4]), 4,
                                                                   np.where((target_array > split_key[4]) & (target_array <= split_key[5]), 5,
                                                                            np.where((target_array > split_key[5]) & (target_array <= split_key[6]), 6,
                                                                                     np.where((target_array > split_key[6]) & (target_array <= split_key[7]), 7,
                                                                                              np.where((target_array > split_key[7]) & (target_array <= split_key[8]), 8, 9)))))))))


    # 도수분포표 생성
    freq_table = pd.DataFrame(pd.Series(target_array).value_counts(), columns = ["freq"])
    freq_table.index.name = column

    freq_table.sort_index(inplace = True)
    freq_table["ratio"] = freq_table.freq / sum(freq_table.freq)
    freq_table["cum_freq"] = np.cumsum(freq_table.freq)
    freq_table["cum_ratio"] = np.round(np.cumsum(freq_table.ratio), 2)
    freq_table["ratio"] = np.round(freq_table["ratio"], 2)

    if "new_index" in locals():
        freq_table.index = new_index
        freq_table.index.name = column

    return freq_table
  • np.linspace(start, end, num): start부터 end까지 num개를 일정한 간격으로 자르는 함수로, 아주 간편하게, 연속형 데이터를 범주화할 수 있다.
  • 흡연경험의 도수분포표
make_freq_table(Rawdata, "흡연경험")

  • 명목 변수인 흡연경험의 최빈값은 1.0인 것을 알 수 있다. 청소년건강행태조사 이용지침서 참고 시, "없다"가 88%로 가장 많이 등장하였다.
make_freq_table(Rawdata, "스트레스인지")

  • 등간 변수(리커트 척도)인 스트레스인지의 최빈값은 3.0인 것을 알 수 있다. 청소년건강행태조사 이용지침서 참고 시, "조금 느낀다"가 가장 많이 등장하였다.
make_freq_table(Rawdata, "몸무게")

  • 비율 변수인 몸무게에서 제일 많이 등장한 등급(Class)는 45.87 ~ 56.3 kg인 것을 알 수 있다. 표본집단인 중·고등학생 중 36%가 해당 구간에 존재한다.

 

1.2. 파이썬을 이용하여 최빈값 구하기

  • 도수분포표를 일일이 구하고, 최빈값을 구하는 일은 꽤 번거로운 일이다.
  • 데이터 분석에서 기본적으로 사용되는 라이브러리 중 하나인 pandas는 다양한 기본 함수를 제공하여, 이러한 문제를 쉽게 해결할 수 있게 해 준다.
  • Series.mode(): 최빈값을 출력한다.
>>> 흡연경험_최빈값 = Rawdata.흡연경험.mode()
>>> 흡연경험_최빈값
0    1.0
dtype: float64


>>> 스트레스인지_최빈값 = Rawdata.스트레스인지.mode()
>>> 스트레스인지_최빈값
0    3.0
dtype: float64


>>> 몸무게_최빈값 = Rawdata.몸무게.mode()
>>> 몸무게_최빈값
0    60.0
dtype: float64
  • Series.mode()는 Series로 결과를 출력한다.
  • 양적 변수라 할지라도, 바로 최빈값을 찾는 경우, 굳이 도수분포표를 만드는 수고를 할 필요가 없으므로, 구간을 만드는 수고를 하지 않아도 된다.
  • 이번에는, 최빈값에 해당하는 빈도수를 출력해보자.
# 최빈값과 최빈값 도수 출력
def mode_value_printer(data, column):
    
    mode_ = data[column].mode().values[0]
    freq =len(data[data[column] == mode_])
    
    print(f"{column} - 최빈값: {mode_}, 도수: {freq}")
>>> mode_value_printer(Rawdata, "흡연경험")
흡연경험 - 최빈값: 1.0, 도수: 48995

>>> mode_value_printer(Rawdata, "스트레스인지")
스트레스인지 - 최빈값: 3.0, 도수: 22915

>>> mode_value_printer(Rawdata, "몸무게")
몸무게 - 최빈값: 60.0, 도수: 2350
  • 보시다시피 pandas 기본 함수를 사용하면, 아주 쉽게 최빈값과 그에 해당하는 도수를 찾을 수 있다.
  • 그러나, 양적 변수, 그중에서도 관찰 값이 매우 많은 변수는 범주화를 시키는 것과, 단순하게 가장 많이 등장한 관찰 값을 찾는 것이 다른 결과를 가져온다.
  • 때문에 양적 변수에서는 중심경향치를 확인하고자 할 때, 최빈값보다는 평균, 중위수와 같은 다른 값을 추출하는 경우가 더 많다(물론, 연구자의 의도에 따라 최빈값 역시 필요할 수 있으므로, 절대 양적 변수에 최빈값을 사용하지는 않는다고 생각해선 안된다).

 

 

 

 

2. 중앙값(Median)


◎ 중앙값(Median): 수치로 된 자료를 크기 순서대로 나열할 때, 가장 가운데에 위치하는 관찰값을 말한다.

$$Md = \frac{(n+1)}{2}$$


  • 중앙값은 순서, 일정한 간격을 가지고 있는 양적 변수에 대해서만 사용 가능하며, 말 그대로 한 변수 내 모든 관찰값들의 중앙에 있는 값을 가리킨다.
  • 중앙값에서 이슈라고 할 수 있는 것은 관찰값의 수가 짝수인지 홀수인지로, 아래 예시를 보자.

$$ A = {1, 3, 4, 7, 8, 10, 11, 15, 16}$$

  • 위 예시 같이 집합 내 원소의 수가 홀수인 경우에는 그냥 $\frac{9+1}{2}=5$에 있는 관찰값을 중앙값으로 하면 되지만, 짝수인 경우는 조금 다르다.

$$ B = {2, 4, 6, 7, 9, 10} $$

  • 위 예시 같이 집합 내 원소의 수가 짝수인 경우에는 $\frac{6+1}{2} = 3.5$가 되어, 3.5번째에 있는 관찰값을 중앙값으로 사용해야 하나, 3.5번째 관찰값은 존재할 수 없다.
  • 이 때는, 3번째 관찰값인 6과 4번째 관찰값인 7의 평균을 중앙값으로 사용한다. 즉, $\frac{6+7}{2} = 6.5$가 중앙값이 된다.

 

2.1. 도수분포표를 이용하여 연속형 데이터의 중앙값 구하기

  • 중앙값은 관찰값들의 중앙에 있는 값이므로, 도수분포표를 사용하지 않고 구할 수 있고, 그것이 정석이다.
  • 그러나, 항상 모든 관찰값들을 알 수 있는 것이 아니고, 때에 따라서는 도수분포표를 사용해서 중앙값을 유추해야할 필요도 있다.
    (물론, 원시자료를 손 델 수 있다면, 굳이 그럴 필요는 없지만!)
  • 이번에는 범주화된 연속형 데이터의 도수분포표를 이용해서 중앙값을 구해보자.
  • 위에서 만든 make_freq_table함수를 이용해서 키에 대한 도수분포표를 만들어보자.
make_freq_table(Rawdata, "키")

  • 총데이터의 양은 55748개이며, 55748의 중앙값은 $\frac{55748+1}{2} = 27874.5$이다. 즉, 27,874.5번째에 있는 값이 있는 구간이 중앙값이다.
  • 누적빈도를 볼 때, 27,874.5는 162.67 ~ 169.33 구간에 존재하므로, 중앙값이 있는 구간은 162.67 ~ 169.33임을 알 수 있다.
  • 이 구간 안에서 비율을 사용해서 중앙값을 유추해보자

  • 위 방법처럼 관찰 값의 비율과 빈도의 비율을 이용하면, 중위수를 유추해낼 수 있다.
  • 실제 중위수랑 비교해보자.
>>> Rawdata.키.median()
165.0
  • 실제 중위수와 도수분포표를 사용해서 유추한 중위수가 상당히 유사한 것을 알 수 있다.

 

2.2. 파이썬을 이용하여 중위수 구하기

  • 파이썬을 이용해 중위수를 구하는 것은 정말 단순하다.
>>> Rawdata.스트레스인지.median()
3.0

>>> Rawdata.몸무게.median()
57.0
  • Series.median()을 사용하면, 중위수를 구할 수 있다.
  • numpy 함수를 사용하는 경우는 다음과 같다.
>>> np.median(Rawdata.스트레스인지.to_numpy())
3.0

>>> np.median(Rawdata.몸무게.to_numpy())
57.0
  • np.median(array)를 사용해서 중위수를 구하면 된다.

 

 

 

 지금까지 최빈값과 중앙값을 구해보았다. 다음 포스트에서는 가장 대표적인 중심경향치인 평균에 대해 자세히 알아보도록 하겠다.

728x90
반응형
728x90
반응형

도수분포표와 시각화

 앞서 도수분포표에서 봤듯, 도수분포표는 수집한 데이터의 분포를 알기 위해 사용한다. 그러나 여전히 숫자만으로 데이터를 파악하기 때문에 데이터의 분포를 명확하게 이해하기 어려울 수도 있다. 도수분포표를 시각화한다면, 보다 쉽게 데이터의 분포를 파악할 수 있다.

  • 도수분포표의 시각화이므로, 들어간 데이터의 도수(빈도)를 시각화 하는 것이다.
  • 파이썬으로 도수분포표를 시각화하는 방법은 크게 두가지가 있다.
  1. 범주화된 데이터를 사용해서 히스토그램을 만들기
  2. 도수분포표 생성 후, 도수분포표를 기반으로 그래프 그리기
  • 개인적으로 추천하는 방법은 도수분포표를 먼저 생성하고, 그래프를 그리는 것으로, 도수분포표 연산이 한 번 이루어지고 나면, 나머지 과정은 자원을 거의 먹지 않는다.
  • 도수분포표만 만들면, 이를 이용해서 히스토그램(막대그래프 사용), 도수분포다각형, 누적도수분포곡선 3가지를 모두 쉽게 그릴 수 있다.

 

 

 

 

1. 히스토그램

  • 히스토그램은 가장 대표적인 도수분포표의 시각화 방법이다.
  • 위에서 설명한 파이썬으로 도수분포표 시각화를 하는 첫 번째 방법으로, 원본 데이터(범주화가 된)를 사용해서 히스토그램을 그리는 것이다.
  • 히스토그램은 막대그래프로 한 변수를 구성하는 각 집단의 빈도를 이용하여, 막대 그래프를 그리는 것이다.
  • 이전 데이터에서 사용했던, 청소년건강행태조사 2019년 데이터에서 일부 변수만 추려낸 데이터를 사용해보자.

Data_for_study.csv
3.39MB

  • "건강인지"를 히스토그램으로 나타내보자.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Rawdata = pd.read_csv("Data_for_study.csv")
# 한글 사용
plt.rc('font', family='NanumGothic')

# 전체 그래프 크기
fig = plt.figure(figsize=(8, 6))

# 히스토그래프 그리기
plt.hist(Rawdata.건강인지.to_numpy(), bins=9)

# x축 ticks 지정
plt.xticks(np.arange(1, 6), labels=["매우 좋음", "좋음", "보통", "나쁨", "매우 나쁨"])
plt.tick_params(axis="x", direction="in", labelsize = 12, pad = 20)

# title, xlabel, ylabel 지정
plt.title("건강인지 히스토그램", fontsize = 30, pad = 30)
plt.xlabel('건강인지', fontsize = 20, loc = 'center', labelpad = 20)
plt.ylabel('도수', fontsize = 20, rotation = 0, loc='center', labelpad = 30)

plt.show()

  • plt.hist(density=True)로 지정해주면, 빈도가 아닌, 비율로 나타낼 수도 있다.
  • 그러나, 이 비율은 히스토그램 전체를 1로 하는 비율이 아닌, 최대 빈도를 1로 하는 비율이다.
fig = plt.figure(figsize=(8, 6))

plt.hist(Rawdata.건강인지.to_numpy(), bins=9, density=True)
plt.xticks(np.arange(1, 6), labels=["매우 좋음", "좋음", "보통", "나쁨", "매우 나쁨"])
plt.tick_params(axis="x", direction="in", labelsize = 12, pad = 20)

plt.title("건강인지 히스토그램", fontsize = 30, pad = 30)

plt.xlabel('건강인지', fontsize = 20, loc = 'center', labelpad = 20)
plt.ylabel('도수', fontsize = 20, rotation = 0, loc='center', labelpad = 30)


plt.show()

  • 입력된 데이터는 숫자지만, 실제로는 문자인 Factor이므로, label을 문자로 입력하였다.
>>> Rawdata.건강인지.to_numpy()
array([1., 1., 2., ..., 4., 3., 3.])
  • 실제 정의에 맞게 하려면, 다음과 같이 숫자를 원래 형태인 문자로 바꿔주고, 문자 배열에 대한 도수를 히스토그램으로 그려야 한다.
건강인지 = Rawdata.건강인지.to_numpy()
건강인지 = np.where(건강인지==1, "매우 좋음",
                np.where(건강인지==2, "좋음",
                         np.where(건강인지==3, "보통",
                                  np.where(건강인지==4, "나쁨", "매우 나쁨"))))

 

 

 

 

2. 도수분포다각형

  • 도수분포다각형은 히스토그램의 각 중간점을 이어서 그린 것으로, 데이터가 연속적인 경우에 사용한다.
  • 도수분포다각형을 사용하면, 분포의 윤곽이 보다 명확하게 보이며, 빈도의 증감을 보다 명확히 볼 수 있다.
  • 또한, 서로 다른 집단에 대한 도수분포를 같은 그림 위에서 비교할 수 있다는 장점이 있다.
  • 도수분포다각형, 누적도수분포곡선은 도수분포표를 기반으로 그리는 것이 훨씬 쉽다(히스토그램 역시, 이미 생성된 도수분포표를 기반으로 막대그래프로 그리는 것이 추가 연산 시간이 없으므로 쉽다).
  • 이전 포스트에서 만들었던, 16세 남성의 키와 16세 여성의 키를 10cm 간격으로 범주화한 도수분포표를 대상으로 해서 만들어보도록 하자.
  • 총합은 도수분포표를 이해하기 좋게 만든 것이므로, 제거하고, 필요한 각 클래스별 값만 유지하겠다.
def cat_height(array):
    cat_array = np.where(array<=140, "140 이하",
                     np.where((array>140) & (array<=150), "140~150",
                              np.where((array>150) & (array<=160), "150~160",
                                       np.where((array>160) & (array<=170), "160~170",
                                                np.where((array>170) & (array<=180), "170~180",
                                                         np.where((array>180) & (array<=190), "180~190", "190 이상"))))))
    return cat_array
    
    
def Freq_table(array):

    freq_table = pd.DataFrame(pd.Series(array).value_counts(), columns=["freq"])
    freq_table.sort_index(inplace = True)
    freq_table["ratio"] = freq_table.freq / sum(freq_table.freq)
    freq_table["cum_freq"] = np.cumsum(freq_table.freq)
    freq_table["cum_ratio"] = np.round(np.cumsum(freq_table.ratio), 2)
    freq_table["ratio"] = np.round(freq_table["ratio"], 2)

    return freq_table
    
남자_16세_키 = Rawdata[(Rawdata["연령"] == 16) & (Rawdata["성별"] == 1.0)]["키"].to_numpy()
여자_16세_키 = Rawdata[(Rawdata["연령"] == 16) & (Rawdata["성별"] == 2.0)]["키"].to_numpy()

M_DF = Freq_table(cat_height(남자_16세_키))
F_DF = Freq_table(cat_height(여자_16세_키))
fig = plt.figure(figsize=(8, 6))

plt.plot(F_DF.index, F_DF.ratio, label = "Female, 16 years old")
plt.plot(M_DF.index, M_DF.ratio, linestyle = "--", label = "Male, 16 years old")

plt.title("16세 남성 & 여성 키 도수분포다각형",fontsize = 20, pad = 20)
plt.xlabel("키", fontsize = 15)
plt.ylabel("비율", fontsize = 15, rotation = 0, labelpad = 30)
plt.legend(loc="upper right")

plt.show()

  • 생성된 두 집단의 도수분포표를 상대적으로 비교하기 위해, 상대 빈도인 비율을 사용하여 그래프를 그렸다.
  • 도수분포다각형이 히스토그램의 꼭짓점을 연결한 것임을 보기 위해 히스토그램도 뒤에 연하게 그려보자.
fig = plt.figure(figsize=(8, 6))


plt.plot(F_DF.index, F_DF.ratio, label = "Female, 16 years old")
plt.plot(M_DF.index, M_DF.ratio, linestyle = "--", label = "Male, 16 years old")

plt.bar(F_DF.index, F_DF.ratio, alpha = 0.4, color = "blue")
plt.bar(M_DF.index, M_DF.ratio, alpha = 0.4, color = "yellow")

plt.title("16세 남성 & 여성 키 도수분포다각형",fontsize = 20, pad = 20)
plt.xlabel("키", fontsize = 15)
plt.ylabel("비율", fontsize = 15, rotation = 0, labelpad = 30)
plt.legend(loc="upper right")

plt.show()

  • 동일한 비율을 사용하기 위해 plt에서 histogram 함수가 아닌 막대그래프인 bar를 가지고 왔다.
  • 히스토그램과 막대그래프는 본질이 다르지만, 도수분포표를 사용해서 그린다면 히스토그램과 막대그래프는 동일한 결과를 가지고 온다.
    (히스토그램은 데이터가 한 차원만 들어가고, 그 빈도로 그래프를 그린다. 막대그래프는 두 차원의 데이터가 필요하며, 그 두 차원의 데이터를 이용해서 그래프를 그린다)
  • 가지고 있는 전체 데이터를 이용해서 그래프를 그린다면 히스토그램을 사용하고, 이미 도수분포표를 만들었다면, 막대그래프를 그리길 추천한다.

 

 

 

 

3. 누적도수분포곡선

  • 누적도수분포곡선은 위에서 도수분포다각형을 그렸던 방법에서, y축에 들어가는 데이터만 누적 도수로 바꾸면 된다.
  • 이번에도 두 집단을 비교하기 쉽도록, 비율로 구해보도록 하겠다.
fig = plt.figure(figsize=(8, 6))


plt.plot(F_DF.index, F_DF.cum_ratio, label = "Female, 16 years old")
plt.plot(M_DF.index, M_DF.cum_ratio, linestyle = "--", label = "Male, 16 years old")

plt.bar(F_DF.index, F_DF.cum_ratio, alpha = 0.4, color = "blue")
plt.bar(M_DF.index, M_DF.cum_ratio, alpha = 0.4, color = "yellow")

plt.title("16세 남성 & 여성 키 누적도수분포곡선",fontsize = 20, pad = 20)
plt.xlabel("키", fontsize = 15)
plt.ylabel("비율", fontsize = 15, rotation = 0, labelpad = 30)
plt.legend(loc="lower right")

plt.show()

 

 

 

 지금까지 파이썬을 사용해서 도수분포표의 시각화를 해보았다. 개인적으로는 도수분포표를 먼저 구하고, 그 도수분포표를 바탕으로 시각화를 진행하길 바란다.

728x90
반응형
728x90
반응형

도수분포표(Frequency Distribution Table)


◎ 도수분포표: 수집된 데이터를 분류한 후, 각 분류에 해당하는 데이터의 빈도, 비율 등으로 정리한 표를 말한다.


 앞서 통계학은 크게 기술통계학(Descriptive statistics)과 추론통계학(Inferential statistics) 이 두 가지로 나뉘며, 이 둘은 별개의 존재가 아니라, 기술통계학 > 추론통계학순으로 순차적으로 이루어진다고 하였다.

 기술통계학은 말 그대로 데이터가 가지고 있는 정보를 기술(Describe)하는 것이며, 도수분포표는 데이터의 각 범주별 빈도수와 비율을 이용하여, 데이터를 설명하는 방법으로 기술통계학의 기초가 되는 기법이다.

 백 마디 말보다, 한 번 실제 만들어보는 것이 가장 좋은 방법이니, 실제로 도수분포표를 만들어보고, 도수분포표가 어떻게 생겼고, 도수분포표를 이용해서 무엇을 할 수 있기에 기술통계학의 기초가 되는 것인지 알아보도록 하자.

  • 도수분포표를 학습할 때, 집단을 잘 구분하는 것이 중요하다.
  • 한 변수 안에는 $m$개의 데이터가 존재하는데, 이 $m$개의 데이터를 중복을 제거하면 $n$개의 데이터가 남게 된다($m$ ≥ $n$).
  • 이 중복이 없는 $n$의 데이터는 한 원소 안의 집단(Group), 등급(Class) 두 가지 용어로 부를 수 있는데, 본 포스트에서는 이해하기 쉽도록, 선택된 군은 집단(Group)으로, 한 변수 안의 중복이 제거된 데이터의 군은 등급(Class)라 부르겠다.

 

 

 

 

1. Python을 사용하여, 기본적인 도수분포표를 만들어보자.

1.1. 데이터 가지고 오기

 이전 포스트(참고: "통계 분석을 위한 데이터 준비")에서 생성한 데이터를 기반으로 통계 분석을 진행하도록 하겠다. 해당 데이터는 청소년건강행태조사 2019년 데이터에서 대표적인 16개 변수만 선택하고, 간단하게 결측값을 처리한 데이터다. 보다 상세한 설명이 필요한 경우 위 참고를 보길 바란다.

Data_for_study.csv
3.69MB

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
  • 데이터 분석을 할 때, 기본적으로 사용하는 라이브러리다.
  • pandas는 DataFrame을 이용해, 데이터를 관리하는 모든 과정을 굉장히 편하게 해 준다.
  • numpy는 빠른 수학 연산에 필수인 라이브러리다.
  • matplotlib.pyplot은 시각화에 필수인 라이브러리다.
Rawdata = pd.read_csv("Data_for_study.csv")
Rawdata
  • pd.read_csv("파일이름.csv"): csv 파일을 DataFrame으로 불러온다.

  • 변수(Column)의 수는 총 14개이며, 55,748개의 대상이 들어가 있는 데이터가 불러와졌다.

 

1.2. 질적 변수 도수분포표 만들기

  • 출력된 위 데이터만으로 데이터가 어떻게 생겼고, 그 안에 숨어있는 정보를 찾아내는 것은 불가능에 가깝다.
  • 위 데이터를 가장 쉽게 정리하는 방법이 바로 도수분포표(Frequency distribution table)이다.
  • 성별에 대한 도수분포표를 만들어보겠다.
>>> Rawdata.성별.value_counts()
1.0    29059
2.0    26689
Name: 성별, dtype: int64
  • value_counts(): 시리즈로 빈도표를 출력한다
  • 1은 남자, 2는 여자이므로, 총 55,748명 중 남자가 29,059명, 여자가 26,689명임을 알 수 있다.
  • 비율을 추가해보자.
성별_빈도표 = pd.DataFrame(Rawdata.성별.value_counts())
성별_빈도표.columns = ["freq"]
성별_빈도표["ratio"] = np.round(성별_빈도표.freq/sum(성별_빈도표.freq),2)
성별_빈도표
  • pd.DataFrame.columns: DataFrame의 컬럼명을 조작한다.
  • np.round(array, n): array의 값들을 n의 자리에서 반올림한다.

  • 대한민국의 중, 고등학생을 모집단으로 하는 데이터의 표본집단에서 남성이 차지하는 비중은 52%, 여성이 차지하는 비중은 48% 임을 쉽게 알 수 있다.

 

1.3. 양적 변수 도수분포표 만들기

  • 이번엔 동일한 방법으로 양적 변수인 키에 대해 도수분포표를 만들어보겠다.
키_빈도표 = pd.DataFrame(Rawdata.키.value_counts())
키_빈도표.columns = ["freq"]
키_빈도표["ratio"] = np.round(키_빈도표.freq/sum(키_빈도표.freq),2)
키_빈도표

  • 데이터를 보기 쉽게 만드려고 했는데, 여전히 보기가 어렵다.
  • 키와 같은 양적 변수는 들어갈 수 있는 값이 매우 다양하여 등급(Class)이 많기 때문에 이를 바로 도수분포표로 만들면, 여전히 보기 어렵다. 이를 범주화(Categorization)시켜 단순화해보자.
>>> 키_array = Rawdata.키.to_numpy()
>>> print("min:", 키_array.min())
>>> print("max:", 키_array.max())
min: 136.0
max: 196.0
  • DataFrame.column.to_numpy(): DataFrame의 특정 열 column을 numpy의 array로 변환시킨다.
  • array.min(): 배열의 최솟값
  • array.max(): 배열의 최댓값
  • 최솟값이 136.0cm, 최댓값이 196.0cm이므로, "140 이하", "140~150", "150~160", "160~170", "170~180", "180~190", "190 이상"으로 데이터를 범주화해보자.
키_범주 = np.where(키_array<=140, "140 이하",
                np.where((키_array>140) & (키_array<=150), "140~150",
                         np.where((키_array>150) & (키_array<=160), "150~160",
                                  np.where((키_array>160) & (키_array<=170), "160~170",
                                           np.where((키_array>170) & (키_array<=180), "170~180",
                                                    np.where((키_array>180) & (키_array<=190), "180~190", "190 이상"))))))
                                                    
키_도수분포표 = pd.DataFrame(pd.Series(키_범주).value_counts(), columns=["freq"])
키_도수분포표.sort_index(inplace=True)
키_도수분포표
  • np.where(조건, a, b): 조건에 해당하는 경우 a로 해당하지 않는 경우 b를 반환
  • DataFrame.sort_index(): index로 정렬함.

  • 비율을 추가해보자.
키_도수분포표["ratio"] = np.round(키_도수분포표.freq / sum(키_도수분포표.freq), 2)
키_도수분포표

 

1.4. 누적 빈도, 누적 비율 추가

  • 이번에는 빈도(freq)와 비율(ratio)을 첫 집단부터 차근차근 누적시키는 누적 빈도(Cumulative frequency)와 누적 비율(Cumulative ratio)을 보자.
키_도수분포표["cum_freq"] = np.cumsum(키_도수분포표.freq)
키_도수분포표["cum_ratio"] = np.cumsum(키_도수분포표.ratio)
키_도수분포표

  • np.cumsum(array): array를 주어진 순서대로 누적합

 

 

 

 

2. 도수분포표의 개념 정리

 위에서 만든 도수분포표를 기반으로, 도수분포표의 개념을 정리해 보자.

  • 질적 변수는 일반적으로 구성하고 있는 등급(Class)의 수가 그리 많지 않기 때문에 바로 도수분포표를 생성해도 가시성이 높다. 물론, 질적 변수 역시 구성하고 있는 등급(Class)의 수가 매우 많다면, 재 범주화하여, 그 등급(Class)의 수를 줄여야한다.
    예) 읍, 면, 동 단위로 지역명이 들어가 있는 변수는, 이를 시 단위로 재범주화 할 수 있음
  • 양적 변수로 구성된 데이터는 중복을 제거하더라도, 구성하고 있는 등급(Class)가 매우 많아 도수분포표로 만들더라도, 가시성이 매우 떨어지므로, 변수의 성격에 따라 그 변수의 데이터 분포를 가장 잘 보여줄 수 있는 구간으로 데이터를 범주화시켜 도수분포표를 만든다.

 

  • 각 등급(Class)에서 관찰된 객체의 수를 빈도수 또는 도수(Frequency)라고 하며, $f$로 나타낸다.
  • 각 변수를 구성하는 데이터의 빈도, 비율 등을 파악하기 때문에 이 과정을 빈도 분석(Frequency Analysis)라 하며, 출력된 도수분포표를 빈도표라고도 한다.
  • 빈도 분석을 통해 생성하는 도수분포표 자체도 통계 분석에서 목적이 될 정도로 중요하지만, 일반적으로는 데이터의 형태를 파악하는 기초 자료로 생성하는 경우가 많다.

 

  • 누적 빈도(Cumulative frequency):
    어떤 등급(Class)에 해당하는 빈도를 포함해, 그 이하 또는 그 이상에 있는 모든 빈도를 합친 것
  • 누적 빈도를 사용하게 되면, 특정 등급(Class)에 있는 대상이 전체 데이터에서 차지하는 위치를 알 수 있다. 위 도수분포표를 보면, 중·고등학생 전체 집단에서 키가 170~180에 있는 집단이 전체 대상에서 96%에 위치하고 있음을 알 수 있다.
  • 누적 빈도는 질적 변수에 대해서는 사용하지 않는 것을 추천한다. 양적 변수는 데이터에 순서가 있고, 값과 값 사이의 간격이 일정하므로, 누적 빈도를 통해 대상 등급(Class)의 객관적인 위치를 알 수 있다. 그러나, 명목 변수는 순서가 없고, 순서가 존재하는 서열 변수라 할지라도, 간격이 일정하지 않기 때문에, 대상 등급(Class)이 전체 등급의 어디에 위치하는지 알 수 없다.

 

 

 

 

3. 상대 빈도(Relative frequency) = 비율(Ratio)

  • 위에서 생성한 키에 대한 도수분포표는 표본 집단인 중·고등학교에 재학 중인 청소년을 대상으로 한 것이다.
>>> print("만연령 min:", Rawdata.연령.min())
>>> print("만연령 max:", Rawdata.연령.max())
만연령 min: 12.0
만연령 max: 18.0
  • 대상 집단의 연령 범위는 만 12세~18세이며, 성별이 남, 녀 두 가지가 들어 있기 때문에 단순하게 위 도수분포표를 보고, 해당 집단의 특성을 파악한다면 아래와 같은 정보 전달의 오류가 발생할 위험이 있다.
  • 키 170cm는 12세 여성이란 집단에서는 굉장히 큰 키이지만, 18세 남성이란 집단에서는 그리 큰 키가 아니다. 위 도수분포표는 만 12세 ~ 18세 중·고등학생 표본집단을 대상으로 하였기 때문에 위 도수분포표만으로는 둘을 같게 볼 여지가 있다.
    (물론, 대상을 만 12~18세라고 미리 설명해놨다면, 이런 문제는 발생하지 않는다.)
  • 보다 정밀한 데이터 파악을 위해선, 연구자의 의도를 가장 잘 보여줄 수 있는 도수분포표(빈도표) 생성이 필요하다.
  • 이번에는 만 16세인 사람으로 한정하여, 남성과 여성의 키를 보도록 하자.
def cat_height(array):
    cat_array = np.where(array<=140, "140 이하",
                     np.where((array>140) & (array<=150), "140~150",
                              np.where((array>150) & (array<=160), "150~160",
                                       np.where((array>160) & (array<=170), "160~170",
                                                np.where((array>170) & (array<=180), "170~180",
                                                         np.where((array>180) & (array<=190), "180~190", "190 이상"))))))
    return cat_array
    
    
def Freq_table(array):

    freq_table = pd.DataFrame(pd.Series(array).value_counts(), columns=["freq"])
    freq_table.sort_index(inplace = True)
    freq_table["ratio"] = freq_table.freq / sum(freq_table.freq)
    freq_table["cum_freq"] = np.cumsum(freq_table.freq)
    freq_table["cum_ratio"] = np.round(np.cumsum(freq_table.ratio), 2)

    # 반올림 및 총합 생성
    freq_table.loc["총합"] = [sum(freq_table.freq), sum(freq_table.ratio), "", ""]
    freq_table["ratio"] = np.round(freq_table["ratio"], 2)

    return freq_table
  • 위에서 만들었던, 양적 변수의 범주화(키)와 도수분포표를 출력하는 코드들을 정리하여 별 개의 함수로 만들어놓았으며, 추가로 총합이 계산되도록 코드를 추가하였다.
  • 이러한 코드 함수화를 통해, 코드의 재활용성, 가시성, 유지보수의 용이함 등의 이점을 얻을 수 있다.
남자_16세_키 = Rawdata[(Rawdata["연령"] == 16) & (Rawdata["성별"] == 1.0)]["키"].to_numpy()
여자_16세_키 = Rawdata[(Rawdata["연령"] == 16) & (Rawdata["성별"] == 2.0)]["키"].to_numpy()
Freq_table(cat_height(남자_16세_키))

Freq_table(cat_height(여자_16세_키))

  • 상대 빈도(relative frequency)는 비율(ratio)과 동일하다.
  • 상대 빈도 즉, 비율을 사용하면, 서로 다른 집단에 대하여, 각 범주별 차지하는 비중을 알 수 있게 되므로, 서로 다른 집단을 비교하는데 매우 유용하다.
  • 위 표를 하나로 합쳐보자.
# 성별에 따른 변수명 구분을 위해 column 앞에 특정 문자를 붙여줌
M_DF = Freq_table(cat_height(남자_16세_키))
M_DF = M_DF.add_prefix("M_")
F_DF = Freq_table(cat_height(여자_16세_키))
F_DF = F_DF.add_prefix("F_")

# 병합 및, 결측값은 0으로 채운다.
T_DF = pd.concat([M_DF, F_DF], axis=1).sort_index()
T_DF.fillna(0, inplace=True)

T_DF

  • 위 표를 보면, 남성(M)과 여성(F)의 도수분포표를 비율(ratio)을 이용해서, 두 집단의 규모 차이를 무시하고 비교할 수 있다.
  • 만 16세 남성의 59%는 170~180cm에 존재하며, 만 16세 여성의 50%는 160~170cm에 존재한다는 것을 알 수 있다.

 

 

 

 지금까지 기술통계학의 가장 기초가 되는 빈도 분석(Frequency analysis)의 도수분포표(Frequency distribution table)에 대해 알아보았다.

 빈도 분석은 모든 데이터 분석의 기반이 되며, 데이터의 분포를 파악하고, 연구자의 의도를 대상에게 전달하는 데 있어, 작성하기도 쉽고, 이해하기도 쉬우므로, 강력한 영향을 미친다.

 변수의 수가 무수히 많고, 하나하나의 변수를 구성하는 집단 역시 매우 많기 때문에, 모든 빈도를 보여주는 것보다, 연구자의 의도가 가장 잘 담겨 있는 대상에 대한 도수분포표를 보여주는 것이 매우 중요하며, 도수분포표를 생성하기 전에 자신이 전달하고자 하는 바가 무엇인지? 자신이 전달하고자 하는 바에서 대상 집단이 어떻게 되는지를 명확히 하도록 하자.

728x90
반응형

'Python으로 하는 기초통계학 > 기본 개념' 카테고리의 다른 글

중심경향치(1) - 최빈값, 중앙값  (0) 2021.03.03
도수분포표와 시각화  (0) 2021.03.02
통계 분석을 위한 데이터 준비  (0) 2021.03.01
변수(Variable)  (0) 2021.03.01
통계학이란?  (0) 2021.02.26
728x90
반응형

 데이터 분석을 하기 위해선, 제일 먼저 데이터가 필요하다. 난수 데이터를 생성하거나, 직접 데이터를 만드는 것도 나쁜 방법은 아니지만, 해당 포스팅을 보는 사람이 실제 데이터를 이용해서 논문을 쓰거나, 특정 결과물을 만들고 싶을 가능성이 높다고 생각하고, 실제 데이터 속에 숨어 있는 진짜 정보를 찾아내는 것이 지식이 되므로, 원시 자료(Rawdata)를 구하고, 학습에 필요한 변수들만 일부 추출하여, 기초 통계분석을 위한 학습용 데이터를 만들어보겠다.

 

 

0. 분석 환경 설명

분석 환경 구축은 상황에 따라 그 수준이 크게 차이가 나지만, 본 포스트에서는 윈도우 환경에서 아나콘다를 설치하고, 이를 통해 Python을 사용할 예정이다.

  • conda 4.9.2 버전, Python 3.7 버전을 사용하겠다.
  • 자세한 설치 방법은 이전 포스트인 "Python 파이썬과 아나콘다"를 참고하기 바란다.
  • Python을 사용할 방법은 아나콘다를 설치하면서 함께 설치 된 주피터 노트북을 사용할 것이나, 보다 편한 툴을 원하는 사람은 파이참("Python 파이썬과 파이참")을 사용하길 바란다.
  • 분석에는 기본적으로 pandas, numpy, scipy, matplotlib를 사용할 것이며, pandas는 1.1.3 버전, numpy는 1.19.2 버전, scipy는 1.5.2 버전, matplotlib는 3.3.2 버전을 사용할 것이다.
  • pandas, numpy, scipy, matplotlib는 아나콘다 설치 시, 기본적으로 설치되므로, 굳이 다른 라이브러리를 다운로드할 필요는 없으나, 이에 관심 있는 경우, "Python 필요한 모듈들을 설치해보자"를 참고하기 바란다.

 

 

 

 

1. 필요한 원시 자료 구하기

  • 원시 자료(Rawdata)는 말 그대로, 아무런 가공도 하지 않은, 가장 기본적인 데이터 상태를 가리킨다.
  • 정부 4.0 이후로, 수많은 공공 기관, 의료 기관 등에서 자체 관리하던 데이터를 통합 관리하려는 시도가 있었고, 그덕에 질 높은 원시 자료 구하기가 꽤 쉬워졌다.
  • 추천하는 원시자료 홈페이지는 다음과 같다.
  • 공공데이터포털 - 행정안전부에서 운영하는 각종 공공 데이터가 모여있는 곳
  • 보건복지데이터포털 - 건강위험인지조사, 노인실태조사 등
  • 고용조사 분석시스템 - 청년패널조사, 대졸자직업이동경로조사, 고령화연구패널조사
  • 보건의료빅데이터개방시스템 - 전국 병의원 및 약국 현황, 의료장비 상세 현황, 요양기관 개설 현황 등
  • 청소년건강행태조사 - 질병관리청
  • 게임이용자 패널 연구 - 한국콘텐츠진흥원
  • 한국복지패널 - 한국보건사회연구원
  • 해당 포스트에서는 비교적 접근하기 쉽고, 데이터의 질도 상당히 좋은 한국복지패널을 사용하도록 하겠다.

 

 

 

 

2. 청소년건강행태조사 원시자료 구하기

  • 위 참조를 통해 질병관리청의 청소년건강행태조사를 다운로드하자.
  • 청소년건강행태조사는 흡연, 음주, 신체활동과 같은 변수를 통해 청소년층의 건강행태를 파악하는 것을 목적으로, 2005년부터 매년마다 중·고등학교 재학생을 대상으로 꾸준히 실시해온 국가승인통계조사로, 직관적인 데이터와 높은 참여율로, 다루기 매우 편한 데이터다.
  • Python을 사용하여 분석할 것이기 때문에, SAS나 SPSS 무엇을 다운로드 받든 지 큰 상관은 없으나, 본 포스트에서는 SPSS를 사용하여 분석을 진행하도록 하겠다.
  • 본 포스트에서 다운로드할 데이터는 "제15차(2019) 청소년건강행태조사"다.

  • 해당 원시자료에 관심이 있거나, 이를 이용하여 연구를 해보고 싶다면, 지침서나 통계집 등의 산출물을 자세히 읽어보는 것을 추천한다.

 

 

 

 

3. 데이터 가져오기

  • spss, sas 데이터는 pandas를 이용해서 쉽게 가지고 올 수 있다.
import pandas as pd
>>> Rawdata = pd.read_spss("kyrbs2019.sav")

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-2-a3be1637ac91> in <module>
----> 1 Rawdata = pd.read_spss("kyrbs2019.sav")

~\anaconda3\lib\site-packages\pandas\io\spss.py in read_spss(path, usecols, convert_categoricals)
     34     DataFrame
     35     """
---> 36     pyreadstat = import_optional_dependency("pyreadstat")
     37 
     38     if usecols is not None:

~\anaconda3\lib\site-packages\pandas\compat\_optional.py in import_optional_dependency(name, extra, raise_on_missing, on_version)
    108     except ImportError:
    109         if raise_on_missing:
--> 110             raise ImportError(msg) from None
    111         else:
    112             return None

ImportError: Missing optional dependency 'pyreadstat'.  Use pip or conda to install pyreadstat.
  • 처음 spss 데이터를 가지고 오는 경우, 위와 같은 오류가 뜰 수 있는데, ImportError에서 요청한 데로, pyreadstat 패키지를 깔면 해결된다.
>>> !pip install pyreadstat
Collecting pyreadstat
  Downloading pyreadstat-1.0.9-cp38-cp38-win_amd64.whl (1.2 MB)
Requirement already satisfied: pandas>0.24.0 in c:\users\gooop\anaconda3\lib\site-packages (from pyreadstat) (1.1.3)
Requirement already satisfied: python-dateutil>=2.7.3 in c:\users\gooop\anaconda3\lib\site-packages (from pandas>0.24.0->pyreadstat) (2.8.1)
Requirement already satisfied: pytz>=2017.2 in c:\users\gooop\anaconda3\lib\site-packages (from pandas>0.24.0->pyreadstat) (2020.1)
Requirement already satisfied: numpy>=1.15.4 in c:\users\gooop\anaconda3\lib\site-packages (from pandas>0.24.0->pyreadstat) (1.19.2)
Requirement already satisfied: six>=1.5 in c:\users\gooop\anaconda3\lib\site-packages (from python-dateutil>=2.7.3->pandas>0.24.0->pyreadstat) (1.15.0)
Installing collected packages: pyreadstat
Successfully installed pyreadstat-1.0.9
WARNING: You are using pip version 20.3.3; however, version 21.0.1 is available.
You should consider upgrading via the 'c:\users\gooop\anaconda3\python.exe -m pip install --upgrade pip' command.
>>> Rawdata = pd.read_spss("kyrbs2019.sav")
>>> Rawdata

  • 총 57303명의 객체(Rows)와 183개의 변수(Columns)가 있는 데이터가 가져와졌다.
  • 위 표를 DataFrame이라고 하며, 이에 대한 보다 자세한 정보를 알고자 한다면, 해당 포스팅("Pandas-데이터 프레임의 구조와 용어 정리")을 참고하길 바란다.

 

 

 

 

4. 필요 변수(Columns)만 추출하기

  • 이번에는 "제15차(2019) 청소년건강행태조사 원시자료(지침서)"를 보고, 가져온 원시자료를 파악해보자.
  • 변수의 이름은 겹치지 않는 것이 매우 중요하며, 그 내용이 길면 다루기 어려워지므로, 보통 영어 알파벳과 숫자로 구성한다.
  • 때문에, 원시자료 지침서를 참고하지 않는다면, 자신이 다룰 데이터의 변수들을 파악하기 쉽지 않으므로, 원시자료를 다루고자 한다면, 반드시 변수들이 정리되어 있는, 지침서나 코딩 북 등을 참고하기 바란다.
  • 모든 변수를 보는 것은 매우 비효율적이므로, 앞으로 분석에 필요할 청소년건강행태조사의 대표적인 변수 16개만 골라, 앞으로 학습할 데이터를 만들도록 하겠다.
  • 선택 변수 설명
변수명 변수 설명 변수명 변수 설명
SEX 성별 PA_TOT 하루 60분 이상 신체활동 일수
AGE 만나이 M_STR 평상시 스트레스 인지
HT 신장 M_SLP_EN 잠으로 피로 회복 정도
WT 체중 AC_LT 평생 음주 경험
E_S_RCRD 학업성적 TC_LT 평생 흡연 경험
E_SES 가정의 경제상태 INT_WD_MM 주중 학습 목적 이외 평균 인터넷 이용 시간
PR_HT 주관적 건강인지 INT_WK_MM 주말 학습 목적 이외 평균 인터넷 이용 시간
Target_DF = Rawdata[["SEX", "AGE", "HT", "WT", "E_S_RCRD", "E_SES",
                     "PR_HT", "PA_TOT", "M_STR", "M_SLP_EN", "AC_LT",
                     "TC_LT", "INT_WD_MM", "INT_WK_MM"]]
  • 변수의 수를 줄였으므로, 변수 이름을 아예 한글로 바꿔서 알아보기 쉽게 만들자.
Target_DF.columns = ["성별", "연령", "키", "몸무게", "학업성적",
                     "경제상태", "건강인지", "운동일수", "스트레스인지",
                     "피로회복정도", "음주경험", "흡연경험",
                     "주중_인터넷이용시간","주말_인터넷이용시간"]
                     
Target_DF

  • Python은 UTF-8을 기반으로 만들어졌기 때문에, 한글을 사용했을 때, 문제가 발생하기 쉬운 다른 언어들과 달리 한글을 Column의 이름으로 사용하거나, 객체를 담는 변수의 이름으로 사용할 수도 있다.
  • 물론, 가능은 하지만 실전에서는 가능한 한글을 사용하지 않기를 바란다.

 

 

 

 

5. 결측값 처리하기

  • 출력된 표를 보니 NaN이라는 이상한 문자가 있는 것을 볼 수 있다.
  • 이는 결측값(Missing Value)로 어떠한 연유에 의해 값이 누락된 것이다.
  • 결측값을 해결하는 문제는 데이터 분석에서 매우 민감하고 중요한 부분이지만, 이는 현 포스트에서 다루고자 하는 기초 통계학 부분과는 거리가 있으므로, 이를 아주 단순하게 처리하고 가도록 하겠다.
  • 결측값이 존재하는 변수는 다음과 같다.
>>> Target_DF.isna().sum()
성별                0
연령              234
키              1555
몸무게            1555
학업성적              0
경제상태              0
건강인지              0
운동일수              0
스트레스인지            0
피로회복정도            0
음주경험              0
흡연경험              0
주중_인터넷이용시간    14297
주말_인터넷이용시간    12488
dtype: int64
  • 결측값이 발생한 이유에 대한 분석은 보고서를 읽는 것이 가장 정확하지만, 매우 단순하게 해당 부분을 해결하겠다.
  • "주중_인터넷이용시간", "주말_인터넷이용시간"은 결측값 제외 시, 최솟값이 10.0인 것을 볼 때, 인터넷을 사용하지 않은 사람을 결측값으로 처리한 것으로 판단하고, 모두 0으로 바꾸도록 하겠다.
  • 연령, 키, 몸무게가 누락된 대상은 전체 데이터 셋 57,303명에서 차지하는 비중이 매우 작으므로, 제거하여 무시하도록 하겠다.
Target_DF["주중_인터넷이용시간"] = Target_DF.주중_인터넷이용시간.fillna(0)
Target_DF["주말_인터넷이용시간"] = Target_DF.주말_인터넷이용시간.fillna(0)
Target_DF.dropna(inplace = True)
Target_DF.reset_index(drop = True, inplace = True)
Target_DF

  • 위 코드 실행 시, 붉은색으로 SettingWithCopyWarning이 뜨는데, 이는 pandas의 메모리를 절약하기 위한 방법인, 데이터 종속성으로 인해 발생하는 문제로, 기존의 Rawdata와 Target_DF가 별개로 존재하게 되므로, 발생하는 문제다. 이를 해결하기 위해선, copy함수를 이용해서 Target_DF를 생성할 때, Rawdata와 별개로 흐르게 만들면 되지만, 딱히 결과에 영향을 주진 않으므로, 그냥 넘어가도록 하자.
  • 추출된 데이터 셋을 추후 쉽게 사용하기 위해 저장해놓도록 하겠다.
Target_DF.to_csv("Data_for_study.csv", index=False)

Data_for_study.csv
3.39MB

 

 Python으로 하는 기초통계학은 해당 데이터를 사용하여 진행할 것이다. 해당 데이터를 참고 파일로 올려놓을 테니, 위 부분을 생략하고 진행하고자 하는 경우, 바로 데이터만 다운로드하고 사용해도 괜찮다.

728x90
반응형

'Python으로 하는 기초통계학 > 기본 개념' 카테고리의 다른 글

중심경향치(1) - 최빈값, 중앙값  (0) 2021.03.03
도수분포표와 시각화  (0) 2021.03.02
도수분포표  (0) 2021.03.02
변수(Variable)  (0) 2021.03.01
통계학이란?  (0) 2021.02.26
728x90
반응형

 처음 통계학을 접하게 되었을 때, 변수(Variable)가 무엇인지 헷갈리는 경우가 꽤 많다. 학교에서 데이터 분석 강의를 하거나, 주변인들이 데이터 분석에 대해 질문을 해올 때, "변수라는 용어를 많이 사용하는데 대체 그 변수가 구체적으로 무엇이냐?"라는 질문을 종종 해온다.

 해당 파트에서 학습할 변수는 분포와 함께 데이터 분석에 있어, 상식으로 사용되는 개념이므로, 꼭 숙지하고 넘어가도록 하자.

 

 

변수(Variable)


 "변수(Variable)"는 우리가 관심 있는 대상이 가지고 있는 속성(Attribute)이다.


 위 한 줄이 가장 쉽게 변수를 설명할 수 있는 말인데, 막연하게 느껴질 수 있으므로, 좀 더 자세히 설명해보도록 하겠다. 이전 포스트("통계학이란? - 1.모집단과 표본집단")에서 "연구자가 관심 있는 대상""모집단"이라고 했다.

 이 모집단이 가지고 있는 속성(Attribute)이 바로 변수다. "속성(Attribute)"은 연구자가 정의할 수 있는 대상이 가지고 있는 성질이며, 동시에 대상을 특정 혹은 정의할 수 있는 개념이다.

 

예시를 통한 설명

  • 당신이 "사람"이라는 대상에 대해 관심이 있다고 가정해보자. 그럼 사람은, 성별, 연령, 국적, 키, 몸무게, 거주지, 최종 학력 등의 속성을 가지고 있다고 할 수 있다.
  • 만약 당신이 특정 속성을 갖는 사람을 찾고 싶다고 해보자. 성별이 여성, 연령이 24살이며 한국 국적을 갖고 있는 사람을 찾는다고 하면, 꽤 광범위하므로 찾기 쉽지 않을 것이다.
  • 여기에 변수를 하나하나 추가해보자. 키가 153cm, 몸무게 54kg, 대전광역시 거주, 대학교 졸업, 원무과에서 근무함.
  • 이런 식으로 변수가 하나하나 추가될수록 특정 개체를 쉽게 설명할 수 있게 된다. 우리는 우리가 관심 있는 대상을 이러한 변수들을 통해, 그들의 속성을 구체화시키고, 그들 개개인을 구분할 수 있다.
  • 모집단이 연구자의 관심 집단이 바뀌면, 바뀌듯이 변수 역시 모집단에 종속되어 변한다.

 

변수와 개인정보

  • 변수를 통해 개인을 특정할 수 있다고 하였는데, 변수에 따라 그 정도가 바뀌게 된다.
  • 단 하나로 대상을 특정할 수 있는 변수가 있으며, 3개 이상의 변수가 동시에 사용되어 대상을 특정할 수 있는 변수도 있다.
  • 예를 들어, 주민등록번호, 휴대폰 번호와 같은 변수는 아주 강력하게 특정 객체를 지목하게 한다.
  • 이름, 거주지, 연령과 같이 함께 사용되어, 강력하게 특정 객체를 지목하는 변수도 있다.
  • 이는 RDB의 Primary key, Super key와 유사한 개념이다.
  • 때문에 주민등록번호, 휴대폰 번호, 이름 같이 강력한 변수는 아예 데이터에 넣지 않거나, 만약 데이터에 들어가 있는 경우, 그 관리 수준이 상당히 엄중하다. 

 

 

 

 

 

 

1. 변수의 종류

  • 변수는 크게 "질적 변수(Qualitative variable)", "양적 변수(Quantitative variable)" 둘로 나뉜다.
  • 변수의 종류에 따라 접근하는 통계 분석 방법이 바뀌므로, 정확히 변수의 종류를 인식하는 것은 필수다.

 

 

 

 

2. 변수와 척도

  • 척도는 어떠한 현상을 측정하기 위해 만든 도구를 의미한다.
  • 연구자가 관심 있는 대상인 모집단이 존재하고, 그 모집단이 가지고 있는 속성인 변수가 존재하는데, 이 변수를 어떠한 도구를 이용해서 측정할 것인가를 이야기한다.
  • 척도는 위 변수를 측정하는 방법으로써 1:1로 대응되어 존재한다.
    (이산형 변수는 등간 변수라고도 부르며, 연속형 변수는 비율 변수라고도 부르므로, 변수의 이름과 척도의 이름은 동일하다.)

  • 변수와 헷갈리기 꽤 쉬운 개념으로, 척도는 종종 변수와 혼용되어 지칭되기도 한다.
  • 일반적으로, 명목 변수는 명목 척도로, 서열 변수는 서열 척도로, 등간 변수는 등간 척도로, 비율 변수는 비율 척도로 측정하기 때문에 이를 혼용하여 지칭해도 정보가 잘못 전달되거나 하는 문제가 발생할 가능성은 크지 않다.
  • 그러나, 변수와 척도는 동일한 개념은 아니기 때문에 주의할 필요는 있는데, 위 사진에서 보듯, 상위 척도를 이용하여, 보다 하위 레벨의 변수를 측정할 수도 있기 때문이다.
  • 예를 들어, 길이와 같은 연속형 변수를 1m보다 작다, 크다와 같이 이분화시켜 명목형 척도로 측정할 수 있으며, 10 cm 이하, 10cm ~ 1m 사이, 1m 이상 과 같은 서열 척도로 측정할 수도 있다.
  • 그러나, 하위 수준의 변수를 보다 높은 수준의 척도로는 측정할 수 없다(성별과 같은 명목 척도를 연속형 척도로 측정할 수는 없다).

 

 

 

 

3. 질적 변수(Quantitative Variable)

  • 범주형 변수(Categorical Variable)이라고도 하며, 말 그대로 변수 안에 있는 데이터들이 범주화되어 있다는 뜻이다.
  • 즉, 변수 안에 N개의 집단이 존재하며, 그 집단을 숫자로 나타낸다 할지라도 그 숫자는 데이터의 양을 줄이기 위한 목적이지, 그 숫자엔 숫자로써의 의미가 존재하지 않는다.
  • 즉, 문자로 나타낼 수 있는 변수를 의미한다.

 

3.1. 명목 변수(Nominal Variable)

  • 완전히 서로 관련 없는 문자들로 이루어진 변수를 의미한다.
  • 이를 쉽게 데이터화 하기 위해 숫자로 나타낸다 할지라도, 그 숫자에 대해선, 서로 구분하는 의미만 존재하지, 숫자가 가진 그 어떠한 정보도 존재하지 않는다.
  • 예를 들어, 성별의 남자를 1로, 여자를 2로 표기한다 할지라도, 여기에는 "남자는 1등 여자는 2등이다.", "여자가 남자보다 2배 더 우월하다."와 같은 의미는 전혀 존재하지 않는다.
  • 토트넘 축구 선수인 "손흥민의 등번호 7번"과 주장인 "위고 요리스의 등번호 1번"에는 그 어떠한 숫자적 의미가 존재하지 않는다.
  • 야구의 4번 타자와 같은 특정 숫자에 상징성이 있을 수는 있으나, 등번호를 늘여놓았을 때, 그 순서에 일정한 방향을 가진 서열이 존재하지 않기 때문에, 부여된 숫자는 단순히 객체를 구분하는 역할만 한다.

 

3.2. 서열 변수(Ordinal Variable)

  • 명목 척도 중에 순서의 개념이 존재하는 변수를 의미한다.
  • 예를 들어, 최종 학력은 "무학", "초등학교", "중학교", "고등학교", "대학교", "대학원"과 같이 명목형 척도로 측정되지만, 순서가 존재하기 때문에, 이를 숫자로 만들었을 때, 그 숫자에 아무런 의미가 존재하지 않는다고 할 수는 없다.
  • 즉, 숫자의 개념 중 순서의 개념이 존재하는 변수이다.
  • "무학 = 0, 초등학교 = 1, 중학교 = 2, 고등학교 = 3, 대학교 = 4, 대학원 = 5"로 나타낸다고 할 때, 이를 늘어놓으면, 5가 2보다 뒤에 있다라고는 할 수 있지만, "대학원(5) - 고등학교(3) = 중학교(2)"라고 할 수는 없다.

 

 

 

 

4. 양적 변수(Qualitative Variable)

  • 단순하게 연속형 변수(Continuous)라고 지칭하는 경우도 종종 있는데, 이 경우, 양적 변수를 구성하는 이산형 데이터와 연속형 데이터를 구분하기 어려워질 수 있으므로, 그냥 양적 변수라고 하길 추천한다.
  • 데이터를 숫자로 나타냈을 때, 숫자 그 자체인 경우다.
  • 그 숫자를 이산형으로만 나타낼 수 있는가, 연속형으로도 나타낼 수 있는가에 따라 이산형 변수(등간 변수)와 연속형 변수(비율 변수)가 나뉜다.

 

4.1. 등간 변수(Interval Variable)

  • 이산형으로만 나타낼 수 있는 숫자로, 각 숫자 사이가 일정하며, 그 사이에 그 어떠한 값도 존재하지 않는 데이터를 의미한다.
  • 이산형이라는 말은 숫자가 연속되지 않고 일정한 거리로 떨어져 있다는 소리로, 이해하기 쉽게 이야기하면 소수점이 존재하지 않는 경우라고 할 수 있다(물론 이는 이해하기 쉬운 예시이지 온도와 같이 소수점을 갖는 등간 변수 역시 존재하므로, 등간 변수에는 절대 소수점이 등장하지 않는다고 생각해서는 안된다).
  • 예를 들어, 남극에 있는 펭귄 수는 이산 되어 있는 숫자다. 펭귄이 반마리만 있는 경우, 이미 죽은 펭귄이므로, 이를 펭귄 0.5마리라고 할 수는 없다. 
  • 이글루 안에 펭귄 5마리가 있을 때, 이 이글루 안에 펭귄을 2마리 더 넣어 7마리로 만들 수 있고, 펭귄 3마리를 다시 빼서 4마리로 만들 수도 있으므로, 가감(더하기 빼기)이 가능하다.
  • 그러나, 펭귄 5마리에게 펭귄 2마리를 곱하거나 나눈다는 것은 불가능하며, 펭귄 1마리를 2로 나누겠다는 소리는 애초에 단위가 다르기 때문에 시도해서도 안되며, 펭귄을 죽이겠다는 소리이므로, 이런 상상은 하지도 말자.
  • 등간 변수와 비율 변수는 꽤 구분하기 어려운 개념인데, 대표적인 등간 변수인 온도는 36.2˚와 같이 소수점이 있는 경우도 존재하기 때문이다.
  • 온도는 절대적인 기준을 갖는 것이 아닌, 일정한 간격을 가지고 상대적으로 존재하는 것이기 때문에 36˚보다 18˚가 두 배 더 춥다고 할 수는 없다.

 

4.2. 비율 변수(Ratio Variable)

  • 연속형 숫자로 나타낼 수 있는 데이터로, 정수 사이에 수많은 값이 존재한다.
  • 170 cm와 171cm 사이에는 170.5, 170.05, 170.005와 같이 소수점으로 나타낼 수 있는 수많은 숫자가 존재한다.
  • 이를 비율 변수라고 부르는 이유는 측정된 데이터를 비율로 계산이 가능하기 때문으로, 이러한 비율 변수는 절대적인 기준이 존재하기 때문에 곱하고 나눌 수 있다.
  • 이 절대적인 기준이라는 것은 이 속성이 존재하지 않을 수 있는 절대 영점(Absolute Zero Point)이 존재한다는 소리로, 길이나 무게는 0이 되는 순간, 대상에게 있어 그 속성의 값이 "없다"가 될 수 있으나, 온도는 존재하지 않는다는 개념이 존재하지 않는다.
  • 비율 변수는 절대적인 기준이 존재하기 때문에 더하기, 빼기, 곱하기, 나누기가 모두 가능하다.
  • 비율 변수는 통계 분석에 있어 가장 편리한 대상으로, 모든 척도로 측정할 수 있기 때문에, 하위 변수로 쉽게 변환할 수 있다. 그 덕에 모든 통계 분석 기법의 대상이 될 수 있다.

 

 

 

 

5. 정리

  • 변수는 대상 집단(모집단)이 가지고 있는 속성이며, 이 변수는 크게 질적 변수(명목 변수, 서열 변수), 양적 변수(이산형 변수, 연속형 변수)로 나뉜다.
  • 변수를 측정하는 도구는 척도이며, 상위 변수는 하위 변수로 그 수준을 바꿀 수 있으며, 그로 인해 하위 척도로도 상위 변수를 측정할 수 있다.
  • 변수를 나누는 기준을 정리한 표는 다음과 같다.
변수 순서 더하기, 빼기 곱하기, 나누기 절대영점
명목 변수 X X X X
서열 변수 O X X X
등간 변수 O O X X
비율 변수 O O O O
  • 위 기준만으로 나누기 애매한 경우도 종종 존재하기 때문에, 이를 보다 단순화시킨 질적 변수, 양적 변수로 이분화시켜 변수를 구분하는 경우가 많다.
  • 변수의 종류에 따라 사용할 수 있는 통계 분석 기법이 크게 달라지기 때문에 변수의 종류가 무엇인지 판단하는 능력은 통계 분석을 위해 필수로 가지고 있어야 하는 기술이다.
728x90
반응형

'Python으로 하는 기초통계학 > 기본 개념' 카테고리의 다른 글

중심경향치(1) - 최빈값, 중앙값  (0) 2021.03.03
도수분포표와 시각화  (0) 2021.03.02
도수분포표  (0) 2021.03.02
통계 분석을 위한 데이터 준비  (0) 2021.03.01
통계학이란?  (0) 2021.02.26
728x90
반응형

연립일차방정식과 가우스 소거법

  • 앞서 행렬은 연립일차방정식의 계수와 변수를 분리하여 사용하게 되면서 등장하였다고 했다.
  • 앞서 행렬의 기본적인 성질은 배웠으니, 이제 연립일차방정식과 행렬이 어떻게 연결되는지에 대해 알아보자.
  • 연립일차방정식을 통해 첨가 행렬을 만들어보고, 가우스 소거법으로 연립일차방정식을 풀이해보자.

 

 

 

 

1. 연립일차방정식(System of Linear equations)

1.1. 일차방정식(Linear equation)

  • 미지수 $x_1, x_2, x_3, ..., x_n$에 관한 일차방정식은 상수 $b$와 계수 $a_1, a_2, a_3, ..., a_n$이 실수일 때, 다음과 같은 꼴로 나타나는 방정식이다.
  • 일차방정식이므로, 미지수 $x_1, x_2, x_3, ..., x_n$의 차수는 1이다.

$$a_1x_1 + a_2x_2 + a_3x_3 + \cdots a_nx_n = b$$

 

1.2. 연립일차방정식(System of Linear equations)

  • 미지수 $x_1, x_2, x_3, ..., x_n$에 대하여 유한개의 일차방정식 모임은 아래와 같다.

$$a_{11}x_1 + a_{12}x_2 + a_{13}x_3 + \cdots a_{1n}x_n = b_1$$

$$a_{21}x_1 + a_{22}x_2 + a_{23}x_3 + \cdots a_{2n}x_n = b_2$$

$$a_{31}x_1 + a_{32}x_2 + a_{33}x_3 + \cdots a_{3n}x_n = b_3$$

$$ \vdots $$

$$a_{m1}x_1 + a_{m2}x_2 + a_{m3}x_3 + \cdots a_{mn}x_n = b_m$$

  • 실수 $b_1, b_2, b_3, ..., b_m$이 모두 0이면 이 연립방정식을 동차(Homogeneous)라 하며, 반대의 경우에는 비동차(non-Homogeneous)라 한다.
  • 미지수 $x_1, x_2, x_3, ..., x_n$에 대하여 어떤 수 $s_1, s_2, s_3, ..., s_n$을 각각 대입하여, 각 방정식이 모두 성립하면 어떤 수 $s_1, s_2, s_3, ..., s_n$을 연립일차방정식의 해(Solution)이라 한다.
  • 연립일차방정식의 해 전체 집합을 연립일차방정식의 해집합(Solution set)이라 한다.
  • 동일한 해집합을 가지는 두 연립일차방정식을 동치(Equivalent)라고 한다.
  • 연립일차방정식의 해에 대하여, 일반적으로 다음 중 하나가 성립한다.
  1. 해를 갖지 않는다.
  2. 유일한 해를 갖는다.
  3. 무수히 많은 해를 갖는다.

 

1.3. 연립일차방정식과 행렬

  • 위 연립일차방정식을 행렬로 나타내면 다음과 같다.

$$A = \begin{pmatrix}
 A_{11}& A_{12} & A_{13}  & ... & A_{1n}\\ 
 A_{21}& A_{22} & A_{23}  & ... & A_{2n}\\ 
 A_{31}& A_{32} & A_{33}  & ... & A_{3n}\\ 
 \vdots & \vdots & \vdots & \ddots & \vdots\\
 A_{m1}& A_{m2} & A_{m3}  & ... & A_{mn}\\
\end{pmatrix},\ \ \  

X = \begin{pmatrix}
x_1\\ 
x_2\\ 
x_3\\ 
\vdots \\
x_n
\end{pmatrix},\ \ \ 

B = \begin{pmatrix}
b_1\\ 
b_2\\ 
b_3\\ 
\vdots \\
b_m
\end{pmatrix}$$

$$AX = B$$

  • 우리가 지금까지 봐왔던, 행렬은 바로 $A$로 이를 계수행렬(Coefficient matrix)라 한다.

 

 

 

 

2. 첨가행렬(Augmented matrix)

  • 계수행렬 $A$와 상수항들이 모여서 만들어진 행렬$B$를 붙이면 첨가행렬(Augmented matrix)가 만들어진다.

$$(A | B) = \begin{pmatrix}
 A_{11}& A_{12} & A_{13}  & ... & A_{1n} | b_1\\ 
 A_{21}& A_{22} & A_{23}  & ... & A_{2n} | b_2\\ 
 A_{31}& A_{32} & A_{33}  & ... & A_{3n} | b_3\\ 
 \vdots & \vdots & \vdots & \ddots & \ \ \ \vdots \ \ | \ \vdots \\
 A_{m1}& A_{m2} & A_{m3}  & ... & A_{mn} | b_m\\
\end{pmatrix}$$

  • 첨가행렬은 행렬 방정식의 풀이와 역행렬 구하기에 응용된다.
  • 가우스 소거법을 사용하여 연립일차방정식을 풀이해보자.

 

 

 

 

3. 가우스 소거법(Gaussian elimination)

  • 선형대수학에서, 가우스 소거법은 연립일차방정식을 풀이하는 알고리즘으로, 풀이 과정에서 일부 미지수가 차츰 소거되어, 남은 미지수에 대한 선형 결합으로 풀이가 완성된다.
  • 가우스 소거법은 보통 행렬을 사용하며, 첨가 행렬을 그와 풀이가 더 간단한 행렬로 변환하여 풀이를 완성한다.
  • 가우스 소거법은 행렬식과 역행렬의 계산에도 응용된다.
  • 가우스 소거법은 맨 위 일차방정식부터 임의의 k를 곱해가며 아래에 있는 일차방정식들을 하나하나 맨 앞의 계수부터 0으로 만들어가는 방법으로, 최종적으로 주대각선의 모든 값이 1인 상삼각행렬을 만들게 된다.
  • 내용이 조금 길기 때문에 손으로 풀어보겠다.

  • 가우스 소거법은 위에서부터 천천히 아래로 내려가면서, 주대각성분이 1인 상삼각행렬을 만들어가면 된다.
  • $①$, 최초 첨가행렬에서 첫 번째 행 $R_1$의 첫 원소인 $A_{11}=4$는 주대각성분이므로 이를 1로 만들어주기 위해, $R_1$에 $\frac{1}{4}$를 곱해주어, $A_{11}=1$로 만들어주었다.
  • $②$, 두 번째 행 $R_2$의 첫 원소인 $A_{21}=2$을 0으로 만들어주기 위해, $R_1$의 인자들에 $-2$를 곱하여 $R_2$에 더해주었다.
  • $③$, 세 번째 행 $R_3$의 첫 원소인 $A_{31}=3$을 0으로 만들어주기 위해, $R_1$의 인자들에 $-3$을 곱하여 $R_3$에 더해주었다.
  • $④$, 두 번째 행 $R_2$의 두 번째 원소인 $A_{22}=\frac{1}{2}$은 주대각성분이므로, $1$로 만들어주기 위해, $2$를 $R_2$에 곱해주었다.
  • $⑤$, 세 번째 행 $R_3$의 두 번째 원소인 $A_{32}=-\frac{33}{4}$를 0으로 만들어주기 위해, $R_2$에 $\frac{33}{4}$를 곱하여, $R_3$에 더해주었다.
  • 이를 통해, 연립일차방정식의 해인 $x=2,\ y=-1,\ z=3$을 찾았다.

 

 

 

 행렬이 연립일차방정식에서 어떻게 나오게 되었고, 행렬을 이용해서 연립일차방정식의 해를 쉽게 찾을 수 있는 가우스 소거법에 대해 간단하게 학습해보았다.

 다음 포스트에서는 가우스 소거법에 대해 좀 더 알아보도록 하자.

728x90
반응형

'Python으로 하는 기초 수학 > 행렬' 카테고리의 다른 글

역행렬(Inverse matrix)  (0) 2021.02.26
영인자(Zero Divisor)  (0) 2021.02.25
행렬의 성질  (0) 2021.02.25
행렬(Matrix)  (0) 2021.02.25
728x90
반응형

역행렬(Inverse matrix)

  • $AA^{-1} = A^{-1}A = E$
  • 선형대수학에서 가역행렬(Invertible matrix)은 그와 곱한 결과가 단위행렬인 행렬$A^{-1}$을 갖는 행렬$A$를 말한다.
  • 이 행렬$A^{-1}$를 행렬 $A$의 역행렬이라고 한다.
  • 고등학교 행렬 문제에서는 교환법칙의 성립 유/무를 묻는 문제가 많이 나온다.
  • 수능 유형 예시)

$$A(A+B)=E \rightarrow AB = BA$$

$$put) A(A + B) = E = (A+B)A\ \rightarrow \ A^2+AB=E=A^2+BA \ \rightarrow \  AB=BA$$

 

 

 

 

1. 역행렬을 구하는 방법

  • 행렬 A가 이차 정사각 행렬일 땐 다음 방법으로 구할 수 있다.

$$A = \begin{pmatrix} a & b\\ c & d \end{pmatrix},\ \ \ A^{-1}=\frac{1}{ad-bc}\begin{pmatrix} d & -b\\ -c & a \end{pmatrix}$$

  • 위 역행렬을 구하는 방법에서 $ad-bc=0$인 경우, 분모가 0이 되므로 역행렬을 만들 수 없다.
  • 즉, $ad-bc$의 값을 통해 역행렬이 존재하는지를 확인할 수 있다.
  • $ad-bc \neq 0$: $A^{-1}$이 존재한다.
  • $ad-bc = 0$: $A^{-1}$이 존재하지 않는다.
  • Python으로 역행렬을 구해보자.
>>> mat = np.array([[2, 1, 5],[0,0,1],[-1,0,2]])
>>> inv_mat = np.linalg.inv(mat)
>>> np.dot(mat, inv_mat)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
  • 만약 역행렬이 존재하지 않는 행렬이라면, 다음과 같은 오류를 반환한다.
>>> mat = np.array([[2, 1],[2,1]])
>>> inv_mat = np.linalg.inv(mat)
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-12-72ac304bfc31> in <module>
      1 mat = np.array([[2, 1],[2,1]])
----> 2 inv_mat = np.linalg.inv(mat)

...

---> 88     raise LinAlgError("Singular matrix")
     89 
     90 def _raise_linalgerror_nonposdef(err, flag):

LinAlgError: Singular matrix

 

 

 

 

2. 이차 정사각행렬 역행렬 공식의 증명

  • 역행렬 공식의 증명은 가우스 조던 소거법(Gauss-Jordan elimination method)로 구하는 방법과 전치행렬, 소행렬, 여인자를 이용해서 구하는 방법 두 가지가 있다.
  • 그러나 이차 정사각행렬은 비교적 공식이 간단하므로, 옳바른 증명 방법은 아니긴 하지만, 위 기법들을 사용하지 않고도 구할 수 있다.
  • 행렬 $A$와 역행렬 $A^{-1}$을 다음과 같이 정의하자.

$$A=\begin{pmatrix} a & b\\ c & d \end{pmatrix},\ \ A^{-1}=\begin{pmatrix} x & y\\ z & r \end{pmatrix}$$

$$AA^{-1}=E \rightarrow \begin{pmatrix} a & b\\ c & d \end{pmatrix}\begin{pmatrix} x & y\\ z & r \end{pmatrix} = \begin{pmatrix}1 & 0\\ 0 & 1 \end{pmatrix}$$

$$ax + bz = 1 \cdots ①$$

$$ay + br = 0 \cdots ②$$

$$cx + dz = 0 \cdots ③$$

$$cy + dr = 1 \cdots ④$$

  • 위 식을 기반으로 $(ad-bc)$가 만들어지도록 4개의 식을 유도해보자

$$①*c - ③*a = (acx+bcz-c)-(acx+adz)=0\  \rightarrow \ (bc-ad)z = c \cdots ⑤$$

$$①*d-③*b = (adx+bdz-d)-(bcx+bdz)=0\ \rightarrow \ (ad-bc)x = d \cdots ⑥$$

$$②*c-④*a=(acy+bcr)-(acy+adr-a)=0\ \rightarrow \ (bc-ad)r = -a \cdots ⑦$$

$$②*d-④*b=(ady+bdr)-(bcy+bdr-b)=0\ \rightarrow \ (ad-bc)y = -b \cdots ⑧$$

  • ⑤, ⑥, ⑦, ⑧을 볼 때, $ad-bc \neq 0$이다.
  • $ad-bc=0$인 경우, 행렬 $A$가 영행렬이기 때문에 전제가 성립하지 않는다.
  • ⑤, ⑥, ⑦, ⑧의 양변을 $ad-bc$로 나눠보자.

$$⑤ \rightarrow z = \frac{-c}{ad-bc}$$

$$⑥ \rightarrow x = \frac{d}{ad-bc}$$

$$⑦ \rightarrow r = \frac{a}{ad-bc}$$

$$⑧ \rightarrow y = \frac{-b}{ad-bc}$$

  • ⑤, ⑥, ⑦, ⑧으로부터 유도된 $x,y,z,r$를 $A^{-1}$에 대입하자.

$$A^{-1}=\frac{1}{ad-bc} \begin{pmatrix} d & -b\\ -c & a \end{pmatrix}$$

  • 이차 정사각행렬의 역행렬을 구하는 공식이 유도 되었다.

 

 

 

 

3. 역행렬의 성질

3.1. $(A^{-1})^{n} = (A^{n})^{-1}$

  • $A$의 역행렬이 존재하면, $A^n$의 역행렬도 존재한다.
  • 즉, $A^{100}$의 역행렬이 존재한다면, $A^{20}$의 역행렬도 존재한다는 소리다.

 

3.2. $(kA)^{-1} = \frac{1}{k}A^{-1}$

  • 역원의 개념이므로, 상수 k가 뒤집어진다.
  • $k=0$인 경우, 어차피 영행렬이므로, 역행렬이 존재하지 않는다.

 

3.3. $(AB)^{-1} = B^{-1}A^{-1},\ \ (APB)^{-1} = B^{-1}P^{-1}A^{-1}$

 

3.4. 차수가 같은 두 행렬 A,B 모두 역행렬이 존재한다면, AB역시 역행렬이 존재한다.

  • 역, 대우 모두가 참인 성질이다.
  • 역) A, B중 적어도 하나가 역행렬이 존재하지 않는다면, AB의 역행렬 또한 존재하지 않는다.
  • 대우) AB가 역행렬이 없으면, A, B 중 적어도 하나는 반드시 역행렬이 존재하지 않는다.
728x90
반응형

'Python으로 하는 기초 수학 > 행렬' 카테고리의 다른 글

연립일차방정식과 가우스 소거법(Gaussian elimination)  (0) 2021.02.26
영인자(Zero Divisor)  (0) 2021.02.25
행렬의 성질  (0) 2021.02.25
행렬(Matrix)  (0) 2021.02.25
728x90
반응형

통계학이란?


"통계학이란 불확실한 상황에서 현명한 의사결정을 하기 위한 이론과 방법의 체계이며, 통계학은 자료의 수집·분류·분석과 해석의 체계를 갖는다."
 W.Allen Walls and Harry V.Roberts, Statistics: A New Approach(Glence, Ill., Free Press, 1956), p. 3.
(박정식, 윤영선, 박래수(2010) 현대통계학 제5판 참고)

"통계학은 실증적인 뿌리를 가지고 있으며 실질적 활용에 초점을 맞추고 있기 때문에, 순수수학과 구분되는 응용수학의 일종으로 여겨진다. 통계학의 방법을 통해, 실제 수치들을 왜곡하여 해석하는 것을 막고 연구를 바탕으로 합리적인 의사결정을 할 수 있다."
 Moore, David(1992). <Teaching Statistics as a Respectable Subject>. F. Gordon and S. Gordon. <Statistics for the Twenty-First century>. Washington, DC: The Mathematical Association of America. 14-25쪽. ISBN 978-0-88385-078-7.
(Wikipidia 통계학 참고)


  • 통계학은 Data를 다루는 학문으로, 연구자가 관심 있는 대상을 나타낼 수 있는 다량의 Data를 수집하는 것부터, 그 Data의 모양을 파악하고, 자신의 연구 모델에 맞게 Data를 체계화시켜, 그 안에 숨어 있는 패턴을 찾아내는 모든 과정에 대한 학문이라고 할 수 있다.
  • 통계학은 머신러닝, 딥러닝을 비롯한 데이터를 다루는 각종 학문의 근간이 되므로, 통계학을 제대로 이해하지 못한다면, 다른 학문들의 원리를 제대로 이해할 수 없다.
  • 통계학은 기본적으로 데이터가 어디에 모여 있고, 얼마나 흩어져 있는지를 통해서 데이터를 파악한다.

 

 

 

 

1. 모집단과 표본집단


 모집단(Population): 연구자의 관심 대상이 되는 모든 개체의 집합으로, 연구 대상이 되는 데이터의 전체를 가리킨다.

◎ 표본집단(Sample): 모집단에서 추출해낸 개체의 집합이다.


  • 모집단과 표본집단 예시 1)
    • 연구자가 사람의 발 크기와 키에 대해 어떠한 경향성(Pattern)이 존재할 것이라고 생각했다고 해보자. 이를 확인하고자 한다면, 전 세계에 있는 모든 사람들(모집단)을 대상으로, 데이터를 모아야 할 것이다.
    • 그러나, 이는 막대한 비용과 시간이 소모되기 때문에 불가능한 일이다. 때문에 연구자는 인종, 연령, 성별 등 다양한 변수들을 고려하여, 모집단을 대표할 수 있는 표본집단(Sample)을 추출하여, 모집단을 추정한다.

 

  • 모집단과 표본집단 예시 2)
    • 참치 통조림을 만드는 공장에서 제품에 이상이 있는지 확인하기 위해, X-ray를 비롯한 다양한 도구를 이용해서 전수 조사하였으나, 실제로 제품을 열어서 확인해보는 것이 가장 정확한 결과를 가져온다고 가정해보자.
    • 모든 통조림을 열어서 확인해보는 것이 품질이 떨어지는 제품이 얼마나 발생하는지 알 수 있겠지만, 그렇게 했다간 통조림을 팔 수 없게 될 것이다. 때문에 모집단인 모든 통조림에서 통조림을 일부만 추출(표본집단)해서 모집단을 추정하게 된다.

 

  • 모집단과 표본집단 예시 3)
    • 당신이 통계 유치원 선생님이고, 기린반 어린이 30명과 해바라기반 어린이 25명과 함께 학예회 준비로 동요를 부르려고 하는데, 아이들이 뽀로로 주제가와 핑크퐁 아기 상어 중 무엇을 더 좋아할지를 몰라 이에 대해 고민하고 있다고 가정하자.
    • 당신은 기린반 어린이와 해바라기반 어린이들을 대상으로 선호하는 캐릭터에 대해 조사를 할 수 있다. 이 경우 당신의 관심 대상인 기린반, 해바라기반 어린이들은 55명으로 매우 적기 때문에 모집단 전체에 대해 조사를 할 수도 있다.

 

  • 모집단은 연구자의 마음에 따라 그 규모가 크게 달라지기 때문에, 예시 3)처럼 모집단의 규모가 작다면, 모집단 전체를 대상으로 분석을 할 수 있다. 즉, 반드시 표본집단을 통해서 통계 분석을 진행하는 것은 아니다.
  • 그러나, 모집단이 작은 경우만 존재하지는 않기 때문에, 모집단을 가장 잘 대표할 수 있는 표본집단을 뽑아, 통계적 기법을 통해 모집단의 성격을 추정하는 것이 현대 통계학의 주류다.

 

 

 

 

2. 모수와 통계량


 모수(Parameter): 모집단의 특성을 수치로 나타낸 것이다.

 통계량(Statistic): 표본의 특성을 수치로 나타낸 것이다.


  • 대전 여자 중학생의 평균 팔 굽혀 펴기 횟수를 알고 싶다고 가정해보자.
    • 대전에 사는 여자 중학생들의 평균 팔 굽혀 펴기 횟수를 알기 위해, 완전 무작위로 각 중학교의 학년별 한 반의 여중생들을 대상으로 평균 팔 굽혀 펴기 횟수를 구했다.
    • 모집단인 대전에 사는 모든 여자 중학생의 평균 팔 굽혀 펴기의 횟수(모수)와 표본집단의 평균 팔 굽혀 펴기 횟수(통계량)가 같다고 할 수 있을까?
    • 우연히 샘플로 추출된 여중생들이 팔 굽혀 펴기를 유난히 잘하는 사람들이어서, 모수보다 통계량이 더 클 수도 있고, 반대로 우연히 운동을 너무 싫어하는 사람들이 뽑혀서 통계량이 모수보다 더 작을 수도 있다.
    • 즉, 모수와 통계량은 같은 값이 아니다.

 

  • 모집단의 특성을 나타내는 모수를 구하는 것이 가장 정확하겠으나, 앞서 봤듯 모수를 구하지 못하는 상황에서는 표본집단을 통해 모수를 추정해야 하고, 이때 표본집단의 특성을 나타내는 통계량을 이용하게 된다.
  • 모수나 통계량은 앞서 말한 평균뿐만이 아니라, 각 집단을 나타낼 수 있는 다른 특성인 중위수, 최빈값, 최솟값, 최댓값, 분산, 표준편차 등도 다양한 지표들을 포함하는 개념이다.
  • 모수는 그리스 문자($\mu,\ \sigma^2, \sigma$)로 표기하고, 통계량은 영어 알파벳($\bar{X}, S^2, S$)으로 표기하는 것이 관례다.
  • 단, 모집단의 크기인 개체의 양은 $N$으로, 표본집단의 크기는 $n$으로 표기하는 것이 관례다.

 

 

 

 

3. 기술통계학과 추론통계학


◎ 기술통계학(Descriptive statistics): 데이터를 정리하고 요약하여, 데이터의 특성을 찾아 서술하는 통계학이다. 

◎ 추론통계학(Inferential statistics): 모집단으로부터 추출한 표본집단의 특성(통계량)을 기반으로, 모집단 특성(모수)을 추측해내는 통계학이다.


  • 기술통계학(Descriptive statistics)과 추론통계학(Inferential statistics)은 별개의 것이 아니며, 서로 연결되어 순차적으로 진행된다.
  • 데이터를 분석하는 과정은 연구설계부터 자료수집, 자료 정리, 자료해석을 통해 모집단 또는 표본집단의 특성을 파악하는 기술통계학을 우선 실시한다.
  • 표본을 대상으로 한 경우 표본에서 얻어진 통계량을 기초로 추론통계학을 실시해 모집단의 특성인 모수를 추정하게 된다.
  • 즉, 기술통계량은 모집단, 표본집단 모두를 대상으로, 데이터의 특성(모수, 통계량)을 찾아내고, 대상 집단이 표본집단인 경우 추론통계학을 실시하여, 모수를 추정하게 된다.

 

  • 기술통계학과 추론통계학의 예시)
    • 기술통계학
      우리나라 남성들의 평균 키를 알기 위해, 모집단인 우리나라의 모든 남성들의 신장 Data를 수집하거나, 이는 비효율적이므로 일부를 표본집단으로부터 신장 Data를 추출하여 표본집단의 평균 키나 키의 표준편차를 구하여, 데이터의 특성을 파악한다.
    • 추론통계학
      표본집단에서 구해진 통계량인 평균 키, 키의 표준편차를 기반으로 모집단인 우리나라 모든 남성들의 평균 키(모수)를 추정한다.

 

 

 

 

4. 모수통계학과 비모수통계학


◎ 모수통계학(Parametric statistics): 모집단의 분포에 대한 가정이 필요하며, 연속형 척도를 대상으로 한다.

◎ 비모수통계학(nonParametric statistics): 모집단에 대한 가정이 필요하지 않으며, 질적 자료나 양적 데이터라 할지라도 빈도수와 같은 비연속적인 데이터를 대상으로 한다.


  • 모수통계학은 대상 집단의 모집단이 정규분포와 같은 분포를 따른다는 가정하에 진행된다.
  • 즉, 연구자가 관심 있는 대상인 모집단의 분포 모양이 정규분포의 형태를 그리면서, 연속형 데이터를 대상으로 할 때, 모수통계학을 사용하고, 그 외의 기법들은 비모수통계학이라고 생각하면 된다.
  • 추론통계학에서는 주로 비모수통계학보다 모수통계학을 사용하는데, 이는 모수통계학이 모수 추정에 있어 더 신뢰도가 높기 때문이다.
  • 그러나, 모집단에 대한 정보가 전혀 없거나 부정확하여, 모수통계학의 가정을 만족시키지 못한 상태라면 비모수통계학의 신뢰도가 더 높다.

 

  • 비모수통계학의 특징
    • 분포 무관(Distribution-free) 검정법이라고도 불리며, 말 그대로 모집단의 분포에 상관없이 사용할 수 있다.
    • 범주형 척도 같은 비연속성 데이터라 할지라도 분석할 수 있다.
    • 계산 방법이 단순하여 빠르고 쉽게 통계량을 구할 수 있으며, 결과에 대한 해석과 이해가 쉽다.
    • 표본을 많이 추출하기 어려운 경우에도 사용할 수 있다.
728x90
반응형

'Python으로 하는 기초통계학 > 기본 개념' 카테고리의 다른 글

중심경향치(1) - 최빈값, 중앙값  (0) 2021.03.03
도수분포표와 시각화  (0) 2021.03.02
도수분포표  (0) 2021.03.02
통계 분석을 위한 데이터 준비  (0) 2021.03.01
변수(Variable)  (0) 2021.03.01
728x90
반응형

영인자(Zero Divisor)

  • $A \neq O,\ B \neq O,\ AB = O$
  • $ A \neq O,\ A^2 = O$
  • 행렬 $A$와 행렬 $B$가 영행렬이 아님에도 불구하고, 행렬 $AB$를 행렬곱하였을 때, 영행렬이 나오는 경우
  • 위에서 보듯 $A$는 제곱하였을 때, 영행렬이 나왔다. 영인자의 존재로 인해 행렬에서는 방정식의 근, 지수법칙을 사용할 수 없다.
  • 고등학교 행렬 문제에서 영인자의 존재는 수많은 반례를 가지고 오므로, 요주의 대상이다.

 

 

1. 영인자의 곱 순서

$$AB = O\ \overset{F}{\rightarrow} BA = O$$

$$ AB = O\ \overset{F}{\rightarrow} BA \neq O $$

  • 영인자는 특정한 배열의 곱에서만 영행렬이 된다.
  • 물론, 예외 역시 존재하기 때문에 $AB = BA = O$이 되는 경우도 존재한다.
>>> mat1 = np.array([[0, 0],[2, -2]])
>>> mat2 = np.array([[1, 0],[1, 0]])
>>> np.dot(mat1, mat2)
array([[0, 0],
       [0, 0]])
       
>>> np.dot(mat2, mat1)
array([[0, 0],
       [0, 0]])

 

 

 

 

2. 영인자는 역행렬을 가지지 않는다.

2.1. 증명

  • 다음과 같은 정사각행렬 $A$가 있다고 하자.
  • $ A \neq O \rightarrow A^2 = O $
  • 위 조건을 만족하는 행렬 $A$는 영행렬이 아니므로, 영인자이다.
  • 정사각행렬이므로, 케일리 헤밀턴의 정리를 사용해보자
  • $ A^2 - (a+d)A + (ad - bc)E = O $
  • $A^2 = O$이고, $A \neq O,\ E \neq O$이므로, $(ad-bc)E = (a+d)A$가 성립해야한다.
  • 그러나, 단위행렬의 배수는 제곱하여 영행렬이 될 수 없으므로, 영인자인 행렬 $A$는 단위행렬의 배수가 아니다.
  • 그러므로, $(a+b)=0, (ad-bc)=0$이 성립한다.
  • $ad-bc=0$이므로, 역행렬 생성 법칙에 따라, 영인자 $A$는 역행렬을 가질 수 없다.

 

2.2. 케일리 헤밀턴 정리(Cayley–Hamilton theorem)

  • 이차 정사각행렬 $A$에 대하여 케일리 헤밀턴 정리를 사용하면, 행렬의 거듭제곱을 아주 쉽게 구할 수 있다.
  • $A \neq kE$일 때 사용 가능하다(행렬 $A$가 단위행렬의 배수가 아닐 때).

$$ A = \begin{pmatrix}
a & b\\ 
c & d
\end{pmatrix} \neq kE $$

$$ A^2 - (a+d)A + (ad - bc)E = O $$

  • 케일리 헤밀턴 정리 사용 예시

$$A = \begin{pmatrix}
1 & 2\\ 
3 & 4
\end{pmatrix}$$

$$A^2 - 5A -2E = O \rightarrow A^2 = 5A + 2E$$

 

2.3. 영인자와 역행렬 관계

  • 위에서 봤듯이 영인자인 행렬은 역행렬이 존재할 수 없다.
  • 반대로 말하자면, 역행렬이 존재하는 행렬은 영인자가 아니라는 소리다.
  • 만약 행렬 $A$와 $B$가 역행렬이 존재한다면 영인자가 아니라는 의미이므로, 다음 공식이 성립한다.

$$(AB)^2 = A^2B^2 \ \overset{T}{\rightarrow}\ AB=BA$$

$$ABAB = AABB$$

$$A^{-1}ABABB^{-1} = A^{-1}AABBB^{-1}$$

$$BA = AB$$

  • 그러나 행렬은 3차 이상에서부터는 성립하지 않는 경우가 많으므로 위 공식도 주의해야한다.

$$(AB)^3 = A^3B^3 \ \overset{F}{\rightarrow}\ AB=BA$$

$$ABABAB = AAABBB$$

$$A^{-1}ABABABB^{-1} = A^{-1}AAABBBB^{-1}$$

$$BABA = AABB$$

  • $BABA = ABAB$와 $BA = AB$는 다르다.

 

 

 

 

3. 영인자와 지수법칙

  • 영인자의 존재로 인해 행렬에서는 지수법칙을 사용하기가 어렵다.
  • 영인자의 존재로 인해 행렬은 지수에 대하여 다음과 같은 성질을 갖는다.

$$A^n(n\geq 3)\ \overset{F}{\rightarrow}\ A=O$$

$$A^n(n\geq 3)\ \overset{T}{\rightarrow}\ A^2=O$$

  • 영인자의 존재로 인해, 위 명제에서 행렬 $A=O$이라고 할 수 없다.
  • 행렬 $A$가 영인자인 경우 $A^2=O$이므로, 그 이상의 차수에서도 모두 영행렬이 나오게 된다.

 

3.1. 지수법칙이 반드시 성립불가한 것은 아니다.

  • 하나의 행렬에서는 지수법칙이 성립한다.

$$A^m*A^n = A^{m+n},\ (m, n \in N)$$

$$(A^m)^n = A^{mn}$$

  • 그러나, 하나의 행렬이 아닌 경우에는 성립하지 않는다.
  • 이는 교환법칙이 성립하지 않기 때문이다.

$$(AB)^n \neq A^nB^n$$

$$ABABABAB \neq AAAABBBB$$

 

3.2. 영인자와 지수법칙

$$(AB)^n = A^nB^n \overset{F}{\rightarrow} AB = BA$$

  • 영인자의 존재로 인해 위 명제는 성립하지 않는다.

 

3.2.1. 증명

  • $AB = O$로 영인자라고 가정해보자.
  • 영인자의 성질로 인해 $BA \neq O$일 수 있다.

$$(AB)^n = O,\ A^nB^n = AA\cdots AABB\cdots BB = O$$

  • 영인자 AB의 존재로 인해 $(AB)^n = A^nB^n$은 성립하였으나, $AB=BA$는 성립하지 않는다.

 

3.2.2. 역은 성립한다.

$$(AB)^n = A^nB^n \overset{T}{\leftarrow} AB = BA$$

  • $AB = BA$라는 말은 $AB$가 영인자인 경우라 할지라도 $AB=BA=O$이 성립하고, 교환 법칙이 성립할수도 있다는 의미이기 때문이다.
728x90
반응형

'Python으로 하는 기초 수학 > 행렬' 카테고리의 다른 글

연립일차방정식과 가우스 소거법(Gaussian elimination)  (0) 2021.02.26
역행렬(Inverse matrix)  (0) 2021.02.26
행렬의 성질  (0) 2021.02.25
행렬(Matrix)  (0) 2021.02.25
728x90
반응형

행렬의 성질

  • 전제: $M_{(m*n)},\ A \in M,\ B \in M, \ C \in M$

 

 

1. 기본 연산

1.1. 행렬의 덧셈과 뺄셈

  • $A + B \in M$, $A - B \in M$
  • 동형인 행렬끼리만 +, -가 가능하다(행렬은 덧셈 뺄셈에 대하여 닫혀 있다.)
>>> Mat1 = np.arange(0, 15).reshape((3,5))
>>> Mat2 = np.full((3,5), 3)
>>> Mat1 + Mat2
array([[ 3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12],
       [13, 14, 15, 16, 17]])
       
>>> Mat1 - Mat2
array([[-3, -2, -1,  0,  1],
       [ 2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11]])

 

1.2. 행렬의 곱셈

  • $AB^T \notin M$
  • 행렬끼리 곱을 하면 행과 열의 모양이 바뀐다.
  • 행렬끼리 곱을 하려면, 앞의 행렬의 열과 뒤의 행렬의 행의 크기가 동일해야 한다.
  • 위 조건을 만족할 때, 출력된 행렬의 모양은 앞 행렬의 행($l$)과 뒤 행렬의 열($n$)의 모양인 행렬($l*n$)이 나온다.
  • $(l * m) * (m * n) = (l * n) $ 
  • 행렬은 행렬끼리의 곱에 대하여 닫혀있지 않다고 할 수 있으나, 정방 행렬 간의 곱에 대해서는 닫혀 있다고 할 수 있다.
    $m = n,\ AB \in M$
# 행렬 곱 시, 행렬의 모양이 바뀐다.
>>> Mat1 = np.arange(0, 15).reshape((3,5))
>>> Mat2 = np.full((3,5), 3)
>>> np.dot(Mat1, Mat2.T)
array([[ 30,  30,  30],
       [105, 105, 105],
       [180, 180, 180]])
       
# 정방행렬끼리의 곱을 하는 경우, 행렬 모양이 유지된다.
>>> Mat3 = np.arange(0, 9).reshape((3,3))
>>> Mat4 = np.full((3,3), 3)
>>> np.dot(Mat3, Mat4)
array([[ 9,  9,  9],
       [36, 36, 36],
       [63, 63, 63]])

 

 

 

 

2. 결합 법칙

2.1. 덧셈의 결합 법칙

  • $(A+B)+C = A+(B+C)$
  • 행렬의 덧셈과 뺄셈은 각 행렬의 형태가 동일해야 하며, 그 순서를 어떻게 하는지는 상관없다.
>>> Mat1 = np.arange(0, 15).reshape((3,5))
>>> Mat2 = np.repeat(np.array([1,2,3]), 5).reshape((3,5))
>>> Mat3 = np.array([[1,3,5,7,9],[2,4,6,8,10],[3,6,9,12,15]])
>>> (Mat1 + Mat2) + Mat3 == Mat1 + (Mat2 + Mat3)
array([[ True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True]])

 

2.2 곱셈의 결합 법칙

  • $A(B^TC) = (AB^T)C$
>>> Mat1 = np.arange(0, 15).reshape((3,5))
>>> Mat2 = np.array([[1,3],[2,4],[3,6],[4,8],[5,10]])
>>> Mat3 = np.array([[1,3,5,7,9,11,13],[2,4,6,8,10,12,14]])
>>> np.dot(np.dot(Mat1,Mat2),Mat3) == np.dot(Mat1,np.dot(Mat2,Mat3))
array([[ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])

 

 

 

 

3. 항등원(Identity Elementa)

3.1 행렬의 덧셈의 항등원

  • $ A + O = O + A = A$
  • 영행렬은 행렬의 덧셈의 항등원이다.
  • 뺄셈은 부호가 바뀌게 되므로 항등원이 없다.
>>> Mat1 = np.arange(0, 15).reshape((3,5))
>>> Mat2 = np.zeros((3,5))
>>> Mat1 + Mat2 == Mat2 + Mat1
array([[ True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True]])

 

3.2. 행렬의 곱셈의 항등원

  • $AE = EA = A$
  • 모든 정방 행렬 $A$에 대하여 단위행렬 $E$를 곱하면 행렬 $A$가 나온다.
>>> Mat1 = np.arange(0, 16).reshape((4,4))
>>> Mat2 = np.identity(4)
>>> np.dot(Mat1, Mat2) == Mat1
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])
       
>>> Mat1 == np.dot(Mat1, Mat2)
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])

 

 

 

 

4. 역원

4.1. 덧셈에 대한 역원

  • $A+(-A) = (-A) + A = O$
>>> Mat1 = np.arange(0, 12).reshape((4,3))
>>> Mat1 + (-Mat1) == (-Mat1) + Mat1
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])
       
>>> Mat1 + (-Mat1)
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])

 

4.2. 곱셈에 대한 역원

  • $AA^{-1} = A^{-1}A = E$
  • 역행렬을 갖지 않는 경우도 존재하므로, 항상 성립하는 것은 아니다.
  • $AB = BA = E$인 경우 B는 A의 역행렬이다.
>>> Mat = np.array([[0, 1],[2, 3]])
>>> Inv_Mat = np.linalg.inv(Mat)
>>> np.dot(Mat, Inv_Mat)
array([[1., 0.],
       [0., 1.]])

 

4.3. 곱셈에 대한 역원에서 파생된 행렬 성질

  • $A(A+B) = E \Rightarrow AB = BA$

4.3.1. 증명

  • $A(A+B) = E$이므로, $A^{-1}$은 존재한다. $A^{-1} = (A+B)$이므로, 다음 식이 성립한다.

$$A(A + B) = (A + B)A\ \rightarrow \ A^2 + AB = A^2 + BA \ \rightarrow \ AB = BA$$

 

 

 

 

5. 교환 법칙

5.1. 행렬의 교환 법칙은 성립하지 않는다.

  • $AB \neq BA$
  • 교환법칙이 성립하지 않으므로 곱셈법칙, 지수법칙을 적용할 수 없다(항상은 아니며, 가능한 경우도 있으므로, 부분적으로 사용 가능하다).
  • 대우: 곱셈법칙이 성립한다면 $AB = BA$가 성립한다. [거짓]
  • 행렬에서는 대우 명제마저도 성립하지 않을 수 있다.

5.1.1 증명

$$(A+B)^2 = A^2 + 2AB + B^2\ \overset{T}{\rightarrow} \ AB = BA \cdots (1)$$

$$(A+B)^3 =  A^2 + 3A^2B + 3AB^2 + B^3 \ \overset{F}{\rightarrow} \ AB = BA \cdots (2)$$

  • $AB$가 영인자인 경우, $A^2 + 3AAB + 3ABB + B^3 = A^3 + B^3 =  A^2 + 3A^2B + 3AB^2 + B^3$은 성립한다.
  • $AB$는 영인자이므로, $AB=O$은 성립하나, $BA \neq O$이다.
  • 행렬에서는 영인자의 존재로 인해 2차 함수에서 성립하는 것이 3차 함수 이상에서는 성립하지 않을 수 있다.

 

5.2. 교환 법칙 관련 재밌는 공식

  • $A + B = AB$라면 $AB = BA$이다.

5.2.1. 증명

$$A + B = AB \rightarrow AB - A - B = O \rightarrow (A-E)(B-E)-E=O$$

$(A-E)(B-E)=E$이므로, $(A-E)^{-1},\ (B-E)^{-1}$이 존재한다.

$$ (A-E)(B-E)=E=(B-E)(A-E)\rightarrow BA -A-B=O $$

$$ \therefore AB = BA $$

 

 

 

728x90
반응형

+ Recent posts