A A
[Data Mining] Statistics (톡계학)

Describing a Single Set of Data (단일 데이터 μ„ΈνŠΈ)

단일 데이터 μ„ΈνŠΈ(describing a single set of data)λŠ” ν•˜λ‚˜μ˜ 데이터 μ„ΈνŠΈμ— λŒ€ν•œ νŠΉμ„±μ΄λ‚˜ νŠΉμ§ˆμ„ μ„€λͺ…ν•˜κ³  λΆ„μ„ν•˜λŠ” 과정을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • 이λ₯Ό 톡해 λ°μ΄ν„°μ˜ 쀑심 κ²½ν–₯, λΆ„μ‚°, ν˜•νƒœ 및 뢄포 등을 νŒŒμ•…ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 예λ₯Ό 듀어보면, λͺ¨κΈˆ ν™œλ™ λ‹¨μ²΄μ˜ 뢀사μž₯이 νšŒμ›λ“€μ΄ 친ꡬλ₯Ό μ–Όλ§ˆλ‚˜ 가지고 μžˆλŠ”μ§€μ— λŒ€ν•œ μ„€λͺ…을 μš”μ²­ν–ˆμŠ΅λ‹ˆλ‹€.
from collections import Counter
from linear_algebra import sum_of_squares, dot
import math
from operator import add
num_friends = [100,49,41,40,25,21,21,19,19,18,18,16,15,15,15,15,14,14,13,13,13,13,12,12,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
t = Counter(num_friends)
def make_friend_counts_histogram(plt):
    # Counter 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ 각 친ꡬ 수의 λΉˆλ„λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    friend_counts = Counter(num_friends)
    
    # x 좕은 0λΆ€ν„° 100κΉŒμ§€μ˜ μ •μˆ˜λ‘œ μ„€μ •ν•©λ‹ˆλ‹€.
    xs = range(101)
    
    # 친ꡬ μˆ˜μ— λŒ€ν•œ λΉˆλ„λ₯Ό κ°€μ Έμ™€μ„œ ys λ¦¬μŠ€νŠΈμ— μ €μž₯ν•©λ‹ˆλ‹€.
    ys = [friend_counts[x] for x in xs]
    
    # λ§‰λŒ€ κ·Έλž˜ν”„λ₯Ό κ·Έλ¦½λ‹ˆλ‹€.
    plt.bar(xs, ys)
    
    # x μΆ•κ³Ό y μΆ•μ˜ λ²”μœ„λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
    plt.axis([0, 101, 0, 25])
    
    # κ·Έλž˜ν”„μ˜ 제λͺ©μ„ μ„€μ •ν•©λ‹ˆλ‹€.
    plt.title("Histogram of Friend Counts")
    
    # x μΆ•μ˜ λ ˆμ΄λΈ”μ„ μ„€μ •ν•©λ‹ˆλ‹€.
    plt.xlabel("# of friends")
    
    # y μΆ•μ˜ λ ˆμ΄λΈ”μ„ μ„€μ •ν•©λ‹ˆλ‹€.
    plt.ylabel("# of people")
    
    # κ·Έλž˜ν”„λ₯Ό 화면에 ν‘œμ‹œν•©λ‹ˆλ‹€.
    plt.show()
import matplotlib.pyplot as plt
make_friend_counts_histogram(plt)
  • μœ„μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ•„λž˜ 결과의 κ·Έλž˜ν”„κ°€ λ‚˜μ˜΅λ‹ˆλ‹€.

  • μ•„μ‰½κ²Œλ„, μ΄μ°¨νŠΈλŠ” 결과와 데이터λ₯Ό ꡬ체적으둜 보여쀀닀고 ν•˜κΈ°μ—” μ–΄λ ΅μŠ΅λ‹ˆλ‹€.
  • κ·Έλž˜μ„œ λͺ‡κ°€μ§€ 톡계값을 ν•œλ²ˆ λ§Œλ“€μ–΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.
  • 제일 λ¨Όμ € λ§Œλ“€μ–΄ λ³΄λŠ” 톡계값은 κ°„λ‹¨ν•œ 데이터 포인트의 μˆ˜μž…λ‹ˆλ‹€.

Min, Max, Smallest, Largest

데이터 포인트의 수λ₯Ό κ³„μ‚°ν•˜κ³ , μ΅œλŒ€κ°’ & μ΅œμ†Œκ°’μ„ 찾으며, μ •λ ¬λœ κ°’μ—μ„œ 두 번째둜 μž‘μ€ κ°’κ³Ό 두 번째둜 큰 값을 μ°ΎλŠ” λ“±μ˜ 톡계λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 이λ₯Ό 좜λ ₯ν•˜μ—¬ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

num_points = len(num_friends)               # 204

largest_value = max(num_friends)            # 100
smallest_value = min(num_friends)           # 1

sorted_values = sorted(num_friends)
smallest_value = sorted_values[0]           # 1
second_smallest_value = sorted_values[1]    # 1
second_largest_value = sorted_values[-2]    # 49

print("num_points", len(num_friends))
print("largest value", max(num_friends))
print("smallest value", min(num_friends))
print("second_smallest_value", sorted_values[1])
print("second_largest_value", sorted_values[-2])
num_points 204
largest value 100
smallest value 1
second_smallest_value 1
second_largest_value 49

 

Numpy Version

import numpy as np

num_friends = np.array(num_friends)

num_points = num_friends.shape[0]              # 204

largest_value = np.max(num_friends)            # 100
smallest_value = np.min(num_friends)           # 1

sorted_values = np.sort(num_friends)
smallest_value = sorted_values[0]           # 1
second_smallest_value = sorted_values[1]    # 1
second_largest_value = sorted_values[-2]    # 49

print("num_points", len(num_friends))
print("largest value", max(num_friends))
print("smallest value", min(num_friends))
print("second_smallest_value", sorted_values[1])
print("second_largest_value", sorted_values[-2])

num_friends = list(num_friends)
num_points 204
largest value 100
smallest value 1
second_smallest_value 1
second_largest_value 49
  • NumPyλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό λ°°μ—΄λ‘œ λ³€ν™˜ν•˜κ³ , λ°°μ—΄μ˜ ν˜•νƒœλ₯Ό ν™•μΈν•˜λ©°, μ΅œλŒ“κ°’κ³Ό μ΅œμ†Ÿκ°’μ„ κ³„μ‚°ν•˜κ³ , 배열을 μ •λ ¬ν•˜μ—¬ κ·Έ 쀑 μž‘μ€ κ°’κ³Ό 큰 κ°’ 등을 μ°ΎμŠ΅λ‹ˆλ‹€. 그리고 좜λ ₯ν•˜μ—¬ 확인 ν›„. λ§ˆμ§€λ§‰μœΌλ‘œ, 배열을 λ‹€μ‹œ 리슀트둜 λ³€ν™˜ν•©λ‹ˆλ‹€.

쀑심 κ²½ν–₯μ„±(Central Tendencies)

쀑심 κ²½ν–₯μ„±(Central Tendencies)은 데이터 μ„ΈνŠΈμ—μ„œ 데이터 값듀이 λͺ¨μ—¬ μžˆλŠ” κ²½ν–₯을 λ‚˜νƒ€λ‚΄λŠ” μΈ‘μ •μΉ˜μž…λ‹ˆλ‹€.
μ΄λŠ” 데이터λ₯Ό λŒ€ν‘œν•˜λŠ” 값을 μ œκ³΅ν•˜μ—¬ λ°μ΄ν„°μ˜ 쀑심을 μ΄ν•΄ν•˜λŠ” 데 도움을 μ€λ‹ˆλ‹€.
  • 쀑심 κ²½ν–₯성을 λ‚˜νƒ€λ‚΄λŠ” μ£Όμš” ν†΅κ³„λŸ‰μ—λŠ” 평균(mean), 쀑앙값(median), μ΅œλΉˆκ°’(mode)이 μžˆμŠ΅λ‹ˆλ‹€.
  • median은 λ°μ΄ν„°μ˜ λͺ¨λ“  값에 μ˜μ‘΄ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, κ°€μž₯ 큰 점수λ₯Ό 더 크게 λ§Œλ“€κ±°λ‚˜ (λ˜λŠ” κ°€μž₯ μž‘μ€ 점수λ₯Ό 더 μž‘κ²Œ λ§Œλ“€λ©΄), 쀑간 μ μˆ˜λŠ” λ³€κ²½λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • mean은 λ°μ΄ν„°μ˜ μ΄μƒμΉ˜μ— 맀우 λ―Όκ°ν•©λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, 우리 μΉœκ΅¬κ°€ 100λͺ…이 μ•„λ‹Œ 200λͺ…μ˜ 친ꡬλ₯Ό κ°€μ‘Œλ‹€λ©΄, mean은 7.82둜 μƒμŠΉν•˜μ§€λ§Œ, median은 κ·ΈλŒ€λ‘œ μœ μ§€λ©λ‹ˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, 1980λ…„λŒ€ μ€‘λ°˜μ— λ…ΈμŠ€μΊλ‘€λΌμ΄λ‚˜ λŒ€ν•™μ—μ„œ κ°€μž₯ 높은 평균 μ΄ˆλ΄‰μ„ 가진 전곡은 μ§€λ¦¬ν•™μ΄μ—ˆλ‹€κ³  자주 μ–ΈκΈ‰λ©λ‹ˆλ‹€. μ΄λŠ” 주둜 NBA μŠ€νƒ€μ΄μž μ΄μƒμΉ˜μΈ 마이클 쑰던 λ•Œλ¬Έμ΄μ—ˆμŠ΅λ‹ˆλ‹€.
  • median의 μΌλ°˜ν™”λœ ν˜•νƒœλŠ” quantile둜, νŠΉμ • λ°±λΆ„μœ„μˆ˜μ˜ 데이터가 κ·Έ 값보닀 μž‘λ‹€λŠ” 것을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. (median은 λ°μ΄ν„°μ˜ 50%κ°€ κ·Έ 값보닀 μž‘λ‹€λŠ” 것을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.)
  • mode: κ°€μž₯ ν”ν•œ 값을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
λ§Œμ•½, 쀑심경ν–₯μ„± → Outlier(결츑치)에 있으면 λˆ„κ°€ λ―Όκ°ν•˜κ²Œ λ°˜μ‘ν• κΉŒμš”? (Mean: 평균값이 κ°•ν•˜κ²Œ λ°˜μ‘ν•©λ‹ˆλ‹€)

 

 

mean(평균), median(쀑간), quantile(제일 μž‘μ€κ°’ ~ 제일 큰값), mode(μ΅œλΉˆκ°’)

데이터 집합에 λŒ€ν•œ 평균(mean), 쀑앙값(median), λ°±λΆ„μœ„μˆ˜(quantile), μ΅œλΉˆκ°’(mode)을 κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜λ“€μ„ μ •μ˜ν•©λ‹ˆλ‹€.
각 ν•¨μˆ˜λŠ” 주어진 리슀트의 톡계적 νŠΉμ„±μ„ κ³„μ‚°ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.
def mean(x):
    # 리슀트 x의 평균을 κ³„μ‚°ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.
    return sum(x) / len(x)

def median(v):
    """v의 '쀑앙값'을 μ°ΎμŠ΅λ‹ˆλ‹€."""
    n = len(v)
    sorted_v = sorted(v)  # vλ₯Ό μ •λ ¬ν•©λ‹ˆλ‹€.
    midpoint = n // 2  # 쀑앙 지점을 κ³„μ‚°ν•©λ‹ˆλ‹€.

    if n % 2 == 1:
        # λ§Œμ•½ 리슀트의 길이가 ν™€μˆ˜λΌλ©΄, μ€‘μ•™μ˜ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
        return sorted_v[midpoint]
    else:
        # 짝수라면, 쀑앙에 μœ„μΉ˜ν•œ 두 κ°’μ˜ 평균을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
        lo = midpoint - 1
        hi = midpoint
        return (sorted_v[lo] + sorted_v[hi]) / 2

def quantile(x, p):
    """x의 p번째 λ°±λΆ„μœ„μˆ˜ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€."""
    p_index = int(p * len(x))  # λ°±λΆ„μœ„μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 인덱슀λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    return sorted(x)[p_index]  # xλ₯Ό μ •λ ¬ν•˜κ³ , ν•΄λ‹Ή 인덱슀의 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

def mode(x):
    """λ¦¬μŠ€νŠΈμ—μ„œ κ°€μž₯ 많이 λ‚˜νƒ€λ‚˜λŠ” 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€. μ—¬λŸ¬ 개일 경우 리슀트둜 λ°˜ν™˜λ©λ‹ˆλ‹€."""
    from collections import Counter  # Counterλ₯Ό μ‚¬μš©ν•˜μ—¬ 각 κ°’μ˜ λΉˆλ„λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    counts = Counter(x)
    max_count = max(counts.values())  # κ°€μž₯ 높은 λΉˆλ„λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.
    return [x_i for x_i, count in counts.items()
            if count == max_count]  # κ°€μž₯ 높은 λΉˆλ„λ₯Ό 가진 값듀을 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
print("mean(num_friends)", mean(num_friends))
print("median(num_friends)", median(num_friends))
print("quantile(num_friends, 0.10)", quantile(num_friends, 0.10))
print("quantile(num_friends, 0.25)", quantile(num_friends, 0.25))
print("quantile(num_friends, 0.75)", quantile(num_friends, 0.75))
print("quantile(num_friends, 0.90)", quantile(num_friends, 0.90))
print("mode(num_friends)", mode(num_friends))
mean(num_friends) 7.333333333333333
median(num_friends) 6.0
quantile(num_friends, 0.10) 1
quantile(num_friends, 0.25) 3
quantile(num_friends, 0.75) 9
quantile(num_friends, 0.90) 13
mode(num_friends) [6, 1]

 

num_friends 리슀트의 λͺ¨λ“  μš”μ†Œλ₯Ό λ³΅μ‚¬ν•˜μ—¬ num_friends_2λΌλŠ” μƒˆλ‘œμš΄ λ¦¬μŠ€νŠΈμ— ν• λ‹Ήν•©λ‹ˆλ‹€.
[:]λŠ” 리슀트의 μ‹œμž‘λΆ€ν„° λκΉŒμ§€ λͺ¨λ“  μš”μ†Œλ₯Ό μ„ νƒν•˜λŠ” μŠ¬λΌμ΄μ‹±(slicing) μ—°μ‚°μžμž…λ‹ˆλ‹€.
  • λ”°λΌμ„œ, μ΄λŠ” num_friends 리슀트의 κΉŠμ€ 볡사(deep copy)λ₯Ό μƒμ„±ν•˜λŠ” 방법 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.
num_friends_2 = num_friends[:] # 
mean(num_friends_2) # 평균

# Result: 7.333333333333333
median(num_friends_2) # 쀑간값

# Result: 6.0
num_friends_2[0] = 200
75900 * 1300 // 10000 # 75900 x 1300ν›„ λ‚˜λˆ„κΈ° 10000
# Result: 9867
  • num_friends_2[0] = 200 이 μ½”λ“œλŠ” num_friends_2 리슀트의 첫 번째 μš”μ†Œ(인덱슀 0에 μœ„μΉ˜ν•œ μš”μ†Œ)의 값을 200으둜 λ³€κ²½ν•©λ‹ˆλ‹€.
  • λ§Œμ•½ num_friends_2 λ¦¬μŠ€νŠΈκ°€ [10, 20, 30, 40]와 같이 μ •μ˜λ˜μ—ˆλ‹€λ©΄, 이 μ½”λ“œλ₯Ό μ‹€ν–‰ν•œ ν›„ num_friends_2의 λ‚΄μš©μ€ [200, 20, 30, 40]으둜 λ³€κ²½λ©λ‹ˆλ‹€.
  • μ΄λŠ” 리슀트 λ‚΄ νŠΉμ • μœ„μΉ˜μ— μžˆλŠ” 값을 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ μ—…λ°μ΄νŠΈν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

 

 

Numpy Version

Numpy 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ num_friends 데이터셋에 λŒ€ν•œ 기초 톡계λ₯Ό κ³„μ‚°ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€.
  • np.quantile ν•¨μˆ˜λŠ” Numpy 버전 1.16λΆ€ν„° μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • np.percentile ν•¨μˆ˜λŠ” λΉ„μœ¨ λŒ€μ‹  νΌμ„ΌνŠΈλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
import numpy as np

# λ°μ΄ν„°μ…‹μ˜ 평균을 κ³„μ‚°ν•©λ‹ˆλ‹€.
print("mean(num_friends)", np.mean(num_friends))

# λ°μ΄ν„°μ…‹μ˜ 쀑앙값을 κ³„μ‚°ν•©λ‹ˆλ‹€. 데이터가 ν™€μˆ˜λΌλ©΄ μ€‘μ•™μ˜ κ°’, 짝수라면 쀑앙에 μžˆλŠ” 두 κ°’μ˜ 평균을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
print("median(num_friends)", np.median(num_friends))

# λ°μ΄ν„°μ…‹μ˜ 10%에 ν•΄λ‹Ήν•˜λŠ” λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. 즉, 데이터λ₯Ό μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν–ˆμ„ λ•Œ ν•˜μœ„ 10%λ₯Ό μ°¨μ§€ν•˜λŠ” κ°’μž…λ‹ˆλ‹€.
print("quantile(num_friends, 0.10)", np.percentile(num_friends, 10))

# λ°μ΄ν„°μ…‹μ˜ 25%에 ν•΄λ‹Ήν•˜λŠ” λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. 이λ₯Ό 1μ‚¬λΆ„μœ„μˆ˜ λ˜λŠ” ν•˜μœ„ 25% 경계값이라고 ν•©λ‹ˆλ‹€.
print("quantile(num_friends, 0.25)", np.percentile(num_friends, 25))

# λ°μ΄ν„°μ…‹μ˜ 75%에 ν•΄λ‹Ήν•˜λŠ” λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. 이λ₯Ό 3μ‚¬λΆ„μœ„μˆ˜ λ˜λŠ” μƒμœ„ 25% 경계값이라고 ν•©λ‹ˆλ‹€.
print("quantile(num_friends, 0.75)", np.percentile(num_friends, 75))

# λ°μ΄ν„°μ…‹μ˜ 90%에 ν•΄λ‹Ήν•˜λŠ” λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. 즉, 데이터λ₯Ό μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν–ˆμ„ λ•Œ ν•˜μœ„ 90%λ₯Ό μ°¨μ§€ν•˜λŠ” κ°’μž…λ‹ˆλ‹€.
print("quantile(num_friends, 0.90)", np.percentile(num_friends, 90))
mean(num_friends) 7.333333333333333
median(num_friends) 6.0
quantile(num_friends, 0.10) 1.0
quantile(num_friends, 0.25) 3.0
quantile(num_friends, 0.75) 9.0
quantile(num_friends, 0.90) 13.0

 

import numpy as np

np.percentile(np.array([0,1,2,3,4,5,100]), [75, 50, 25])

# Result: array([4.5, 3. , 1.5])
  • Numpy의 np.percentile ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 주어진 λ°°μ—΄ [0, 1, 2, 3, 4, 5, 100]의 75번째, 50번째(쀑앙값), 그리고 25번째 λ°±λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • 이 ν•¨μˆ˜λŠ” 데이터λ₯Ό μ •λ ¬ν•œ ν›„ μ§€μ •λœ λ°±λΆ„μœ„μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 데이터 포인트 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

import numpy as np
from scipy import stats

array = np.array([1, 2, 2, 3, 4, 4, 5])

# stats.mode ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°°μ—΄μ˜ μ΅œλΉˆκ°’(mode)을 κ³„μ‚°ν•©λ‹ˆλ‹€. 
# 이 ν•¨μˆ˜λŠ” μ΅œλΉˆκ°’κ³Ό κ·Έ λΉˆλ„λ₯Ό λͺ¨λ‘ λ°˜ν™˜ν•©λ‹ˆλ‹€.
mode = stats.mode(array)

# μ΅œλΉˆκ°’λ§Œ 좜λ ₯ν•©λ‹ˆλ‹€. mode[0]은 μ΅œλΉˆκ°’μ„, mode[1]은 ν•΄λ‹Ή μ΅œλΉˆκ°’μ˜ λΉˆλ„λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
# μ—¬κΈ°μ„œλŠ” μ΅œλΉˆκ°’λ§Œ ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— mode[0]λ§Œμ„ 좜λ ₯ν•©λ‹ˆλ‹€.
print(mode[0])

# Result: [2]
  • [1, 2, 2, 3, 4, 4, 5] λ°°μ—΄μ—μ„œ κ°€μž₯ 자주 λ‚˜νƒ€λ‚˜λŠ” 값을 μ°Ύκ³  κ·Έ 값을 좜λ ₯ν•©λ‹ˆλ‹€.
  • stats.mode ν•¨μˆ˜λŠ” μ΅œλΉˆκ°’κ³Ό ν•΄λ‹Ή μ΅œλΉˆκ°’μ˜ λΉˆλ„λ₯Ό λ°˜ν™˜ν•˜λŠ”λ°, μ—¬κΈ°μ„œλŠ” μ΅œλΉˆκ°’μΈ 2λ§Œμ„ 좜λ ₯ν•©λ‹ˆλ‹€.
  • λ§Œμ•½ λ°°μ—΄μ—μ„œ μ—¬λŸ¬ 개의 μ΅œλΉˆκ°’μ΄ λ™μΌν•œ λΉˆλ„λ‘œ λ‚˜νƒ€λ‚œλ‹€λ©΄, stats.mode ν•¨μˆ˜λŠ” κ°€μž₯ μž‘μ€ 값을 μ΅œλΉˆκ°’μœΌλ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

import numpy as np

# 배열을 μƒμ„±ν•©λ‹ˆλ‹€.
array = np.array([1,2,2,3,4,4,5])

# np.uniqueλ₯Ό μ‚¬μš©ν•˜μ—¬ λ°°μ—΄ λ‚΄μ˜ κ³ μœ ν•œ κ°’λ“€(vals)κ³Ό 각 κ°’μ˜ λ“±μž₯ 횟수(counts)λ₯Ό λ°˜ν™˜λ°›μŠ΅λ‹ˆλ‹€.
vals, counts = np.unique(array, return_counts=True)

# counts λ°°μ—΄μ—μ„œ κ°€μž₯ 큰 값을 μ°ΎμŠ΅λ‹ˆλ‹€. 이 값은 λ°°μ—΄ λ‚΄μ—μ„œ κ°€μž₯ 많이 λ“±μž₯ν•˜λŠ” μ›μ†Œμ˜ λ“±μž₯ νšŸμˆ˜μž…λ‹ˆλ‹€.
max_val = np.max(counts)

# counts == max_val은 counts λ°°μ—΄μ—μ„œ max_valκ³Ό 같은 값을 κ°€μ§€λŠ” μ›μ†Œμ˜ μœ„μΉ˜λ₯Ό λΆˆλ¦¬μ–Έ λ°°μ—΄λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
# 이 λΆˆλ¦¬μ–Έ 배열을 μ΄μš©ν•˜μ—¬ vals λ°°μ—΄μ—μ„œ 쑰건을 λ§Œμ‘±ν•˜λŠ” μ›μ†Œλ“€λ§Œμ„ μ„ νƒν•©λ‹ˆλ‹€.
# 결과적으둜, κ°€μž₯ 많이 λ“±μž₯ν•˜λŠ” μ›μ†Œλ“€μ΄ λ°˜ν™˜λ©λ‹ˆλ‹€. λ§Œμ•½ μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬ 개라면, κ·Έ λͺ¨λ“  값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
mode_vals = vals[counts == max_val]

# μ΅œλΉˆκ°’(λ“€)을 좜λ ₯ν•©λ‹ˆλ‹€.
print(mode_vals)

# Result: array([2, 4])
  • λ°°μ—΄ [1,2,2,3,4,4,5]μ—μ„œ 2와 4κ°€ 각각 두 λ²ˆμ”© λ“±μž₯ν•˜μ—¬ κ°€μž₯ 많이 λ“±μž₯ν•˜λŠ” κ°’μž„μ„ ν™•μΈν•˜κ³ , 두 값을 λͺ¨λ‘ λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • 이 방법은 μ—¬λŸ¬ μ΅œλΉˆκ°’μ„ 찾을 λ•Œ μœ μš©ν•˜λ©°, SciPy 라이브러리λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  순수 Numpy둜만 κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.

Dispersion(λΆ„μ‚°)

λΆ„μ‚°(Dispersion)은 데이터 값듀이 ν‰κ· μ΄λ‚˜ 쀑앙값과 μ–Όλ§ˆλ‚˜ λ–¨μ–΄μ Έ μžˆλŠ”μ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μΈ‘μ •μΉ˜μž…λ‹ˆλ‹€.
  • 뢄산은 λ°μ΄ν„°μ˜ 변동성을 μ΄ν•΄ν•˜λŠ” 데 μ€‘μš”ν•˜λ©°, 데이터λ₯Ό μš”μ•½ν•˜κ³  비ꡐ할 λ•Œ 쀑심 κ²½ν–₯μ„± 외에도 μ€‘μš”ν•œ 정보λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.
  • μ£Όμš”ν•œ λΆ„μ‚° μΈ‘μ •μΉ˜λ‘œλŠ” λ²”μœ„(Range), λΆ„μ‚°(Variance), ν‘œμ€€νŽΈμ°¨(Standard Deviation), μ‚¬λΆ„μœ„μˆ˜ λ²”μœ„(Interquartile Range, IQR) 등이 μžˆμŠ΅λ‹ˆλ‹€.

 

  • Dispersion(λΆ„μ‚°)은 데이터가 μ–Όλ§ˆλ‚˜ 퍼져 μžˆλŠ”μ§€ μΈ‘μ •ν•˜λŠ” 것을 λ§ν•©λ‹ˆλ‹€.
  • Range(λ²”μœ„)λŠ” κ°€μž₯ 큰 μš”μ†Œμ™€ κ°€μž₯ μž‘μ€ μš”μ†Œμ˜ 차이일 λΏμž…λ‹ˆλ‹€ → μ΅œμ†Œ, μ΅œλŒ€κ°’μ˜ 차이
  • Variance, Standard deviation(ν‘œμ€€νŽΈμ°¨)
  • Range(λ²”μœ„)와 Standard deviation(ν‘œμ€€νŽΈμ°¨) λͺ¨λ‘ Outlier λ¬Έμ œκ°€ λ™μΌν•©λ‹ˆλ‹€
  • μ‚¬λΆ„μœ„μˆ˜_λ²”μœ„(Interquartile_range): 75번째 λ°±λΆ„μœ„μˆ˜ κ°’κ³Ό 25번째 λ°±λΆ„μœ„μˆ˜ κ°’μ˜ 차이λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

 

# "range"λΌλŠ” 이름은 Pythonμ—μ„œ 이미 λ‹€λ₯Έ 의미둜 μ‚¬μš©λ˜λ―€λ‘œ λ‹€λ₯Έ 이름을 μ‚¬μš©ν•©λ‹ˆλ‹€.
def data_range(x):
    # 데이터 집합 x의 μ΅œλŒ€κ°’κ³Ό μ΅œμ†Œκ°’μ˜ 차이λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    return max(x) - min(x)

def de_mean(x):
    # 데이터 집합 x의 각 μ›μ†Œμ—μ„œ x의 평균을 λΊ€ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    # κ·Έ 결과둜 λ°˜ν™˜λœ 데이터 μ§‘ν•©μ˜ 평균은 0이 λ©λ‹ˆλ‹€.
    x_bar = sum(x) / len(x)
    return [x_i - x_bar for x_i in x]

def variance(x):
    # 데이터 집합 x의 뢄산을 κ³„μ‚°ν•©λ‹ˆλ‹€.
    # 뢄산은 데이터가 ν‰κ· μœΌλ‘œλΆ€ν„° μ–Όλ§ˆλ‚˜ 퍼져 μžˆλŠ”μ§€λ₯Ό μΈ‘μ •ν•©λ‹ˆλ‹€.
    n = len(x)
    deviations = de_mean(x)
    return sum_of_squares(deviations) / (n - 1)

def standard_deviation(x):
    # 데이터 집합 x의 ν‘œμ€€νŽΈμ°¨λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    return math.sqrt(variance(x))

def interquartile_range(x):
    # 데이터 집합 x의 μ‚¬λΆ„μœ„λ²”μœ„(IQR)λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    return quantile(x, 0.75) - quantile(x, 0.25)
print("data_range(num_friends)", data_range(num_friends))
print("variance(num_friends)", variance(num_friends))
print("standard_deviation(num_friends)", standard_deviation(num_friends))
print("interquartile_range(num_friends)", interquartile_range(num_friends))
data_range(num_friends) 99
variance(num_friends) 81.54351395730716
standard_deviation(num_friends) 9.03014473623248
interquartile_range(num_friends) 6

 

Numpy Version

num_friends = np.array(num_friends)  # num_friends 데이터λ₯Ό NumPy λ°°μ—΄λ‘œ λ³€ν™˜

# λ°μ΄ν„°μ˜ μ΅œλŒ“κ°’κ³Ό μ΅œμ†Ÿκ°’μ˜ 차이λ₯Ό 계산 (ptp - λΆ„μ‚°)
print("data_range(num_friends)", np.ptp(num_friends))

# 직접 μ΅œλŒ€κ°’κ³Ό μ΅œμ†Œκ°’μ˜ 차이λ₯Ό κ³„μ‚°ν•˜μ—¬ 데이터 λ²”μœ„λ₯Ό ꡬ함
print("data_range(num_friends)", np.max(num_friends) - np.min(num_friends))

 # λ°μ΄ν„°μ˜ 뢄산을 계산, ddof=1둜 μ„€μ •ν•˜μ—¬ ν‘œλ³Έ 뢄산을 ꡬ함 (var - λΆ„μ‚°)
print("variance(num_friends)", np.var(num_friends, ddof=1))

# λ°μ΄ν„°μ˜ ν‘œμ€€νŽΈμ°¨λ₯Ό 계산, ddof=1둜 μ„€μ •ν•˜μ—¬ ν‘œλ³Έ ν‘œμ€€νŽΈμ°¨λ₯Ό ꡬ함
print("standard_deviation(num_friends)", np.std(num_friends, ddof=1))

# λ°μ΄ν„°μ˜ 75번째 λ°±λΆ„μœ„μˆ˜μ™€ 25번째 λ°±λΆ„μœ„μˆ˜λ₯Ό 계산
q75, q25 = np.percentile(num_friends, [75, 25])

# λ°±λΆ„μœ„μˆ˜ λ²”μœ„, 즉 IQR을 계산
print("interquartile_range(num_friends)", q75 - q25)

# NumPy 배열을 λ‹€μ‹œ 리슀트둜 λ³€ν™˜
num_friends = list(num_friends)
data_range(num_friends) 99
data_range(num_friends) 99
variance(num_friends) 81.54351395730707
standard_deviation(num_friends) 9.030144736232474
interquartile_range(num_friends) 6.0

Boxplot

Boxplot은 λ°μ΄ν„°μ˜ 뢄포λ₯Ό μ‹œκ°μ μœΌλ‘œ λ‚˜νƒ€λ‚΄λŠ” λ„κ΅¬λ‘œ, λ°μ΄ν„°μ˜ 쀑심 κ²½ν–₯κ³Ό 뢄산을 λ™μ‹œμ— λ³΄μ—¬μ€λ‹ˆλ‹€.
Boxplot은 λ°μ΄ν„°μ˜ μ£Όμš” ν†΅κ³„λŸ‰μΈ μ΅œμ†Œκ°’, 1μ‚¬λΆ„μœ„μˆ˜(Q1), 쀑앙값(μ€‘μœ„μˆ˜, Median), 3μ‚¬λΆ„μœ„μˆ˜(Q3), μ΅œλŒ€κ°’μ„ λ‚˜νƒ€λ‚΄λ©°, μ΄μƒμΉ˜(outliers)λ₯Ό μ‹œκ°ν™”ν•˜λŠ” 데 μœ μš©ν•©λ‹ˆλ‹€.

import numpy as np
p75, p50, p25 = np.percentile(np.array([0,1,2,3,4,5,100]), [75, 50, 25])
p75, p50, p25
(4.5, 3.0, 1.5)
  • 주어진 λ°°μ—΄ [0,1,2,3,4,5,100]에 λŒ€ν•΄ 75번째 λ°±λΆ„μœ„μˆ˜(p75), 50번째 λ°±λΆ„μœ„μˆ˜(쀑앙값, p50), 25번째 λ°±λΆ„μœ„μˆ˜(p25)λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • np.percentile ν•¨μˆ˜λŠ” μ§€μ •λœ λ°±λΆ„μœ„μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • μœ„ λ°°μ—΄μ—μ„œ, 25번째 λ°±λΆ„μœ„μˆ˜(p25)λŠ” 1κ³Ό 2 μ‚¬μ΄μ˜ κ°’μž…λ‹ˆλ‹€.50번째 λ°±λΆ„μœ„μˆ˜(p50), 즉 쀑앙값은 3μž…λ‹ˆλ‹€.
  • 75번째 λ°±λΆ„μœ„μˆ˜(p75)λŠ” 4와 5 μ‚¬μ΄μ˜ κ°’μž…λ‹ˆλ‹€.

 

np.percentile(np.array([0,1,2,3]),90)

# Result: 2.7

 

  • NumPy의 np.percentile ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 주어진 λ°°μ—΄ [0,1,2,3]의 90번째 λ°±λΆ„μœ„μˆ˜λ₯Ό κ³„μ‚°ν•˜λ©΄, λ°°μ—΄μ˜ 데이터 뢄포λ₯Ό κ³ λ €ν•˜μ—¬ ν•΄λ‹Ή λ°±λΆ„μœ„μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 값을 μ„ ν˜• 보간(linear interpolation) λ°©μ‹μœΌλ‘œ μ°ΎμŠ΅λ‹ˆλ‹€.
  • 이 λ°°μ—΄μ—μ„œ 90번째 λ°±λΆ„μœ„μˆ˜λŠ” 2와 3 사이에 μœ„μΉ˜ν•©λ‹ˆλ‹€. ꡬ체적으둜, 90%에 ν•΄λ‹Ήν•˜λŠ” μœ„μΉ˜λŠ” λ°°μ—΄μ˜ λμ—μ„œ 두 번째 κ°’κ³Ό λ§ˆμ§€λ§‰ κ°’ 사이에 μžˆμœΌλ―€λ‘œ, 2와 3 μ‚¬μ΄μ˜ κ°’μž…λ‹ˆλ‹€.
  • μ„ ν˜• 보간을 μ‚¬μš©ν•˜μ—¬ κ³„μ‚°ν•˜λ©΄, 90번째 λ°±λΆ„μœ„μˆ˜λŠ” λŒ€λž΅μ μœΌλ‘œ 2.7이 λ©λ‹ˆλ‹€. μ΄λŠ” 2와 3 μ‚¬μ΄μ˜ 거리(1)의 90%에 ν•΄λ‹Ήν•˜λŠ” μœ„μΉ˜λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

 

In case of normal distribution (μ •κ·œλΆ„ν¬)

 

uniform vs peaked vs skewed (균일 λŒ€ 정점 λŒ€ λΉ„λŒ€μΉ­)

 

num_friends 데이터셋에 λŒ€ν•œ λ°•μŠ€ ν”Œλ‘―μ„ μƒμ„±ν•©λ‹ˆλ‹€.
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

plt.boxplot(num_friends) # num_friends 데이터셋에 λŒ€ν•œ λ°•μŠ€ ν”Œλ‘―μ„ 생성
plt.show()

 

 

데이터셋을 ν¬ν•¨ν•˜λŠ” 배열을 λ§Œλ“€μ–΄ 이 λ°°μ—΄μ˜ boxplot 그림을 μƒμ„±ν•©λ‹ˆλ‹€.
λ˜ν•œ 같은 데이터셋을 μ„Έ 번 λ°˜λ³΅ν•˜μ—¬ λ°°μ—΄λ‘œ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ μ„Έ 개의 boxplot 그림이 μƒκΉλ‹ˆλ‹€.
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

# 데이터셋을 ν¬ν•¨ν•˜λŠ” 배열을 λ§Œλ“€μ–΄ 이 λ°°μ—΄μ˜ boxplot 그림을 생성
# 같은 데이터셋을 μ„Έ 번 λ°˜λ³΅ν•˜μ—¬ λ°°μ—΄λ‘œ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ μ„Έ 개의 boxplot 그림이 생김
plt.boxplot([num_friends, num_friends, num_friends])
plt.show()

 

Seaborn λΌμ΄λΈŒλŸ¬λ¦¬μ„ μ‚¬μš©ν•˜μ—¬ λ°•μŠ€ν”Œλ‘―μ„ μƒμ„±ν•©λ‹ˆλ‹€.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.boxplot(num_friends) # Seaborn을 μ‚¬μš©ν•˜μ—¬ λ°•μŠ€ν”Œλ‘― 생성
plt.show()

 

 

데이터λ₯Ό 50개의 κ΅¬κ°„μœΌλ‘œ λ‚˜λˆ„μ–΄ 각 ꡬ간에 μ†ν•˜λŠ” λ°μ΄ν„°μ˜ 개수λ₯Ό λ§‰λŒ€λ‘œ ν‘œν˜„ν•©λ‹ˆλ‹€.
# bins=50 μΈμžλŠ” 데이터λ₯Ό 50개의 κ΅¬κ°„μœΌλ‘œ λ‚˜λˆ„μ–΄ 각 ꡬ간에 μ†ν•˜λŠ” λ°μ΄ν„°μ˜ 개수λ₯Ό λ§‰λŒ€λ‘œ ν‘œν˜„
plt.hist(num_friends, bins=50)
plt.show()

 

 

평균 0, ν‘œμ€€νŽΈμ°¨ 1을 가진 μ •κ·œ λΆ„ν¬μ—μ„œ 1000x3 배열을 μƒμ„±ν•©λ‹ˆλ‹€.
이 배열은 1000개의 μƒ˜ν”Œμ„ 각각 가진 3개의 독립적인 데이터 μ„ΈνŠΈ μž…λ‹ˆλ‹€.
data = np.random.randn(1000,3) 
plt.boxplot(data)
plt.show()

 

λ°μ΄ν„°μ˜ 뢄포λ₯Ό 10개의 κ΅¬κ°„μœΌλ‘œ λ‚˜λˆ„μ–΄ 각 ꡬ간에 μ†ν•˜λŠ” μƒ˜ν”Œμ˜ 수λ₯Ό λ§‰λŒ€λ‘œ ν‘œν˜„ν•œ νžˆμŠ€ν† κ·Έλž¨μ„ μƒμ„±ν•©λ‹ˆλ‹€.
이 μ½”λ“œμ—μ„œλŠ” 3개의 데이터 μ„ΈνŠΈμ— λŒ€ν•΄ νžˆμŠ€ν† κ·Έλž¨μ΄ μƒμ„±λ˜λ©°, 각각의 데이터 μ„ΈνŠΈλŠ” λ³„λ„μ˜ λ§‰λŒ€ 그룹으둜 ν‘œμ‹œν•©λ‹ˆλ‹€.
plt.hist(data, bins=10)
plt.show()

 

 

  • λ§Œμ•½ λͺ¨μ§‘λ‹¨μ˜ 평균(μ)을 μ•Œκ³  μžˆλ‹€λ©΄, ν‘œμ€€νŽΈμ°¨(σ)λŠ” λ‹€μŒκ³Ό 같이 κ³„μ‚°λ©λ‹ˆλ‹€.

  • μ—¬κΈ°μ„œ xλŠ” 각 데이터 포인트λ₯Ό λ‚˜νƒ€λ‚΄λ©°, xΛ‰λŠ” ν‘œλ³Έμ˜ 평균이고, n은 데이터 포인트의 μˆ˜μž…λ‹ˆλ‹€.
  • 이 곡식은 λͺ¨λ“  데이터 ν¬μΈνŠΈμ™€ ν‘œλ³Έ 평균 κ°„μ˜ 편차λ₯Ό μ œκ³±ν•œ 값을 λͺ¨λ‘ λ”ν•œ ν›„, 이λ₯Ό 데이터 포인트의 μˆ˜μ—μ„œ 1을 λΊ€ κ°’μœΌλ‘œ λ‚˜λˆ„μ–΄ κ΅¬ν•©λ‹ˆλ‹€.

 

  • λͺ¨μ§‘λ‹¨μ˜ 평균을 μ•Œμ§€ λͺ»ν•˜λŠ” 경우, ν‘œλ³Έ 평균(π‘₯Λ‰)을 μ‚¬μš©ν•˜μ—¬ ν‘œμ€€νŽΈμ°¨(σ)λ₯Ό 계산할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • μ—¬κΈ°μ„œ xλŠ” 각 데이터 포인트λ₯Ό λ‚˜νƒ€λ‚΄λ©°, xΛ‰λŠ” ν‘œλ³Έμ˜ 평균이고, n은 데이터 포인트의 μˆ˜μž…λ‹ˆλ‹€.
  • 이 곡식은 λͺ¨λ“  데이터 ν¬μΈνŠΈμ™€ ν‘œλ³Έ 평균 κ°„μ˜ 편차λ₯Ό μ œκ³±ν•œ 값을 λͺ¨λ‘ λ”ν•œ ν›„, 이λ₯Ό 데이터 포인트의 μˆ˜μ—μ„œ 1을 λΊ€ κ°’μœΌλ‘œ λ‚˜λˆ„μ–΄ κ΅¬ν•©λ‹ˆλ‹€.

 

import numpy as np
print(np.std([1,2,3]))               # λͺ¨μ§‘단 ν‘œμ€€νŽΈμ°¨
print(np.std([1,2,3], ddof=1))       # ν‘œλ³Έ ν‘œμ€€νŽΈμ°¨, ddof=1을 μ„€μ •. ν‘œλ³Έ ν‘œμ€€νŽΈμ°¨λ₯Ό 계산
print(standard_deviation([1,2,3])) # 이 쀄은 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚΄
0.816496580927726
1.0
1.0

Correlation (상관관계)

상관관계(Correlation)λŠ” 두 λ³€μˆ˜ κ°„μ˜ 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 톡계적 μΈ‘μ •μΉ˜λ‘œ, ν•œ λ³€μˆ˜μ˜ λ³€ν™”κ°€ λ‹€λ₯Έ λ³€μˆ˜μ˜ 변화와 μ–΄λ–»κ²Œ κ΄€λ ¨λ˜μ–΄ μžˆλŠ”μ§€λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.
  • μƒκ΄€κ΄€κ³„λŠ” -1κ³Ό 1 μ‚¬μ΄μ˜ 값을 가지며, 이 κ°’μ˜ 크기와 λ°©ν–₯은 λ³€μˆ˜ κ°„μ˜ κ΄€κ³„μ˜ 강도와 λ°©ν–₯을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • μ˜ˆμ‹œλ‘œ μ„€λͺ…을 듀어보면 DataSciences의 μ„±μž₯ λ‹΄λ‹Ή 뢀사μž₯은 μ‚¬λžŒλ“€μ΄ μ‚¬μ΄νŠΈμ—μ„œ λ³΄λ‚΄λŠ” μ‹œκ°„μ΄ μ‚¬μ΄νŠΈμ— μžˆλŠ” 친ꡬ의 μˆ˜μ™€ 관련이 μžˆλ‹€λŠ” 이둠을 가지고 있으며, κ·Έλ…€λŠ” 이λ₯Ό 확인해 쀄 것을 μš”μ²­ν–ˆμŠ΅λ‹ˆλ‹€.
  • 이 두 μ§€ν‘œ(metrics) κ°„μ˜ 관계λ₯Ό μ‘°μ‚¬ν•˜κ³ μž ν•©λ‹ˆλ‹€.
  • Variance(λΆ„μ‚°)은 단일 λ³€μˆ˜κ°€ ν‰κ· μ—μ„œ λ²—μ–΄λ‚˜λŠ” 방법을 μΈ‘μ •ν•˜λŠ” 반면 covariance(곡뢄산)은 두 λ³€μˆ˜κ°€ ν‰κ· μ—μ„œ ν•¨κ»˜ λ³€ν•˜λŠ” 방법을 μΈ‘μ •ν•©λ‹ˆλ‹€.
  • μ •κ·œν™”λ˜μ§€ μ•ŠλŠ” ν•œ "큰" covariance(곡뢄산)이 무엇인지 ν•΄μ„ν•˜κΈ°κ°€ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.
  • 상관관계: covariance(곡뢄산)을 두 λ³€μˆ˜μ˜ standard deviations(ν‘œμ€€ 편차)둜 λ‚˜λˆˆ κ°’μž…λ‹ˆλ‹€.
  • correlation(상관 관계)λŠ” λ‹¨μœ„κ°€ μ—†μœΌλ©° 항상 -1(perfect anti-correlation - μ™„λ²½ν•œ λ°˜μƒκ΄€)κ³Ό 1(perfect correlation - μ™„λ²½ν•œ 상관) 사이에 μžˆμŠ΅λ‹ˆλ‹€.

 

daily_minutes = [1,68.77,51.25,52.08,38.36,44.54,57.13,51.4,41.42,31.22,34.76,54.01,38.79,47.59,49.1,27.66,41.03,36.73,48.65,28.12,46.62,35.57,32.98,35,26.07,23.77,39.73,40.57,31.65,31.21,36.32,20.45,21.93,26.02,27.34,23.49,46.94,30.5,33.8,24.23,21.4,27.94,32.24,40.57,25.07,19.42,22.39,18.42,46.96,23.72,26.41,26.97,36.76,40.32,35.02,29.47,30.2,31,38.11,38.18,36.31,21.03,30.86,36.07,28.66,29.08,37.28,15.28,24.17,22.31,30.17,25.53,19.85,35.37,44.6,17.23,13.47,26.33,35.02,32.09,24.81,19.33,28.77,24.26,31.98,25.73,24.86,16.28,34.51,15.23,39.72,40.8,26.06,35.76,34.76,16.13,44.04,18.03,19.65,32.62,35.59,39.43,14.18,35.24,40.13,41.82,35.45,36.07,43.67,24.61,20.9,21.9,18.79,27.61,27.21,26.61,29.77,20.59,27.53,13.82,33.2,25,33.1,36.65,18.63,14.87,22.2,36.81,25.53,24.62,26.25,18.21,28.08,19.42,29.79,32.8,35.99,28.32,27.79,35.88,29.06,36.28,14.1,36.63,37.49,26.9,18.58,38.48,24.48,18.95,33.55,14.24,29.04,32.51,25.63,22.22,19,32.73,15.16,13.9,27.2,32.01,29.27,33,13.74,20.42,27.32,18.23,35.35,28.48,9.08,24.62,20.12,35.26,19.92,31.02,16.49,12.16,30.7,31.22,34.65,13.13,27.51,33.2,31.57,14.1,33.42,17.44,10.12,24.42,9.82,23.39,30.93,15.03,21.67,31.09,33.29,22.61,26.89,23.48,8.38,27.81,32.35,23.84]
# daily_minutes와 λ‹€λ₯Έ 데이터 μ„ΈνŠΈ κ°„μ˜ 곡뢄산 및 상관관계 계산을 μœ„ν•œ μ½”λ“œ

def covariance(x, y):
    n = len(x)  # x의 길이, 즉 데이터 포인트의 수
    return dot(de_mean(x), de_mean(y)) / (n - 1)  # 곡뢄산 계산

def correlation(x, y):
    stdev_x = standard_deviation(x)  # x의 ν‘œμ€€νŽΈμ°¨ 계산
    stdev_y = standard_deviation(y)  # y의 ν‘œμ€€νŽΈμ°¨ 계산
    if stdev_x > 0 and stdev_y > 0:
        return covariance(x, y) / stdev_x / stdev_y  # 상관관계 계산
    else:
        return 0  # 변동성이 μ—†μœΌλ©΄ μƒκ΄€κ΄€κ³„λŠ” 0
print(covariance(num_friends, daily_minutes))  # 22.43
print(correlation(num_friends, daily_minutes)) # 0.25

# we may conclude that two variables are less correlated
22.425435139573064
0.24736957366478218

 

 

  • de_mean(x): 데이터 집합 xμ—μ„œ 각 데이터 포인트의 κ°’μ—μ„œ 평균 값을 λΉΌμ„œ, 평균이 0이 λ˜λ„λ‘ μ‘°μ •ν•œ μƒˆλ‘œμš΄ 데이터 집합을 μƒμ„±ν•©λ‹ˆλ‹€. μ΄λŠ” x λ°μ΄ν„°μ˜ 쀑심을 μ›μ μœΌλ‘œ μ΄λ™μ‹œν‚€λŠ” νš¨κ³Όκ°€ μžˆμŠ΅λ‹ˆλ‹€.
  • dot(a, b): 두 데이터 집합 a와 bμ—μ„œ 각각 λŒ€μ‘ν•˜λŠ” 데이터 ν¬μΈνŠΈλ“€μ˜ κ³±μ…ˆ κ²°κ³Όλ₯Ό λͺ¨λ‘ λ”ν•˜λŠ” μ—°μ‚°μž…λ‹ˆλ‹€. 즉, a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1]의 합을 κ³„μ‚°ν•©λ‹ˆλ‹€. μ΄λŠ” 두 데이터 집합 μ‚¬μ΄μ˜ μƒν˜Έ μž‘μš©μ„ μˆ˜μΉ˜ν™”ν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€.
  • n: λ°μ΄ν„°μ˜ 개수λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” x λ˜λŠ” y 데이터 μ§‘ν•©μ˜ κΈΈμ΄μž…λ‹ˆλ‹€.
  • / (n - 1): μ΅œμ’…μ μœΌλ‘œ 더해진 값을 n - 1둜 λ‚˜λˆ„μ–΄ μ€λ‹ˆλ‹€. μ΄λŠ” ν‘œλ³Έ 곡뢄산을 계산할 λ•Œ μ‚¬μš©λ˜λŠ” 보정 κ³΅μ‹μ˜ μΌλΆ€λ‘œ, 데이터 μ§‘ν•©μ˜ 크기가 μž‘μ„ λ•Œ λ°œμƒν•  수 μžˆλŠ” 편ν–₯을 μ‘°μ •ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ©λ‹ˆλ‹€.

 

