다중 공선성
- 독립변수들끼리 상관관계가 높을수록 VIF가 커지고 → 회귀분석이 어려워진다

- 모형의 일부 예측변수가 다른 예측변수와 상관되어 있을 때 발생하는 조건이다.
- 중대한 다중공선성은 회귀계수의 분산을 증가시켜 불안정하고 해석하기 어렵게 만들기 때문에 문제가 된다.
- R에서는 vif 함수를 이용해 VIF값을 구할 수 있으며, 보통 VIF값이 4가 넘으면 다중 공선성이 존재한다고 본다.
- => 해결방안 : 높은 상관 관계가 있는 예측변수를 모형에서 제거한다.
회귀 분석 결과 해석
- 모형이 통계적으로 유의미한가? F-분포값과 유의 확률(P-value)
- 회귀 계수들이 유의미 한가? 회귀 계수 T값과 유의 확률
- 모형의 설명력 : 결정 계수 (결정계수가 1에 가까울 수록 유의미)
- 데이터 적합성 : 잔차 통계량, 회귀 진단
#전체코드
data(cars)
cor(cars$dist, cars)
result<-lm(dist~speed, data=cars)
summary(result)
par(mflow=c(2,2))
plot(result)
하나씩 분석해보자
#단순선형회귀모형
result <- lm(dist ~ speed, data=cars)
- 단순선형회귀모형 적합
- 의미: 속도(speed)가 증가할수록 제동거리(dist)가 얼마나 증가하는지 모델링
summary(result)
- 회귀 결과 요약 출력
- 여기서 주로 보는 것:
- 회귀계수(Intercept, speed)
- p-value (speed가 유의한 영향인지)
- R-squared (설명력)
- Residual standard error (오차 크기)
- F-statistic (모델 전체 유의성)
par(mflow=c(2,2))
plot(result)
- 화면 분할해서(2×2) 회귀 진단 플롯 4개 출력




1. Residuals vs Fitted : 선형성(linearity) + 등분산성(heteroscedasticity) 체크
- 정상적이라면
- 점들이 0 근처에 랜덤하게 흩어져야 함
- 빨간 선(추세선)이 거의 수평
- 지금 내 그림에서
- 빨간 선이 약간 U자 형태로 휘어 있음
- 해석: 선형성이 완벽하진 않다(비선형 패턴 가능)
2. Scale-Location (Spread-Location) : 등분산성 확인 (잔차 분산이 일정한지)
- 정상적이라면
- 점들이 모든 fitted에서 비슷한 폭으로 분산
- 빨간 선이 수평
- 지금 내 결과
- fitted value가 커질수록 점들의 높이가 커지는 경향
=> 등분산성 위반 가능성(이분산)
→ 속도가 클수록 오차(잔차)가 더 커지는 경향
- fitted value가 커질수록 점들의 높이가 커지는 경향
3. Normal Q-Q : 잔차 정규성(normality) 확인
- 정상적이라면
- 점들이 직선(대각선)을 따라야 함
- 지금 내 결과
- 오른쪽 꼬리에서 점들이 위로 들림(23, 35, 49 등)
- 잔차가 정규분포에서 벗어남 (특히 꼬리부분)
→ 큰 값에서 이상치/비정규성 존재
4. Residuals vs Leverage : 영향점(influential point) 확인
- 특정 관측치가 회귀선을 많이 흔드는지
- x축: leverage (특이한 x값 여부)
- y축: 표준화잔차
- 점선: Cook’s distance (영향력 기준선)
- 지금 내 결과
- 49번 관측치가 leverage도 크고 잔차도 큼
=> 해석: 영향점 가능성이 높은 관측치가 존재
- 49번 관측치가 leverage도 크고 잔차도 큼
최종 결론
dist ~ speed 모델은 전반적으로 관계는 있지만,
진단 결과에서
- 잔차 패턴이 약간 곡선 형태 → 선형성 완벽X
- fitted가 커질수록 분산 증가 → 이분산 가능성
- Q-Q plot 꼬리에서 이탈 → 정규성 약화
- 몇몇 관측치(예: 49)가 영향점 가능성
따라서 단순선형회귀를 그대로 쓰기보다는
변수 변환 / 다항회귀 / 영향점 검토가 필요하다고 해석할 수 있음.
붓꽃 데이터로 ..
data(iris)
head(iris)
str(iris)

