contents
summary
데이터의 ‘WHERE=(어디에 존재하는가)’ 를 표현해주는 개념
: 평균, 중앙값, 최빈값
-> 간단한 대표값만으로 데이터를 분석할수는 없다.
두 그래프의 평균은 같다. 그렇다면 두 데이터는 같은 것일까?
그렇지 않다 왜냐하면 그래프의 모양을 확인하면 완전히 다르기 때문이다.
그렇기에 자세히 데이터를 분석하기 위해 추가적인 분석이 필요하다. 이를 위해 추가적인 개념을 알아보자!
‘HOW = 어떻게 존재하는가’ 에 대한 개념
: 분산과 편차
-편차(deviation): 하나의 값에서 평균을 뺀 값 = 평균으로부터 얼마나 떨어져 있는지를 의미.
- A 학생의 영어점수: 30점
- B 학생의 영어점수: 70점
- C 학생의 영어점수: 80점
- A,B,C 학생의 평균 영어점수: 60점
> A 학생의 편차: -30
> B 학생의 편차: +10
> C 학생의 편차: +20
->학생 전체의 편차를 나타내기 위해 각 학생들의 편차를 모두 더하게 되면 0이 나온다. 따라서 편차로는 반 전체의 점수 분포를 정확히 알 수가 없기에 나온 개념이 분산입니다.
-분산(variance): 편차의 합이 0으로 나오는 것을 방지하기 위해 생성된 개념
= 편차 제곱합의 평균
- A 학생의 편차 제곱: (-30)^2 = 900
- B 학생의 편차 제곱: (+10)^2 = 100
- C 학생의 편차 제곱: (+20)^2 = 400
> 편차 제곱합: 1400
> 편차 제곱합의 평균(분산): 1400/3 = 466
분산은 466이 도출되었다. 그러나 점수라는 값에 제곱이 들어가며(점수에 제곱..!)
그 단위가 변해버리다. 즉, 실제 데이터가 어느정도로 차이가 있는 지 알기 어렵게 되었다.
이를 해결하기 위해 도입된 개념이 표준편차입니다.
-표준편차: 분산에 제곱근을 씌워준 값. (=원래 단위로 되돌리기 = standard deviation(σ))
- 분산: 466
- 분산의 제곱근 = 표준편차 = 약 21.6 이 되겠습니다.
👉모집단, 표본, 표본분포
:무수히 많은 데이터를 대상으로, 보다 양질의 데이터를 기반으로 효과적인 통계분석 및 데이터 편향(치우침)을 최소화 하기 위해 표본추출을 진행.
특히, 데이터 모델을 통해 추천이나 예측을 진행하는 경우 대표성을 가지는 데이터를 가지고 모델을 개발한다!
*데이터분석시 표준화가 필요한 경우: 머신러닝 모델을 만들 때, 데이터의 범위가 많이 차이나는 경우.
예시)
;최근 일주일 접속일수의 1과 결제금액의 1 은 같은 의미가 아니지만! 머신러닝시, 해당 값의 의미를 같게 받아들이고 처리할 수 있으며, 범위가 큰 데이터의 경우 숫자가 가지는 절대치를 잘못 받아들일 수 있어 표준화는 반드시 필요하다!
👉 신뢰구간, 신뢰수준
신뢰구간: 특정 범위 내에 값이 존재할것으로 예측되는 영역.
(ex:영어점수가 10점에서 90점 사이일 것 같아요)
; 모든 데이터는 표본을 추출하는 순간 불확실성을 가지게 된다. 모집단 전체를 사용하지 않는 한, 결과가 한끗차이도 나지 않기는 어렵기 때문이다!
즉, 이러한 데이터의 불확실성을 우리는 ‘신뢰구간’ 이라는 개념으로 약속.
신뢰수준: 실제 모수를 추정하는데 몇 퍼센트의 확률로 신뢰구간이 실제 모수를 포함하게 되는 확률. 주로 95%와 99% 를 이용.
(ex:영어점수가 10점에서 90점 사이에 있을(분포할) 확률이 95% 같아요)
👉실습
;‘scipy’ 를 활용하여, 95% 와 99% 신뢰구간 구하기
import scipy.stats as st
import numpy as np
#샘플 데이터 선언
sample1 = [5, 10, 17, 29, 14, 25, 16, 13, 9, 17]
sample2 = [21, 22, 27, 19, 23, 24, 20, 26, 25, 23]
df = len(sample1) - 1 # 자유도 : 샘플 개수 - 1
mu = np.mean(sample1) # 표본 평균
se = st.sem(sample1) # 표준 오차
# 95% 신뢰구간 ( = 95% 신뢰하려면 데이터의 범위가 어떻게 되는지?)
st.t.interval(0.95, df, mu, se) # (10.338733110887336, 20.661266889112664)
# 99% 신뢰구간( = 99% 신뢰하려면 데이터의 범위가 어떻게 되는지?)
# 99% 로 신뢰할 수 있어야 하므로, 앞선 95% 보다 데이터 범위가 넓은 점 이해되셨나요? :)
st.t.interval(0.99, df, mu, se) # (8.085277068873378, 22.914722931126622)
key point
insight
df2['Age'].mean()
#44.06846153846154
df2['Age'].median()
#44.0
df2['Age'].mode()
#69
-편차, 분산, 표준편차 구하기
# 평균 계산
mean_age = df2['Age'].mean()
# 편차 (각 값에서 평균을 뺀 값)
deviations = df2['Age'] - mean_age
# 분산과 표준편차
variance_age = df2['Age'].var() # 표본 분산
std_dev_age = df2['Age'].std() # 표본 표준편차
print("편차:\n", deviations)
print("분산:", variance_age)
print("표준편차:", std_dev_age)
편차:
0 10.931538
1 -25.068462
2 5.931538
3 -23.068462
4 0.931538
...
3895 -4.068462
3896 7.931538
3897 1.931538
3898 -0.068462
3899 7.931538
Name: Age, Length: 3900, dtype: float64
분산: 231.27076706058747
표준편차: 15.20758912716238
import random
df2_random_n = df2.sample(n=5, random_state=42)
df2_random_n
2) DataFrame으로 부터 특정 비율의 표본을 무작위로 추출하기 (fraction)
df2_random_fraction= df2.sample(frac=0.5, random_state=42)
df2_random_fraction
import matplotlib.pyplot as plt
# Creating a frequency distribution table for 'Age'
age_freq = df2_random_fraction['Age'].value_counts().sort_index()
# Plotting a histogram for 'Age'
plt.figure(figsize=(10, 6))
plt.hist(df2_random_fraction['Age'], bins=10, color='skyblue', edgecolor='black')
plt.title('Age Distribution in Sampled Data')
plt.xlabel('Age')
plt.ylabel('Frequency')
plt.grid(axis='y', alpha=0.75)
plt.show()
# Display frequency distribution table for 'Age'
age_freq.sort_index().head(10) # Displaying first 10 for brevity
# Calculating the cumulative relative frequency for 'Age'
# Getting frequency and relative frequency
age_counts = df2_random_fraction['Age'].value_counts().sort_index()
relative_freq = age_counts / age_counts.sum() # Relative frequency
# Calculating cumulative relative frequency
cumulative_relative_freq = relative_freq.cumsum()
# Plotting the cumulative relative frequency
plt.figure(figsize=(10, 6))
plt.plot(cumulative_relative_freq.index, cumulative_relative_freq.values, marker='o', linestyle='-', color='b')
plt.title('Cumulative Relative Frequency Distribution of Age in Sampled Data')
plt.xlabel('Age')
plt.ylabel('Cumulative Relative Frequency')
plt.xticks(cumulative_relative_freq.index, rotation=45)
plt.grid(alpha=0.75)
plt.show()
# Display cumulative relative frequency table
cumulative_relative_freq.head(10) # Displaying first 10 for brevity
; 20대의 비율이 전체의 약 20%정도를 차지한다.
import scipy.stats as st
from scipy.stats import norm
# Using df2_random_fraction to calculate sample statistics for 'Age'
# Selecting the fraction of the original df2 dataset
sample_mean_age = df2_random_fraction['Age'].mean()
sample_std_age = df2_random_fraction['Age'].std()
sample_size_age = len(df2_random_fraction['Age'])
confidence_level = 0.95 # 95% confidence level
# Calculating the margin of error using Z-distribution for the 'Age' column
z_score = norm.ppf(1 - (1 - confidence_level) / 2) # Two-tailed z-score
margin_of_error_age = z_score * (sample_std_age / np.sqrt(sample_size_age))
# Computing the confidence interval for 'Age'
lower_bound_age = sample_mean_age - margin_of_error_age
upper_bound_age = sample_mean_age + margin_of_error_age
# Preparing the normal distribution for 'Age'
age_x = np.linspace(sample_mean_age - 4 * sample_std_age, sample_mean_age + 4 * sample_std_age, 1000)
age_y = norm.pdf(age_x, sample_mean_age, sample_std_age)
# Plotting the normal distribution for 'Age'
plt.figure(figsize=(12, 6))
plt.plot(age_x, age_y, label=f'Normal Distribution of Age (µ={sample_mean_age:.2f}, σ={sample_std_age:.2f})', color='g')
plt.axvline(lower_bound_age, color='r', linestyle='--', label=f'95% CI Lower Bound: {lower_bound_age:.2f}')
plt.axvline(upper_bound_age, color='b', linestyle='--', label=f'95% CI Upper Bound: {upper_bound_age:.2f}')
plt.title('Normal Distribution and 95% Confidence Interval for Age')
plt.xlabel('Age')
plt.ylabel('Probability Density')
plt.grid(alpha=0.5)
plt.legend()
plt.show()
lower_bound_age, upper_bound_age, sample_mean_age, sample_std_age
# Standardizing 'Age' data in df2_random_fraction
standardized_age = (df2_random_fraction['Age'] - sample_mean_age) / sample_std_age
# Preparing data for plotting standard normal distribution
z_x = np.linspace(-4, 4, 1000) # Standard normal range (z-scores)
z_y = norm.pdf(z_x, 0, 1) # Standard normal distribution PDF
# Plotting the standard normal distribution using standardized data
plt.figure(figsize=(12, 6))
plt.plot(z_x, z_y, label='Standard Normal Distribution (µ=0, σ=1)', color='purple')
plt.hist(standardized_age, bins=20, density=True, alpha=0.5, color='orange', edgecolor='black', label='Standardized Age Histogram')
plt.title('Standard Normal Distribution and Standardized Age Data')
plt.xlabel('Z-Score')
plt.ylabel('Probability Density')
plt.axvline(0, color='red', linestyle='--', label='Mean (Z=0)')
plt.grid(alpha=0.5)
plt.legend()
plt.show()
# Displaying summary statistics of the standardized data for reference
standardized_age.mean(), standardized_age.std() # Expecting mean ~ 0 and std ~ 1