plt.scatter(num_friends, daily_minutes)
plt.xlabel('num_friends')
plt.ylabel('daily_minutes')
plt.title('corr = {:.2}'.format(correlation(num_friends, daily_minutes)))
plt.show()

  • plt.scatter(num_friends, daily_minutes): num_friendsλ₯Ό xμΆ• κ°’μœΌλ‘œ, daily_minutesλ₯Ό yμΆ• κ°’μœΌλ‘œ ν•˜λŠ” 산점도λ₯Ό κ·Έλ¦½λ‹ˆλ‹€.
  • plt.xlabel('num_friends'): x좕에 'num_friends'λΌλŠ” λ ˆμ΄λΈ”μ„ λΆ™μž…λ‹ˆλ‹€.
  • plt.ylabel('daily_minutes'): y좕에 'daily_minutes'λΌλŠ” λ ˆμ΄λΈ”μ„ λΆ™μž…λ‹ˆλ‹€.
  • plt.title('corr = {:.2}'.format(correlation(num_friends, daily_minutes))): 상관관계 값을 κ³„μ‚°ν•˜μ—¬ 제λͺ©μ— 포맷을 μ μš©ν•œ ν›„ 'corr = ' 뒀에 ν‘œμ‹œν•©λ‹ˆλ‹€.
  • {:.2}λŠ” 상관관계 값을 μ†Œμˆ˜μ  두 μžλ¦¬κΉŒμ§€ ν‘œμ‹œν•˜λ„λ‘ ν•©λ‹ˆλ‹€.plt.show(): κ·Έλž˜ν”„λ₯Ό 화면에 ν‘œμ‹œν•©λ‹ˆλ‹€.

 

