← 모델 목록
수업 실습 2026-08-27 · tabular-regression
선형 모델 계열 (최소제곱 선형 회귀)

LinearRegression (scikit-learn)

선형 회귀 유튜브 7일 조회수 예측 (회귀 모델 과제)
모델
피처마다 가중치를 곱해 더한 직선(초평면)으로 숫자를 예측하는 가장 기본적인 회귀 모델
사용 목적
유튜브 영상 정보로 7일 조회수를 예측하는 회귀 과제의 기준 모델로 쓰고, 지표(MAE·RMSE·R²)를 해석하는 보고서를 쓰려고 사용
코드
mnmms/mldl
가중치
없음
r285.6%
mae13424
rmse28081
실험2회 · 대표 r1
학습 시간없음
추론 CPU / GPU측정 안 함

데이터

  • 수업 제공 1,500개 영상 · 15개 입력
  • train 1,200 · test 300 (seed 42)
  • 조회수 486 ~ 1,848,414 (왜도 7.7)

학습

  • 결측 중앙값 대체 · 1~99% 클리핑
  • CPU · scikit-learn 1.9.0
  • 학습 시간 [미확인]

결과

  • R² 0.856 · MAE 13,424 · RMSE 28,081
  • log1p 타깃 실험은 R² -8.83으로 실패

배운 점

  • RMSE가 MAE의 2배 = 크게 틀린 소수 영상
  • expm1 역변환이 작은 오차를 크게 부풀림
개요용도 의도한 용도: 회귀 모델 4종을 같은 데이터로 학습해 MAE·RMSE·R²를 비교하고 보고서로 해석하는 과제의 기준 모델…

용도

  • 의도한 용도: 회귀 모델 4종을 같은 데이터로 학습해 MAE·RMSE·R²를 비교하고 보고서로 해석하는 과제의 기준 모델
  • 대상 사용자: 해당 없음 (학습용)
  • 의도하지 않은 용도: 실제 유튜브 조회수 예측 (가상 데이터, 큰 조회수에서 오차가 큼)

모델 정보

항목 값
베이스 모델 직접 구현 (처음부터 학습)
크기 · 변형 LinearRegression() 기본값 (가중치 21개 + 절편)
리비전 scikit-learn 1.9.0 (uv.lock 기준)
아키텍처 입력 21열(숫자 13 + 카테고리 원-핫 8)의 선형 결합
학습 방식 처음부터 학습 (최소제곱)
프롬프트 · 에이전트 구성 해당 없음
데이터7일 조회수 분포: 원래 스케일과 log1p 피처 상관관계 확보 방식 공개 데이터셋 그대로 (수업 제공) 출처 수업 자료 da…
7일 조회수 분포: 원래 스케일과 log1p
7일 조회수 분포: 원래 스케일과 log1p
피처 상관관계
피처 상관관계
항목 값
확보 방식 공개 데이터셋 그대로 (수업 제공)
출처 수업 자료 data/youtube_7day_views_regression_practice.csv
직접 수집 내용 해당 없음
이용 조건 확인 해당 없음 (수업 자료)
규모 1,500개 영상 × 16열 (ID, 카테고리, 구독자 수, 영상 길이, 업로드 시각·요일, 썸네일 점수, 제목 길이, CTR, 평균 시청률, 직전 업로드 후 일수, 협찬, 첫 24시간 조회·좋아요·댓글, 7일 조회수)
분할 train 1,200 / test 300 (8:2, 시드 42)
레이블·클래스 분포 7일 조회수 486 ~ 1,848,414, 중앙값 27,886, 왜도 7.74 (오른쪽 꼬리가 긴 분포)
전처리 결측(Thumbnail_Score 22, Avg_Watch_Percent 28)은 중앙값 대체. Channel_Subscribers, First24h_* 3열은 행을 지우지 않고 1~99% 분위수로 클리핑. Category 원-핫 8열. 스케일링 없음
개인정보·민감정보 처리 해당 없음 (가상 데이터)

조회수와 상관이 큰 피처는 First24h_Likes 0.973, First24h_Views 0.973, Channel_Subscribers 0.905, First24h_Comments 0.807 순입니다 (노트북 출력).

