본문 바로가기
IT,SW,Data,Cloud,코딩

파이썬 공부3

by 착실하게 2022. 9. 13.
반응형

범주형 데이터 간의 영향을 확인하는 분석 방법


=========================================
비수치형 데이터 간의 연관성/독립성 확인
=========================================

수치형 데이터는 평균 비교 검정 사용 가능.
비수치형 데이터는 대표값 평균 계산이 마땅치 않음.
그래서 비율이 얼마인지 알아보는 것으로 비교 및 판단. ㅡ> 사실상 평균 비교가 가능해짐.

카이제곱분포
정규분포의 분산에 대한 확률분포.
분산에 대한 분포이므로 양수만 나타난다.

카이제곱분포 기반으로 할 수 있는 분석
- 독립성 검정.
성별이 폰 타입 선호도에 독립적인가?
독립적이라면, 성별이 폰 타입 선호도에 영향이 없다.
독립적이지 않다면, 영향이 있다.

다룰 수 있는 문제들 예시
- 흡연이 폐암에 미치는 영향
- 어떤 광고가 더 판매에 효과적인지
- ㅇㅇ를 먹으면 ㅁㅁ질병의 발생 확률이 낮아진다.

카이제곱 독립성 검정 Chi-square Test
- 두 개의 범주형 데이터를 사용한다.
- 하나의 범주형 데이터가 다른 하나의 범주형 데이터 값에 영향이 있는지 확인하기.

예를 들어, 성별이 ㅇㅇ 선호도에 영향이 있다면 차이가 크다. 영향이 없다면 차이가 없다.
ㅡ> 그러면, 얼마나 차이가 나야 성별에 의한 차이가 난다고 할 수 있나?

카이제곱분포는
- 정규 분포의 분산에 대한 분포.
- 즉 평균으로부터 얼마나 떨어져있는가에 대해 확률적으로 알려주는 분포.

조사한 데이터를 평균과 떨어진 정도로 생각하고
카이제곱분포를 활용하여 데이터가 평균으로부터 얼마나 떨어져 있는지 비교 가능.

- 귀무가설: 기대하는 값이 같다

>> Chi-square Test of Independence 수행!!
- 사례) 연령대에 따른 멤버십 타입 선호가 다른지 확인 해보는 문제.
- 파이썬 scipy.stats 패키지의 chi2_contingency 함수 사용.
해당 함수는 입력값으로 요약표 같은 구조를 필요로 한다.

from scipy.stats import chi2_contingency

crosstab = pd.crosstab( data.age_group, data.membership_type )

chi2_contingency( crosstab )

두 개의 결과값과 어레이 데이터가 반환된다.

위 리턴된 내용을 좀더 보기 좋게 바꾸는 코드는 다음과 같다.

result = chi2_contingency( crosstab )
print( 'Chi2 Statistic : {} , p-value : {}'.format( result[0], result[1] ) )


귀무가설은 age_group 과 membership_type은 독립적이다
p-value가 작게 나오면 귀무가설기각.
즉, 둘은 연관성이 있다는 결론.




=========================================
두 수치형 데이터 간의 연관성을 알아보는 상관 분석!!!
=========================================

데이터 분석 초입 단계에 변수 간의 관계 확인에 사용함.
- 어떤 변수가 중요?
- 어떤 변수가 어떤 변수와 관계 있는지?
- 어떤 변수를 중심으로 깊이 있는 분석을 수행해야?

상관분석 방법
ex) 산점도 scatter plot
계량적 관계 파악을 위해서는 상관분석을 해야 함.

상관분석?
- 두 개의 데이터 (항상 2개 에 대해 분석 수행함. 2개씩 여러번 수행함)
- 수치형 데이터 (수치형만 가능함. 범주형은 불가)
- 직선 관계 확인 : 수치형 변수 두 개가 서로 연관 있는지? 있다면 양의 관계 인지 음의 관계 인지 ?
- 인과 관계는 아님. 하나의 증감이 다른 하나도 필연적으로 증감하는 관계인지는 모른다.
- 상관계수가 데이터 안에 존재하는 진짜 상관성과 일치하지 않는 경우가 자주 있다. 왜냐면, 데이터가 예를 들어 원의 형태로 있을 때. 상관 관계는 0이 나온다. 원의 형태는 x 와 y 의 관계식으로 정확하게 표현할 수 있음에도 불구하고 말이다.
- 상관 분석의 한계: 직선성이 아닌 것, 몇 개의 그룹으로 나눠진 경우, 이상값이 일부 극단값으로 존재하는 경우. 불가능하다.