import matplotlib.pyplot as plt

# μ΄μƒμΉ˜λ₯Ό μ œμ™Έν•œ num_friends와 daily_minutes λ°μ΄ν„°λ‘œ 산점도λ₯Ό κ·Έλ¦½λ‹ˆλ‹€.
plt.scatter(num_friends[1:], daily_minutes[1:])

# x좕에 'num_friends' 라벨을 μΆ”κ°€ν•©λ‹ˆλ‹€.
plt.xlabel('num_friends')
# y좕에 'daily_minutes' 라벨을 μΆ”κ°€ν•©λ‹ˆλ‹€.
plt.ylabel('daily_minutes')

# 제λͺ©μ— μ΄μƒμΉ˜λ₯Ό μ œμ™Έν•œ 데이터λ₯Ό 기반으둜 κ³„μ‚°λœ μƒκ΄€κ³„μˆ˜λ₯Ό ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
# {:.2}λŠ” μƒκ΄€κ³„μˆ˜λ₯Ό μ†Œμˆ˜μ  두 μžλ¦¬κΉŒμ§€ ν‘œμ‹œν•˜λ„λ‘ ν•©λ‹ˆλ‹€.
plt.title('corr = {:.2}'.format(correlation(num_friends[1:], daily_minutes[1:])))