- data(iris) : R 기본 예제 데이터 iris 불러오기
- head(iris) : 상위 6행 출력
- str(iris) : 구조 확인 (변수 타입 및 데이터 형태)
- iris 데이터 구조
- 150개 관측치
- 변수 5개
- 연속형 4개: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width
- 범주형 1개: Species (setosa/versicolor/virginica)
table(iris$Species)

- table() : 각 종이 몇 개씩 있는지 확인
summary(iris)

- summary() : 전체 기술통계량(최소~최대, 평균, 사분위) + Species 분포
#y(연속형) = w1*x1+ w2*x2 + b
iris_data <- iris[,-5] #R 제외하고고
iris_data
- 5번째 열인 Species를 제외
- -> 이유: cor()은 숫자형 변수끼리만 상관계수 계산 가능
#install.packages("corrplot")
library(corrplot)
res<-cor(iris_data) #상관관계표
corrplot(res)
- Pearson 상관계수 계산
- 값 범위: -1 ~ +1
- +1: 완전한 양의 상관
- -1: 완전한 음의 상관
- 0: 상관 거의 없음
install.packages("PerformanceAnalytics")
library(PerformanceAnalytics)
chart.Correlation(iris_data, histogram = TRUE, pch = 19)

- 대각선(diagonal)
- 각 변수의 히스토그램
- 분포 모양 확인 (정규성 느낌 파악 가능)
- 왼쪽 아래(lower panel)
- 산점도(scatter plot)
- 변수 간 관계를 “직접 눈으로” 확인
- 오른쪽 위(upper panel)
- 상관계수(r) 값 표시
- 값이 클수록 강한 관계
상관분석 결과, Petal.Length와 Petal.Width 간 상관계수는 0.96으로 매우 높은 양의 상관관계를 보여 두 변수가 거의 동일한 정보를 포함하고 있음을 확인하였다. 또한 Sepal.Length는 Petal.Length(r=0.87), Petal.Width(r=0.82)와 높은 양의 상관을 나타내어 꽃의 크기와 꽃잎 크기 간 강한 연관성이 존재하였다. 반면 Sepal.Width는 Petal 변수들과 음의 상관(r=-0.43, r=-0.37)을 보여 꽃받침 너비는 꽃잎 크기 증가와 반대 방향으로 변화하는 경향이 나타났다. 대각선 분포에서는 Petal 변수들이 다봉형 분포를 보여 종(Species)에 따라 꽃잎 특성이 뚜렷하게 구분될 가능성이 높으며, 향후 모델링 시 Petal 변수 간 다중공선성에 대한 고려가 필요하다.
data(iris)
head(iris)
str(iris)
table(iris$Species)
summary(iris)
#y(연속형)=w1*x1+w2*x2+b
iris_data <- iris[,-5] #R 제외하고고
iris_data
#install.packages("corrplot")
library(corrplot)
res<-cor(iris_data) #상관관계표
corrplot(res)
#y(연속형)=w1*x1+w2*x2+b
iris_data <- iris[,-5] #R 제외하고고
iris_data
#install.packages("corrplot")
library(corrplot)
res<-cor(iris_data) #상관관계표
corrplot(res)
#install.packages("PerformanceAnalytics")
library(PerformanceAnalytics)
chart.Correlation(iris_data, histogram = TRUE, pch = 19)
plot(iris$Sepal.Length,
col = iris$Species, # 품종별로 색상 다르게 (Setosa=1, Versicolor=2, Virginica=3)
pch = 19, # 점의 모양을 꽉 찬 원으로 설정
main = "품종별 Sepal.Length 산점도",
xlab = "Index (데이터 번호)",
ylab = "Sepal.Length")
# 품종별 박스플롯 (분포의 중앙값과 사분위수 확인)
#with함수 파악 필수
with(iris, boxplot(Sepal.Length ~ Species,
main = "Species별 Sepal.Length 분포",
xlab = "품종", ylab = "꽃받침 길이",
col = c("orange", "lightgreen", "lightblue")))
새로 추가된 코드
plot(iris$Sepal.Length,
col = iris$Species,
pch = 19,
main = "품종별 Sepal.Length 산점도",
xlab = "Index (데이터 번호)",
ylab = "Sepal.Length")
- Sepal.Length 값이 품종별로 어떻게 분포되는지 “점”으로 확인하는 그래프
- x축은 Index(1~150) → 데이터 순서일 뿐이고,
- y축은 Sepal.Length(꽃받침 길이)
=> 품종(Species)에 따라 꽃받침 길이 값이 달라지는지 직관적으로 보는 목적
with(iris, boxplot(Sepal.Length ~ Species,
main = "Species별 Sepal.Length 분포",
xlab = "품종", ylab = "꽃받침 길이",
col = c("orange", "lightgreen", "lightblue")))
Species별로
- 중앙값(median)
- 사분위수(Q1~Q3)
- 이상치(outlier)
를 비교하는 그래프
박스플롯은 분포 요약(통계적 비교) 를 제공하는 시각화
=> Sepal.Length를 Species 집단별로 나눠서 boxplot을 그려라
- y축: Sepal.Length (연속형)
- x축: Species (범주형 집단 3개)
with 함수 !!!
with(iris, boxplot(Sepal.Length ~ Species))
boxplot(iris$Sepal.Length ~ iris$Species)
- 데이터프레임 iris 내부 변수를
- iris$ 없이 바로 쓰게 해주는 함수