인과관계 설명 및 예측까지 갈 수 있어야 함!

상관분석 파이썬 코드

dist_by_column1 = pd.pivot_table( data, index = 'column1', values = 'column2', aggfunc = len )

결과 데이터 = column1 별 column2 값의 갯수

population = pd.read_csv( 'data/population_by_column1.txt' , sep = '\t' )
구분자 디폴트 값: 콤마. 탭으로 지정하는 코드.

두 데이터를 합치는 코드
by_column1 = pd.merge( dist_by_column1 , population, on = 'column1' )

산점도 그려보는 코드
plt.scatter( by_column1.column2 , by_column1.population )

상관계수를 구할 수 있는 함수 2가지
1) scipy.stats 패키지의 pearsonr 함수
2) pandas 패키지의 corr() 함수

1) pearsonr 함수
stats.pearsonr( by_column1.field1 , by_column1.field2 )
첫 번째 값이 상관 계수
두 번째 값은 p-value

상관계수는 -1 에서 1 사이의 값
절대값이 클수록 강한 상관 관계.

p-value 는 0.05보다 크면
통계적으로 유의미한 관계가 아니다.
귀무가설 기각 불가능.
즉, 상관관계 없다.

2) corr 함수

by_column1 = pd.merge( dist_by_column1, population, on = 'column1' ) [[ 'column1', 'column2', 'population' ]]

by_column1.corr()

잘 정돈된 테이블이 나온다.
데이터가 가지고 있는 모든 컬럼을 대상으로 상관계수를 구해서 보여준다.
많은 수치형 데이터 컬럼을 모두 상관분석 해보고자 할때 편리하다.
대신에 p-value 값은 보여주지 않는다.


=========================================
인과관계는 회귀분석!!!!
=========================================


회귀분석은 인과관계를 설명하는 하나의 방법. 통계적으로는 관계를 설명하고, 머신러닝에서는 예측할 때 사용.

독립변수 x 와 종속 변수 y 는 둘 다 수치형 데이터이다.
y = a * x + b
회귀 분석은 두 변수의 관계를 설명하는 선형 식을 찾는 것!

독립변수는 하나 이상의 값이 사용될 수 있다.

일단 독립변수가 1개 사용되는 회귀분석 살펴보기!!
1) 사용법
2) 해석
3) 필수 사항

데이터 관련 주의점
- 두 데이터의 시간 간격이 동일한가?

(( 사례 )) 온도 ㅡ> 자전거 대여
영향이 있는지 파악해보기!!

예를 들어
weather 데이터 : 시,분 단위
bike_data : 시간 단위
일 때, 단위 통일 하는 코드

[ 1 ] scipy 패키지 사용해서 분석해보기

1) weather 데이터 변형

new_weather = pd.pivot_table( weather, index = [ 'date' , 'time' ] , values = [ 'temp' , 'cum_precipitation' , 'humidity' , 'insolation' , 'sunshine' , 'wind' , 'wind_direction' , 'sea_lvl_pressure', 'pressure' ] , aggfunc = np.mean )

인덱스 별 values에 나열 된 필드들의 평균 이 결과값으로 나온다.
그런데 이렇게 하면, 인덱스로 처리된 컬럼은 일반 컬럼으로 사용하기 어렵다.

new_weather = new_weather.reset_index()

인덱스를 일반 컬럼처럼 사용하게 처리한 코드.
새로운 연속 번호 인덱스가 생겼다.

분 단위 데이터를 시간 단위로 요약했음.

2) bike_data 변형

new_bike = pd.pivot_table( bike_data , index = [ 'Date' , 'Time' ] , values = [ 'Distance' ] , aggfunc = len )

new_bike = new_bike.reset_index()

참고** 컬럼이름 변경 코드
Distance ㅡ> Count 로 바꾸기.

new_bike.rename( columns = { 'Distance' : 'Count' } , inplace = True )

>> new_bike.columns 확인

두 개의 데이터 프레임 결합