plt.show()

 

 

Correlation (μƒκ΄€κ³„μˆ˜) μΆ”κ°€ μ„€λͺ…

  • μ •ν™•νžˆ –1. μ™„λ²½ν•œ 내리막 (negative) μ„ ν˜• 관계
  • 0.70. κ°•ν•œ 내리막 (negative) μ„ ν˜• 관계
  • 0.50. λ³΄ν†΅μ˜ 내리막 (negative) 관계
  • 0.30. μ•½ν•œ 내리막 (negative) μ„ ν˜• 관계
  • 0. μ„ ν˜• 관계 μ—†μŒ
  • +0.30. μ•½ν•œ 였λ₯΄λ§‰ (positive) μ„ ν˜• 관계
  • +0.50. λ³΄ν†΅μ˜ 였λ₯΄λ§‰ (positive) 관계
  • +0.70. κ°•ν•œ 였λ₯΄λ§‰ (positive) μ„ ν˜• 관계
  • μ •ν™•νžˆ +1. μ™„λ²½ν•œ 였λ₯΄λ§‰ (positive) μ„ ν˜• 관계

Correlation (μƒκ΄€κ³„μˆ˜) vs Cosine μœ μ‚¬μ„±

corr(x, y) = cosine(x - xΜ„, y - yΜ„) → μƒκ΄€κ³„μˆ˜μ™€ 코사인 μœ μ‚¬λ„ μ‚¬μ΄μ˜ 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μˆ˜μ‹μž…λ‹ˆλ‹€.
  • x - xΜ„, y - yΜ„λŠ” 각각 x와 𝑦 λ°μ΄ν„°μ˜ 평균을 λΊ€ κ°’, 즉 "평균 쀑심화(mean-centered)"된 데이터 μž…λ‹ˆλ‹€.
  1. μƒκ΄€κ³„μˆ˜ (Correlation coefficient): μ΄λŠ” 두 λ³€μˆ˜ x와 𝑦 κ°„μ˜ μ„ ν˜• κ΄€κ³„μ˜ 강도와 λ°©ν–₯을 μΈ‘μ •ν•˜λŠ” κ°’μž…λ‹ˆλ‹€.
    • μƒκ΄€κ³„μˆ˜λŠ” -1κ³Ό 1 μ‚¬μ΄μ˜ 값을 가지며, +1은 μ™„λ²½ν•œ μ–‘μ˜ μ„ ν˜• 관계, -1은 μ™„λ²½ν•œ 음의 μ„ ν˜• 관계, 0은 μ„ ν˜• 관계가 μ „ν˜€ μ—†μŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  2. 코사인 μœ μ‚¬λ„ (Cosine similarity): μ΄λŠ” 두 벑터 κ°„μ˜ 코사인 각도λ₯Ό μ΄μš©ν•˜μ—¬ κ³„μ‚°ν•©λ‹ˆλ‹€.
    • 코사인 μœ μ‚¬λ„λŠ” 두 λ²‘ν„°μ˜ λ°©ν–₯이 μ–Όλ§ˆλ‚˜ μœ μ‚¬ν•œμ§€λ₯Ό μΈ‘μ •ν•˜λ©°, μ΄λŠ” λ²‘ν„°μ˜ ν¬κΈ°μ™€λŠ” λ…λ¦½μ μž…λ‹ˆλ‹€. 코사인 μœ μ‚¬λ„λŠ” -1κ³Ό 1 μ‚¬μ΄μ˜ 값을 κ°€μ§‘λ‹ˆλ‹€.