학습하이퍼파라미터 없음 (기본값) 에폭 / 스텝 해당 없음 학습 시간 [미확인] (노트북에 시간 측정이 없음) 하드웨어 CPU (…
항목 값
하이퍼파라미터 없음 (기본값)
에폭 / 스텝 해당 없음
학습 시간 [미확인] (노트북에 시간 측정이 없음)
하드웨어 CPU (scikit-learn). 장비 이름 [미확인]
프레임워크 scikit-learn 1.9.0, pandas 3.0.5, numpy 2.4.6
시드 · 재현 방법 train_test_split(test_size=0.2, random_state=42)
결과test 300개 기준, 노트북 출력입니다. R² 0.856 -8.83 test 300 Ridge 0.856, 랜덤 포레스트 …

test 300개 기준, 노트북 출력입니다.

지표 r1 (원래 스케일) r2 (log1p 타깃) 테스트셋 비교 대상
R² 0.856 -8.83 test 300 Ridge 0.856, 랜덤 포레스트 0.788, 그래디언트 부스팅 0.807
MAE 13,424 48,951 test 300 Ridge 13,022, 랜덤 포레스트 10,490, 그래디언트 부스팅 9,802
RMSE 28,081 232,297 test 300 Ridge 28,069, 랜덤 포레스트 34,131, 그래디언트 부스팅 32,555
  • 노트북 해석: RMSE(28,080)가 MAE(13,424)의 약 2배라 "제곱 페널티 때문에 유독 크게 틀린 몇 개의 오차가 전체를 끌어올렸다". EDA에서 본 롱테일 분포와 맞음
  • 노트북 해석: r2는 log 스케일의 작은 오차가 expm1(지수 함수)로 되돌릴 때 크게 부풀어 실패. 상위 5개 영상이 오차제곱합의 93.6%를 차지

추론 성능 (CPU / GPU)

측정 안 함.

장비 장비 이름 배치 크기 지연 시간 (샘플당, p50 / p95) 처리량 (샘플/초) 메모리 사용
CPU [미확인] - 측정 안 함 측정 안 함 측정 안 함
GPU 해당 없음 (scikit-learn은 CPU 전용) - - - -
실험 기록2회 측정 · 대표 r1

같은 모델을 설정·분류기를 바꿔 2번 측정한 기록입니다. ★ r1이(가) 대표 결과(맨 위 수치)입니다.

직전 실행에서 바뀐 설정지표 최고값
실행날짜바뀐 점targetmodelr2maermse학습 시간
★ r1
원래 스케일
2026-08-27기준: 조회수를 그대로 학습rawLinearRegression85.6%1342428081-
r2
log1p 타깃
2026-08-28타깃을 log1p(조회수)로 바꿔 학습하고 expm1로 되돌려 평가
오차제곱합의 93.6%가 상위 5개 영상에서 나옴 (노트북 출력)
log1pLinearRegression-883.3%48951232297-
r2 변화 실행 순서대로 · 높을수록 좋음
r1 · 원래 스케일
85.6%
r2 · log1p 타깃
-883.3%
한계 · 배운 점한계 알려진 실패 유형: 조회수가 아주 큰 영상에서 오차가 큼 (RMSE ≫ MAE) 편향 / 공정성 이슈: 해당 없음 (가상…

한계

  • 알려진 실패 유형: 조회수가 아주 큰 영상에서 오차가 큼 (RMSE ≫ MAE)
  • 편향 / 공정성 이슈: 해당 없음 (가상 데이터)
  • 성능이 떨어지는 입력 조건: 첫 24시간 지표가 클리핑 범위(1~99%)를 넘는 영상 [🚩AI 설명]
  • [🚩AI 설명] 첫 24시간 조회·좋아요가 서로 0.97 이상 상관이라 다중공선성이 있음. 같은 노트북의 Ridge에서 ill-conditioned matrix 경고가 난 것과 연결됨

배운 점

  • 노트북 결론: 이 데이터에서는 Ridge 또는 LinearRegression이 전체적으로 가장 안정적 (R² 기준)
  • 트리 모델(랜덤 포레스트·그래디언트 부스팅)은 MAE는 더 낮지만 RMSE는 더 높음 = 평소엔 더 잘 맞히지만 큰 영상에서 더 크게 틀림 (노트북 해석)
  • 타깃에 log1p를 씌우는 것이 항상 좋은 것은 아님 (r2)
사용 방법코드 셀 4개
In [1]결측·이상치 처리
df['Thumbnail_Score'] = df['Thumbnail_Score'].fillna(df['Thumbnail_Score'].median())
df['Avg_Watch_Percent'] = df['Avg_Watch_Percent'].fillna(df['Avg_Watch_Percent'].median())

outlier_cols = ['Channel_Subscribers', 'First24h_Views', 'First24h_Likes', 'First24h_Comments']
for col in outlier_cols:
    lower = df[col].quantile(0.01)
    upper = df[col].quantile(0.99)
    df[col] = df[col].clip(lower, upper)
In [2]카테고리 원-핫·데이터 나누기
from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
X_encoded = encoder.fit_transform(df[['Category']])
encoded_df = pd.DataFrame(X_encoded, columns=encoder.get_feature_names_out(['Category']))

df = df.drop(columns=['Video_ID', 'Category'])
df = pd.concat([df, encoded_df], axis=1)

X = df.drop(columns=['Seven_Day_Views'])
y = df["Seven_Day_Views"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(X_train.shape, X_test.shape)
Out[2] 출력 보기
(1200, 21) (300, 21)
In [3]학습·평가 (r1)
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, root_mean_squared_error, r2_score

model = LinearRegression()
model.fit(X_train, y_train)
pred = model.predict(X_test)

print(f"mae: {mean_absolute_error(y_test, pred)}")
print(f"rmse: {root_mean_squared_error(y_test, pred)}")
print(f"r2score: {r2_score(y_test, pred)}")
Out[3] 출력 보기
mae: 13424.07833434806
rmse: 28080.873476833556
r2score: 0.8563177368381205
In [4]log1p 타깃 실험 (r2)
import numpy as np

y_train_log = np.log1p(y_train)
log_model = LinearRegression()
log_model.fit(X_train, y_train_log)
log_pred = np.expm1(log_model.predict(X_test))

print(f"mae: {mean_absolute_error(y_test, log_pred)}")
print(f"rmse: {root_mean_squared_error(y_test, log_pred)}")
print(f"r2score: {r2_score(y_test, log_pred)}")
Out[4] 출력 보기
mae: 48950.97589049459
rmse: 232296.95978402696
r2score: -8.83261391215422

같은 과제·데이터셋 비교 tabular-regression · 수업 자료: youtube_7day_views_regression_practice.csv · 4개

굵은 이름이 이 모델입니다. 주황 테두리가 그룹 안 최고값입니다.