bike_weather = pd.merge( new_bike, new_weather, left_on = [ 'Date' , 'Time' ] , right_on = [ 'date' , 'time' ] )

회귀 분석 파이썬 코드

stats.linregress( bike_weather.temp , bike_weather.Count )

결과값으로 기울기와 절편이 나온다.
slope = 기울기
intercept = 절편
>> 선형회귀식 Count = slope * temp + intercept
rvalue = 제곱해서 R제곱으로 사용한다.
표준오차 = stderr
pvalue = 유의수준과 비교하여, 작으면 귀무가설을 기각하자.

회귀분석의 귀무가설은
- 기울기가 0 이다.
- 회귀 관계가 없다.

pvalue가 작으면, 회귀 관계가 존재 한다.

R 제곱 값 파이썬 코드

slop, intercept, r_value , p_value , std_err = stats.linregress( bike_weather.temp , bike_weather.Count )

print( "R-squared : %f" %r_value**2 )

이 값은 결정계수다.
회귀식이 실제 관찰된 값을 얼마나 설명하는지를 의미한다.
데이터세트의 x값을 회귀식에 넣었을 때 , 계산된 y 값이 실제 데이터에 존재하는 y 값 대비 얼마나 되는지를 말한다.
0에서 1 사이의 값으로 나타난다.
1에 가까울수록 설명력이 높아서 좋은 회귀식으로 평가할 수 있다.




[ 2 ] statsmodels 패키지 사용하는 코드

import statsmodels.api as sm

x0 = bike_weather.temp
x1 = sm.add_constant( x0 )

y = bike_weather.Count

model = sm.OLS( y, x1 )

result = model.fit()

print ( result.summary() )


장점은
- 좀더 명확한 결과값
- 다양한 정보가 표로 표시됨

결정계수, F-검정 통계량의 확률, temp 의 p-value등이 나타난다.

R-squared : R제곱값.

Prob( F-statistic ) : F 검정 통계량 추정치
- 회귀식 전체에 대한 통계적 유의성을 검정한 p-value

회귀식의 귀무가설은
회귀식이 존재하지 않는다.
p-value작으면 귀무가설 기각.

const : 절편
temp : 독립변수로 사용된 x값
이 두 값의 coef : 회귀식의 절편과 기울기.
coef P > |t|
const 절편 0.128
temp 기울기 0.000

회귀식을 만들면 아래와 같다.
count = temp-coef * temp + const-coef


P > |t|
x 변수 들의 p-value 에 해당하는 값
( 위 코드는 x 독립 변수가 1개일 때 케이스 )
( temp (온도) 가 이 케이스의 하나뿐인 독립변수)

p-value( Prob( F-statistic ) ) 를 확인
x 독립변수가 통계적으로 유의하게 종속변수 y의 변동에 영향을 주는지 확인

이 값이 0.05보다 크면 통계적으로 유의하지 않음.
작으면 통계적으로 유의미하다.
독립변수 temp 온도 가 종속변수 count 의 변화 에 기울기 coef 만큼 영향을 준다는 것이 통계적으로 유의미하다.

R제곱값, F값에 대한 p-value, 독립변수의 t 값에 대한 p-value
ㅡ> 회귀식의 존재 자체와, 그 자치를 알 수 있는 지표들이다.
이 지표들이 의미가 없으면 다른 값들은 무의미하다.

F 값에 대한 p-value 가 통계적 유의성을 가지지 못할 경우,
회귀식을 처음부터 다시 고민해 보아야 한다.
>> 회귀식의 존재에 대한 확인.

t값에 대한 p-value가 통계적 유의성을 가지지 못할 경우,
해당 변수를 제외할지 고민해보자.

R 제곱값이 낮으면,
설명력을 높일 방법을 고민해야 한다.


=========================================
다중회귀분석
=========================================

다중회귀분석은
- 수치형 데이터가 아닌데 회귀 관계가 존재하는 경우를 다룰 수 있음.
- 두개 이상의 독립 변수를 다룰 수 있음.

회귀분석 변수가 많아지면 머신러닝도 도움이 된다.

통계와 머신러닝?
- 통계는 설명이 중요
- 머신러닝은 예측이 중요

머신러닝 프로세스
- Train : 회귀 분석 모델 생성
- Predit : 모델을 통한 예측
- Evaluate : 예측 결과의 정확도 계산