Example: x = (1, 2, 3), y = (2, 4, 6), x - xΜ„ = (-1, 0, 1), y - yΜ„ = (-2, 0, 2)
같은 λ°©ν–₯: 1, λ‹€λ₯Έ λ°©ν–₯: -1. 직각: 0 → Correlation

 

Numpy Version

  • np.covλŠ” 곡뢄산 행렬을 λ°˜ν™˜ν•©λ‹ˆλ‹€: λŒ€κ°μ„ μ€ λ³€μˆ˜μ˜ λΆ„μ‚°μž…λ‹ˆλ‹€.
  • np.corrcoefλŠ” μƒκ΄€κ³„μˆ˜ 행렬을 λ°˜ν™˜ν•©λ‹ˆλ‹€: λŒ€κ°μ„ μ€ 항상 1μž…λ‹ˆλ‹€.
  • 𝑛×𝑛 으둜 곡뢄산 행렬을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.
# NumPy λ°°μ—΄λ‘œ λ³€ν™˜
num_friends = np.array(num_friends)
daily_minutes = np.array(daily_minutes)

# 두 배열을 ν–‰μœΌλ‘œ ν•˜λŠ” 2D λ°°μ—΄ 생성
data = np.array([num_friends, daily_minutes])

# λ°μ΄ν„°μ˜ λͺ¨μ–‘ 좜λ ₯ (2, N) ν˜•νƒœμΌ κ²ƒμž„
print(data.shape)
print()