왼쪽 산점도
- x축: 데이터 인덱스(1~150)
- y축: Sepal.Length 값
- 색깔: Species(품종)
- setosa(검정 점): 낮은 구간에 몰려 있음 (약 4.3~5.8)
- versicolor(분홍 점): 중간 구간에 몰려 있음 (약 4.9~7.0)
- virginica(초록 점): 높은 구간에 더 많이 분포 (약 4.9~7.9)
=> 해석
- 품종에 따라 Sepal.Length의 수준이 달라지는 패턴이 보임
- 특히 setosa는 다른 품종보다 전반적으로 Sepal.Length가 짧아 비교적 잘 분리됨
- 반면 **versicolor vs virginica는 일부 겹침(overlap)**이 존재 → Sepal.Length 하나만으로는 100% 분류는 어려울 수 있음
오른쪽 박스플롯
- setosa
- 중앙값이 가장 낮음 (약 5.0 근처)
- 분산(IQR)이 작음 → 개체들이 비교적 균일하게 짧다
- versicolor
- 중앙값이 setosa보다 높음 (약 5.9 근처)
- setosa보다 분산이 더 큼
- 위쪽 whisker가 더 길어서 큰 값도 일부 존재
- virginica
- 중앙값이 가장 큼 (약 6.5 근처)
- 가장 넓은 범위(큰 분산)를 보임
- 아래쪽에 이상치(outlier) 1개 보임 (낮은 Sepal.Length 개체)
해석
- 중앙값 순서:
setosa < versicolor < virginica - 즉, Sepal.Length는 품종에 따라 체계적으로 증가하는 경향
- 다만 versicolor와 virginica의 박스(분포)가 일부 겹치므로
→ Sepal.Length 하나만으로는 두 품종 완전 구분이 어렵다.
plot(iris$Petal.Length,
col = iris$Species, # 품종별로 색상 다르게 (Setosa=1, Versicolor=2, Virginica=3)
pch = 19, # 점의 모양을 꽉 찬 원으로 설정
main = "품종별 Sepal.Length 산점도",
xlab = "Index (데이터 번호)",
ylab = "Sepal.Length")
- plot(y) 형태
- plot()에 y 값만 하나 넣으면 R은 자동으로
- x축 = 1, 2, 3, ..., length(y) (즉 관측치 번호 = Index)
- y축 = y 값 을 사용해서 점 찍음
- x=1:150, y=iris$Petal.Lengthx 라는 의미
- “1번째 데이터의 Petal.Length, 2번째 데이터의 Petal.Length, …”를 순서대로 찍는 그래프.
- 이 그래프에서 x축(Index)은 설명변수가 아니라 단순한 데이터 순서
→ “관계”를 보는 게 아니라, 품종별 값의 분포/구간 차이를 보는 용도.
- col = iris$Species
- 각 점의 색을 Species 값에 따라 다르게 지정.
- Species는 factor라서 내부적으로 1,2,3 같은 정수 코드로 매핑됨:
- col=iris$Species는 “종 이름”을 색으로 쓰는 게 아니라
factor가 숫자로 바뀐 뒤 그 숫자에 해당하는 색이 적용되는 구조
- pch = 19
- 점 모양을 지정하는 옵션.
- pch=19는 꽉 찬 원(●)
- 자주 쓰는 pch:
- pch=1 빈 원(○)
- pch=19 꽉 찬 원(●)
- pch=16도 꽉 찬 원(●, 약간 다름)
=> 이 그래프는 Petal.Length 값이 Species별로 얼마나 분리되는지를 보여줌
iris 데이터는:
- setosa의 Petal.Length가 매우 작고
- versicolor는 중간
- virginica는 큼
색깔별로 점들이 y축에서 서로 다른 구간에 뭉쳐서 보이게 됨 .
=> Petal.Length는 Species를 구분하는 강력한 변수라는 시각적 근거