데이터를 학습용과 평가용으로 분리하기!
train용 데이터와 predict데이터!

[실습] sklearn 패키지를 활용한 데이터 세트 분리 실습!!!

- 독립 변수 4개: cum_precipitation, humidity, temp, wind

from sklearn.model_selection import train_test_split

X = bike_weather[['cum_precipitation','humidity','temp','wind']]
y = bike_weather.Count
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.3 , random_state = 123 )


random_state = 123
- 씨드!! 출발점~~
- 무작위로 실행되는 작업이 일정한 출발점을 가지도록 함.
- 똑같은 결과가 나오게 하는 씨앗 값
- 실행 결과: X 독립변수 2개 세트, y 종속 변수 2개세트

회귀분석의 Train 단계 수행
import statsmodels.api as sm

X1 = sm.add_constant( X_train )
model = sm.OLS( y_train, X1 )
result = model.fit()
print( result.summary() )

add_constant 함수는
statsmodels 의 OLS 회귀함수의 특성상 절편에 해당하는 값을 처리하기 위해서 적용해줘야한다.




결과 해석은 독립변수가 1개일 때와 4개일 때 똑같다~
R제곱값 높은지 보고,
F통계량 추정치로 회귀식에 대한 통계적 유의성 확인하고,
t 검정통계량 추정치의 p-value 들은 작아야 통계적 유의성이 있음, 독립변수들 중에서 통계적 유의성이 있는 변수만 활용하면 된다.
그런데, 독립변수를 1개 사용할 때랑, 4개 사용할때랑, 같은 독립 변수 여도 t 검정 통계량 추정치의 p-value가 다르게 나올 수 있다. 1개만 사용했을때 충분히 통계적으로 유의했던 독립변수도, 4개 사용할때의 회귀분석에서는 유의하지 않게 나올 수도 있다.
어떤 변수와 함께 고려하는지에 따라 결과가 다를 수 있음....




회귀분석 predict단계 수행

X1 = sm.add_constatn( X_test )
pred = result.predict( X1 )
print ( pred )



회귀분석 evaluate단계 수행
y_test : 테스트세트의 정답.
pred 와 y_test 비교하기.

from sklearn import metrics

print( 'MAE : ' , metrics.mean_absolute_error( y_test, pred ))

print('MSE : ' , metrics.mean_squared_error( y_test , pred ))

print( 'RMSE : ', np.sqrt( metrics.mean_squared_error( y_test, pred )))

print( 'MAPE : ', np.mean( np.abs(( y_test - pred ) / y_test )) * 100 )



mape 지표는
퍼센트로 표현하므로 비교와 이해가 쉬움.
에러율. 낮을수록 좋음.
얼마나 낮아야 하는지는 직접 정하는것.


추가 실험
X 에 cum_precipitation, humidity,temp, wind이렇게 넣었는데 바꿔가면서 실험 하기.






만약 범주형 데이터를 회귀분석에 활용 하려면 ?

예를 들어 비가 왔다/안왔다
Rain_YN

cum_precipitation > 0 : Y
cum_precipitation <= 0 : N

숫자를 1, 0 으로 줄 수도 있고
Y , N 으로 할 수도 있음.


bike_weather[ 'Rain_YN' ] = 'N'

bike_weather.loc[ bike_weather.cum_precipitation > 0 , 'Rain_YN' ] = 'Y'


cum_precipitation 대신 Rain_YN을 사용해보자.
범주형 데이터를 수치형 변수로 변환해줘야 한다.

One_hot_encoding
N = 0 , Y = 1 과 같은 식으로 데이터 변경하기.

ohe = pd.get_dummies( bike_weather[ 'Rain_YN' ] )

N, Y 두 컬럼으로 변형이 되었음.
N이었던 행은 N컬럼 1 Y컬럼 0
Y 이었던 행은 Y컬럼 1 N컬럼 0

bike_weather에 ohe 데이터 프레임 합치기

bike_weather = pd.concat( [bike_weather, ohe], axis = 1 , sort = False )



범주형 변수의 회귀분석

from sklearn.model_selection import train_test_split

X = bike_weather[[ 'humidity', 'temp', 'wind', 'N', 'Y' ]]

y = bike_weather.Count

X_train, X_test, y_train, y_test = train_test_split( X , y , test_size = 0.3 , random_state = 123 )