# 곡뢄산 ν–‰λ ¬ 계산 및 좜λ ₯
# λŒ€κ°μ„  μš”μ†ŒλŠ” 각각의 λ³€μˆ˜μ— λŒ€ν•œ 뢄산을, λΉ„λŒ€κ°μ„  μš”μ†ŒλŠ” 두 λ³€μˆ˜ κ°„μ˜ 곡뢄산을 λ‚˜νƒ€λƒ„
print(np.cov(data))

# μƒκ΄€κ³„μˆ˜ ν–‰λ ¬ 계산 및 좜λ ₯
# λŒ€κ°μ„  μš”μ†ŒλŠ” 1(자기 μžμ‹ κ³Όμ˜ μƒκ΄€κ³„μˆ˜), λΉ„λŒ€κ°μ„  μš”μ†ŒλŠ” 두 λ³€μˆ˜ κ°„μ˜ μƒκ΄€κ³„μˆ˜λ₯Ό λ‚˜νƒ€λƒ„
print(np.corrcoef(data))
print()

# 두 λ³€μˆ˜ κ°„μ˜ μƒκ΄€κ³„μˆ˜λ§Œ 좜λ ₯
print(np.corrcoef(data)[0,1])
print()

# 주석 처리된 λΆ€λΆ„: 각 λ³€μˆ˜μ˜ ν‘œλ³Έ λΆ„μ‚° 계산
# ddof=1은 ν‘œλ³Έ 뢄산을 계산할 λ•Œ μ‚¬μš©λ¨. 기본값은 λͺ¨λΆ„μ‚° 계산
# print(np.var(num_friends, ddof=1))
# print(np.var(daily_minutes, ddof=1))