설명 변수 선택법 (최적 회귀방정식 선택)
1. 모든 조합 회귀 분석 : 모든 가능한 독립변수들의 조합에 대한 회귀모형을 고려해 AIC나 BIC의 기준으로 가장 적합한 회귀모형 선택
2. 단계별 변수 선택(Stepwise Variable Selection) => step()함수
- 이용 단계별 선택법: 모든 변수가 포함된 모델에서 출발하여 기준 통계치에 가장 도움이 되지 않는 변수를 삭제하 거나, 모델에서 빠져 있는 변수 중에서 기준 통계치를 가장 잘 개선시키는 변수 추가
- 후진 제거법 : 모든 변수가 포함된 모델에서 기준 통계치가 가장 도움이 되지 않는 변수를 하나씩 제거
- 전진 선택법: 절편만 있는 모델에서 기준 통계치를 가장 많이 개선시키는 변수를 차례로 추가하는 방법'
data(iris)
# 모든 "iris"# 모든 변수가 포함된 모델 (기준점)
full_model <- lm(Sepal.Length ~ . , data = iris)
# 상수항만 있는 모델 (시작점)
m1 <- lm(Sepal.Length ~ 1, data = iris)
# 전진 선택법 실행
stepwise_forward <- step(m1,
scope = list(lower = m1, upper = full_model),
direction = "forward")
summary(stepwise_forward)
stepwise_model <- step(m2, direction = "forward")
?step
'LG DX DATA SCHOOL' 카테고리의 다른 글
| 01/14 (1) | 2026.01.15 |
|---|---|
| 01/13 파이썬 머신러닝 시작 (0) | 2026.01.13 |
| 01/08 가설 검정 (0) | 2026.01.08 |
| 01/07 확률 분포 (t- 검정 vs 카이제곱 검정 ) (0) | 2026.01.07 |
| 01/06 가설 검정 (정규 분포, t-분포) (0) | 2026.01.06 |