import statsmodels.api as sm

X1 = sm.add_constant( X_train )

model = sm.OLS( y_train, X1 )

result = model.fit()

print( result.summary() )

X1 = sm.add_constatn( X_test )

pred = result.predict( X1 )

from sklearn import metrics

print( 'MAE : ' , metrics.mean_absolute_error( y_test , pred ))

print( 'MSE : ' , metrics.mean_squared_error( y_test, pred ))

print('RMSE : ' , np.sqrt( metrics.mean_squared_error( y_test, pred )))

print( 'MAPE : ' , np.mean( np.abs( (y_test - pred ) / y_test ) ) * 100 )


Y, N 컬럼은 둘다 선택하지 않아도 된다. 이 경우 N 과 Y 이 똑같은 의미를 전달하고 있어서. N 이 0 이면 Y 는 1 이 되니까. 이게 drop last 임.



여기는 종속변수가 수치형 데이터인 경우였음.


=========================================
종속 변수가 범주형 데이터로 나타나는 경우!
=> 로지스틱 회귀분석 실행.
=========================================

종속변수가 범주형

선형 관계 설명하는 것은 회귀분석과 동일함.
선형성 기반!

로짓함수의 역함수로 로지스틱 함수를 도출한다.





대여소의 대여 건수의 일평균 건수가 최소 기준을 넘는가를 판단해보는 실습!!



bike_weather[ 'over_500' ] = 1
bike_weather.loc[ bike_weather.Count < 500, 'over_500' ] = 0

카운트가 500건 이상이면 1
미만이면 0



train 단계 수행

from sklearn.model_selection import train_test_split

독립변수 세팅
X = bike_weather[[ 'cum_precipitation' , 'humidity', 'temp', 'wind' ]]

종속변수 세팅
y = bike_weather.over_500

데이터 분리
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.3 , random_state = 123 )

import statsmodels.api as sm

X1 = sm.add_constant( X_train )
logit_model = sm.Logit( y_train, X1 )
result = logit_model.fit()
print( result.summary() )

로지스틱 회귀분석도
회귀분석과 마찬가지로
R제곱값으로 모델의 설명력을 판단한다.

로지스틱 회귀분석의 R제곱값은
회귀분석이 아니므로, Pseudo 라는 표현 사용
Pseudo R-squ 값 !!! 확인하기.

LLR p-value (로지스틱 리니어 리그레션)
아주 작은 값이면 통계적 유의성에 문제 없음.

각 독립변수의 p-value 확인 해보면
값이 아주 작아야 통계적 유의성 있음

일반적인 통계에서는 p-value의 유의성이 확인되지 않은 독립 변수를 제외한다.

머신러닝에서는 무조건 제외하진 않음.




predict 및 evaluate 수행 파이썬 코드


from sklearn.linear_model import LogisticRegression


log_reg = LogisticRegression()

log_reg.fit( X_train, y_train )

print( ' Train set 정확도 : %.2f' %log_reg.score( X_train, y_train ) )

print( ' Test set 정확도 : %.2f' %log_reg.score( X_test, y_test ) )


확률이므로 0에서 1 사이의 값을 가지게 된다.
train set 정확도: 학습 정확도
test set 정확도: 예측 정확도

좀더 상세한 정확도 확인을 위한 파이썬 코드

from sklearn.metrics import classification_report

y_pred = log_reg.predict( X_test )
print( classification_report( y_test, y_pred ) )


로지스틱 회귀분석의 머신러닝 프로세스 에서는 MSE, RMSE, MAPE 등의 에러 지표를 산출하는 것이 아니라,
accuracy, precision, recall, f1-score 등의 확률을 기반으로 평가 한다.


정확도의 종류 4가지
- accuracy : Y 를 Y로, N을 N으로 맞힌 경우를 전체 수로 나눔.
- precision : Y 라고 예측한 것 가운데 실제로 Y 였던 경우의 확률
- recall : Y 인 케이스 중에 얼마나 Y 라고 예측 했는가를 계산
- f1-score : precision 과 recall의 조화 평균



예측 || 실제 Y // N
Y 가 나
N 다 라


accuracy = 가 + 라 / 가 + 나 + 다 + 라
precision = 가 / 가 + 나
recall = 가 / 가 + 다
f1-score =









반응형

댓글