# NumPy 배열을 λ‹€μ‹œ 리슀트둜 λ³€ν™˜
num_friends = list(num_friends)
daily_minutes = list(daily_minutes)
(2, 204)

[[ 81.54351396  22.42543514]
 [ 22.42543514 100.78589895]]
[[1.         0.24736957]
 [0.24736957 1.        ]]

0.247369573664782
  • μƒκ΄€κ³„μˆ˜μ˜ μ ˆλŒ€κ°’μ΄ 1에 κ°€κΉŒμšΈμˆ˜λ‘ κ°•ν•œ μ„ ν˜• 관계λ₯Ό λ‚˜νƒ€λ‚΄λ©°, 0에 κ°€κΉŒμšΈμˆ˜λ‘ μ„ ν˜• 관계가 μ•½ν•˜κ±°λ‚˜ μ—†μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

Simpson’s Paradox (μ‹¬μŠ¨μ˜ μ—­μ„€)

데이터λ₯Ό 뢄석할 λ•Œ ν•˜λ‚˜μ˜ λ†€λΌμš΄ 점은 μ‹¬μŠ¨μ˜ 역섀인데, 이 μ—­μ„€μ—μ„œ Confusion Matrix (ν˜Όλ™ λ³€μˆ˜)λ₯Ό λ¬΄μ‹œν•˜λ©΄ 상관관계가 μ˜€ν•΄μ˜ μ†Œμ§€κ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

ν•΄μ•ˆ νšŒμ› 수  평균 친ꡬ 수
μ„œλΆ€ ν•΄μ•ˆ 101 8.2
동뢀 ν•΄μ•ˆ 103 6.5

 

  • μ„œλΆ€ ν•΄μ•ˆμ˜ 데이터 κ³Όν•™μžλ“€μ€ 동뢀 ν•΄μ•ˆμ˜ 데이터 κ³Όν•™μžλ“€λ³΄λ‹€ 더 μΉœκ·Όν•˜λ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ™œ κ·ΈλŸ΄κΉŒμš”?
  • 사싀, μΆ”κ°€ λ³€μˆ˜λ₯Ό λ„μž…ν•˜λ©΄ 상관관계가 μ •λ°˜λŒ€ λ°©ν–₯으둜 λ‚˜νƒ€λ‚©λ‹ˆλ‹€!
