산점도

    두 숫자형 변수의 관계를 나타내는 그래프

    # 직선이 중요 -> 무슨 의미일까? 차차 알아가보자.

     

    환경 준비

    라이브러리를 먼저 불러오자.

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn as sns

    이번에는 뉴욕 공기 오염도 데이터셋을 사용해보자.

    air = pd.read_csv('https://raw.githubusercontent.com/DA4BAM/dataset/master/air2.csv')
    air['Date'] = pd.to_datetime(air['Date'])

     

    산점도 플롯

    plt.scatter('Temp', 'Ozone', data = air)
    
    #plt.scatter(air['Temp'], air['Ozone'])
    #sns.scatterplot(x='Temp', y='Ozone', data = air)
    plt.xlabel('Temp')
    plt.ylabel('Ozone')
    plt.show()

     

    산점도에서 무엇을 확인할 수 있을까? 잘 보면... 온도가 증가할 때마다 오존 농도도 대체로 증가하는 '직선'을 볼 수 있다.

     

    강한 관계, 약한 관계

     

    산점도에서 강한 관계라는 것은 얼마나 직선에 모여 있는지, x - y 의 관계를 얼마나 직선으로 잘 설명할 수가 있는지를 의미한다.

    하지만 일일이 scatter 사용해서 산점도 하나씩 보고 직선 관계 살펴보고... -> 귀찮고 시간도 걸린다 -> pairplot

     

    sns.pairplot(air)
    plt.show()

    대신 이것도 시간이 좀 걸리긴 한다.

    # 산점도와 각각의 히스토그램을 함께 보여주는 jointplot

    sns.jointplot(x='Temp', y='Ozone', data = air)
    plt.show()

    regplot

    sns.regplot(x='Temp', y='Ozone', data = air)
    plt.show()

     

    하지만, 눈으로 그래프를 보면서 관계를 파악하고 차이를 분석하는 것은 쉬운 일이 아니다. 

    우리에겐 관계를 숫자로 알려주는 '상관계수'가 필요하고, 이 상관계수가 유의미한지를 검정하는 '상관분석'이 필요하다.

     

    상관계수(Correlation)

    상관계수는 'r'로 표현한다. -1~1 사이의 값을 가지며, |1|에 가까울 수록 강한 상관관계를 나타낸다.

    scipy 모듈을 활용하여 상관분석을 해보자.

    import scipy.stats as spst
    spst.pearsonr(air['Temp'], air['Ozone'])
    
    # PearsonRResult(statistic=0.6833717861490114, pvalue=2.197769800200274e-22)

    결과가 tuple 형태로 나오는데, [0]은 상관계수, [1]은 p-value를 의미한다.

     

    p-value

    상관계수가 유의미한지 판단하는 숫자

     

    p-value < 0.05 -> 두 변수 간에 관계가 있다. = 상관계수가 의미있다.

    p-value >= 0.05 -> 두 변수 간에 관계가 없다. = 상관계수가 의미없다.

     

    한꺼번에 상관계수 구하기

    df.corr() 로 구할 수 있다.

    air.corr()

    • 같은 변수끼리는 당연히 상관계수가 1이 나온다 = 의미없다.
    • 상관계수의 절댓값이 1에 가까울수록 강한 상관관계 -> Ozone-Temp가 가장 강한 상관관계
    • 상관계수의 절댓값이 0에 가까울수록 약한 상관관계 -> Solar.R-Wind가 가장 약한 상관관계

    # 양의 상관관계 / 음의 상관관계

    간단히 설명하면 A 증가하면 B도 증가 -> 양

    A 증가하면 B 감소 -> 음

     

    ++ 상관계수를 heatmap으로 시각화

    plt.figure(figsize = (4, 4))
    sns.heatmap(air.corr(), 
                annot = True,            # corr 표기 여부
                fmt = '.2f',             # 숫자 형식: 소수점 2자리까지 표기
                cmap = 'RdYlBu_r',       # 칼라맵
                vmin = -1, vmax = 1)     # 값 최소~최대 범위
    plt.show()

     

     

    이변량분석 범주 - 숫자

    이전에 사용했던 타이타닉 데이터셋으로 실습을 해보자.

     

    준비 단계

    라이브러리 및 데이터를 불러오자.

    import pandas as pd
    import numpy as np
    
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    import scipy.stats as spst
    
    titanic = pd.read_csv('https://raw.githubusercontent.com/DA4BAM/dataset/master/titanic.0.csv')
    
    titanic.info()

     

    시각화

    시각화를 통해 데이터를 한눈에 보고 비교해보자.

    sns.barplot(x="Sex", y="Age", data=titanic)
    plt.grid()
    plt.show()

    검은색 샤프심은 95% 신뢰구간을 의미한다.

     

    수치화

     

     

    t - test

    NaN을 제외한 데이터들로 계산을 해야한다.

    A -> B 의 관계에서, 두 집단의 평균을 비교하여 두 변수간에 관련이 있는지를 확인하는 것

    - t 통계량: 두 평균의 차이를 표준오차로 나눈 값 ( =. 두 평균의 차이) -> 일반적으로 t 값이 |2|보다 크면 차이(관련)가 있다.

     

    - 데이터 준비(NaN 제외)

    가설: 성별 별로 생존여부에 차이가 있을 것이다.

    isna()로 NaN이 있는지 확인 + sum()으로 NaN 개수 총합을 구한다.

    titanic.isna().sum()

    Age, Cabin, Embarked

    우리는 Survived, Sex를 쓸 거니까 NaN 딱히 제외 안해도 되겠군.

    - 데이터를 두 그룹으로 저장 및 결과 확인

    male = titanic.loc[titanic['Sex']=='male', 'Survived']
    female = titanic.loc[titanic['Sex']=='female', 'Survived']
    spst.ttest_ind(male, female)

    pvalue가 0.5 미만 -> 상관계수 의미 O + t값 |2| 이상 -> 성별에 따라 생존여부에 차이가 있다.

     

     

     

    anova(ANalysis Of VAriance): 분산 분석

    위에서 두 집단 간의 차이를 비교하는 방법을 배웠다. 그렇다면 여러 집단 간의 차이는 어떻게 비교할 수 있을까?

    F 통계량 = (집단 간 분산) / (집단 내 분산) = (전체 평균 - 각 집단 평균) / (각 집단의 평균 - 개별 값)

    F 통계량 값이 대략 2~3 이상이면 차이가 있다고 판단한다.

    sns.barplot(x="Pclass", y="Fare", data=titanic)	# P class: 3 범주 -> Fare
    plt.grid()
    plt.show()

    당연히 좌석 클래스별로 운임 차이가 있다는 것을 알지만, 이해를 돕기 위해서...

    이제 한번 가설을 세우고 확인해보자.

    가설: 승선지역에 따라 나이에 차이가 있을 것이다.

    # NaN 제외
    temp = titanic.loc[(titanic['Age'].notnull()) & (titanic['Embarked'].notnull())]
    s = temp.loc[temp.Embarked == 'S', 'Age']
    c = temp.loc[temp.Embarked == 'C', 'Age']
    q = temp.loc[temp.Embarked == 'Q', 'Age']

     

    spst.f_oneway(s, c, q)

    상관계수가 의미없으므로 = 관계가 없다.

     
    이런 식으로 가설을 세우고 검정하면 된다.
     

    'AIVLE' 카테고리의 다른 글

    [AIVLE] 딥러닝 - keras 기초  (0) 2023.02.27
    [AIVLE] 머신러닝  (0) 2023.02.24
    [KT AIVLE 3기] 단변량분석  (0) 2023.02.09
    [KT AIVLE 3기] 데이터 시각화  (0) 2023.02.09
    [KT AIVLE 3기] 시계열 데이터 처리  (0) 2023.02.09
    Posted by 저본