ν•΄μ•ˆ  ν•™μœ„ νšŒμ› 수  평균 친ꡬ 수
μ„œλΆ€ ν•΄μ•ˆ 박사 35 3.1
동뢀 ν•΄μ•ˆ 박사 70 3.2
μ„œλΆ€ ν•΄μ•ˆ 비박사 66 10.9
동뢀 ν•΄μ•ˆ 비박사 33 13.4
  • 이λ₯Ό ν”Όν•˜λŠ” μœ μΌν•œ 방법은 데이터λ₯Ό 잘 μ•Œκ³ , κ°€λŠ₯ν•œ Confusion(ν˜Όλ™) μš”μΈμ„ ν™•μΈν•˜λ €κ³  λ…Έλ ₯ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
  • λ¬Όλ‘ , 이것이 항상 κ°€λŠ₯ν•œ 것은 μ•„λ‹™λ‹ˆλ‹€.
  • μ‹€μ œ 변동성을 λ°˜μ˜ν•œ 데이터에 λŒ€ν•œ μ‹¬μŠ¨μ˜ μ—­μ„€μ˜ μ‹œκ°ν™”λŠ” μ§„μ •ν•œ 관계λ₯Ό νŒλ‹¨ν•˜λŠ” 것이 μ‹€μ œλ‘œ μ–΄λ €μšΈ 수 μžˆμŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • μ „μ²΄μ μœΌλ‘œλŠ” κ°•ν•œ 뢀정적 상관관계: -0.74
  • κ°œλ³„μ μœΌλ‘œλŠ” κ°•ν•œ 긍정적 상관관계: +0.74, +0.82, +0.75, +0.72, +0.69


Some Other Correlational Caveats (기타 상관관계 μ£Όμ˜μ‚¬ν•­)

상관관계가 0이면 두 λ³€μˆ˜ 사이에 μ„ ν˜• 관계가 μ—†μŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • 관련성이 μžˆμœΌλ‚˜ ν¬μ°©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ (Related but not captured)
  • Correlation(상관 관계) X → but, Correlation(상관 관계)둜 ν™˜μ› κ°€λŠ₯ν•©λ‹ˆλ‹€.
# absolute value relationship
x = [-2, -1, 0, 1, 2]
y = [ 2, 1, 0, 1, 2]
plt.scatter(x, y)
plt.show()

 

상관관계가 μ–Όλ§ˆλ‚˜ μ€‘μš”ν•˜κ±°λ‚˜ μ–Όλ§ˆλ‚˜ ν₯λ―Έλ‘œμš΄κ°€μš”? (How important or how interesting the correlation is?)
# x와 y 데이터λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
x = [-2, -1, 0, 1, 2]
y = [99.98, 99.99, 100, 100.01, 100.02]

# x와 y 데이터λ₯Ό 기반으둜 산점도λ₯Ό κ·Έλ¦½λ‹ˆλ‹€.
plt.scatter(x, y)

# μ‚°μ λ„μ˜ 제λͺ©μ„ μ„€μ •ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ correlation(x,y)λŠ” x와 y μ‚¬μ΄μ˜ 상관관계λ₯Ό κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜λ‘œ,
# 이 ν•¨μˆ˜μ˜ 결과값을 μ†Œμˆ˜μ  λ‘˜μ§Έ μžλ¦¬κΉŒμ§€ λ°˜μ˜¬λ¦Όν•˜μ—¬ 제λͺ©μ— ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
plt.title('corr={:.2}'.format(correlation(x, y)))

plt.show()

 

  • μƒκ΄€κ΄€κ³„λŠ” 두 λ³€μˆ˜μ˜ κ΄€κ³„μ˜ 강도와 λ°©ν–₯을 λ‚˜νƒ€λ‚΄λŠ” μ§€ν‘œλ‘œ, -1λΆ€ν„° 1κΉŒμ§€μ˜ κ°’μœΌλ‘œ ν‘œν˜„λ©λ‹ˆλ‹€.
  • 1에 κ°€κΉŒμšΈμˆ˜λ‘ κ°•ν•œ μ •(+)의 μ„ ν˜• 관계λ₯Ό, -1에 κ°€κΉŒμšΈμˆ˜λ‘ κ°•ν•œ λΆ€(-)의 μ„ ν˜• 관계λ₯Ό, 0에 κ°€κΉŒμšΈμˆ˜λ‘ μ„ ν˜• 관계가 μ•½ν•˜κ±°λ‚˜ μ—†μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
# x와 y 데이터λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. 이 데이터듀은 μ™„λ²½ν•œ μ„ ν˜• 관계λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
x = [-2, -1, 0, 1, 2]
y = [99.98, 99.99, 100, 100.01, 100.02]

# x와 y 데이터λ₯Ό μ΄μš©ν•˜μ—¬ 산점도λ₯Ό κ·Έλ¦½λ‹ˆλ‹€.
plt.scatter(x, y)

# 좕을 λ™λ“±ν•œ λΉ„μœ¨λ‘œ μ„€μ •ν•©λ‹ˆλ‹€. μ΄λŠ” 데이터 κ°„μ˜ 관계λ₯Ό 더 λͺ…ν™•ν•˜κ²Œ 보여주기 μœ„ν•¨μž…λ‹ˆλ‹€.
plt.axis('equal')

# κ·Έλž˜ν”„μ˜ 제λͺ©μ— x와 y 데이터 κ°„μ˜ 상관관계 κ³„μˆ˜λ₯Ό ν‘œμ‹œν•©λ‹ˆλ‹€.
# μ—¬κΈ°μ„œ 'correlation(x,y)'λŠ” x와 y λ°μ΄ν„°μ˜ 상관관계λ₯Ό κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©°,
plt.title('corr={:.2}'.format(correlation(x,y)))

plt.show()

  • plt.axis('equal')은 두 μΆ•μ˜ μŠ€μΌ€μΌμ„ λ™μΌν•˜κ²Œ μ„€μ •ν•˜μ—¬, 데이터 포인트 κ°„μ˜ 직선적 관계λ₯Ό λ”μš± λͺ…ν™•ν•˜κ²Œ λ³΄μ—¬μ£ΌλŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
  • 상관관계 κ³„μˆ˜(corr)λŠ” -1μ—μ„œ 1 μ‚¬μ΄μ˜ 값을 가지며, 이 값이 1에 κ°€κΉŒμšΈμˆ˜λ‘ λ³€μˆ˜ 간에 μ™„λ²½ν•œ μ–‘μ˜ μ„ ν˜• 관계가 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 이 μ½”λ“œμ—μ„œλŠ” correlation(x, y) ν•¨μˆ˜λ₯Ό 톡해 κ³„μ‚°ν•©λ‹ˆλ‹€.

Correlation and Causation (상관관계와 인과관계)

"μƒκ΄€κ΄€κ³„λŠ” 인과관계가 μ•„λ‹™λ‹ˆλ‹€ (Correlation is not causation)”
  • λ§Œμ•½ x와 yκ°€ κ°•ν•œ 상관관계λ₯Ό 가진닀면,
    • 그것은 xκ°€ yλ₯Ό μΌμœΌν‚¨λ‹€κ±°λ‚˜,
    • yκ°€ xλ₯Ό μΌμœΌν‚¨λ‹€κ±°λ‚˜,
    • μ„œλ‘œκ°€ μ„œλ‘œλ₯Ό μΌμœΌν‚¨λ‹€κ±°λ‚˜,
    • μ–΄λ–€ 제3의 μš”μΈμ΄ λ‘˜ λ‹€λ₯Ό μΌμœΌν‚¨λ‹€κ±°λ‚˜,
    • λ˜λŠ” 아무 μ˜λ―Έκ°€ 없을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  • DataSciencester μ‚¬μ΄νŠΈμ—μ„œ 더 λ§Žμ€ 친ꡬλ₯Ό 가지고 μžˆλŠ” 것이 μ‚¬μš©μžλ“€μ΄ μ‚¬μ΄νŠΈμ—μ„œ 더 λ§Žμ€ μ‹œκ°„μ„ λ³΄λ‚΄λŠ” 원인이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ°μ΄ν„°μ‚¬μ΄μ–ΈμŠ€ ν¬λŸΌμ—μ„œ λ…ΌμŸν•˜λŠ” μ‹œκ°„μ΄ 길수둝, μœ μ‚¬ν•œ 사고방식을 가진 μ‚¬λžŒλ“€μ„ 더 많이 λ§Œλ‚˜κ³  친ꡬλ₯Ό μ‚¬κ·ˆ κ°€λŠ₯성이 μžˆμŠ΅λ‹ˆλ‹€.
  • 데이터 과학에 열정적인 μ‚¬μš©μžλ“€μ΄ μ‚¬μ΄νŠΈμ—μ„œ 더 λ§Žμ€ μ‹œκ°„μ„ λ³΄λ‚΄λŠ” 것은 μ‚¬μ΄νŠΈλ₯Ό 더 ν₯미둭게 μ—¬κ²¨μ„œμ΄λ©°, 더 λ§Žμ€ 데이터 κ³Όν•™ 친ꡬλ₯Ό ν™œλ™μ μœΌλ‘œ λͺ¨μœΌλŠ” 것은 λ‹€λ₯Έ μ‚¬λžŒλ“€κ³Ό ꡐλ₯˜ν•˜κ³  싢지 μ•ŠκΈ° λ•Œλ¬ΈμΌ 수 μžˆμŠ΅λ‹ˆλ‹€.