오늘은 회귀에 대해서 배우는 수업이었다.
회귀 분석
통계학에서 회귀는 여러 개의 독립 변수와 하나의 종속 변수 사이의 상관 관계를 모델링하는 기법을 통칭한다. 여러 개의 독립 변수에 따라 하나의 종속 변수가 어떤 관계를 나타내는지 모델링하고 연속적인 값을 예측하는 방법이다. 여기서 종속 변수 Y, 독립 변수 X에 영향을 미치는 회귀 계수가 W이다.
Y = W1*X1 + W2*X2 + ... + Wn*Xn
독립 변수의 갯수에 따라 단일 회귀와 다중 회귀, 회구 계수가 선형이냐 아니냐에 따라 선형회귀와 비선형회귀로 구분한다.
파이썬으로 보스톤 집값 데이터를 가지고 직접 선형회귀분석하는 연습을 해보았다.
X = bostonDF.drop('target', axis=1).values
y = bostonDF['target'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=156)
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
rmse
결과는 np.float64(4.158956107955705) 이고, R2 score도 살펴보면 np.float64(0.7572263323138934) 로 나오므로 이 모델의 성능은 상당히 좋다고 할 수 있다.
이후에는 premium.csv라는 데이터를 가지고 보험료 예측 모델을 작성 후 평가도 해보았다.

교차검증도 했었고 결과는 아래와 같이 나왔다.

확실히 교차 검증 후 R2 score가 조금 나아졌지만 RMSE가 너무 높아서 모델의 성능이 좋다고 평가하기는 어렵다.
이 이후에도 다른 데이터셋으로 '자전거 대여량 예측 모델'을 작성 후 평가해보며 오늘 하루 세 가지의 데이터셋으로 선형회귀 코딩을 계속 하였다. 오늘 수업을 통해 회귀 분석이 단순히 값을 예측하는 도구를 넘어서, 변수 간의 관계를 해석하는 중요한 기법이라는 점을 배웠다. 모델이 잘 맞는다고 생각했지만, 교차 검증 결과나 다른 모델 사용시에는 성능 평가가 다르게 나타난다는 점도 흥미로웠다. 보험료 예측 모델이나 자전거 대여량 예측 모델에서는 성능이 기대보다 낮았던 이유를 되짚어보며, 데이터 전처리나 변수 선택의 중요성도 다시 느꼈다.

규제는 과적합 모델(Overfitting Model)을 일반화된 모델(Generalization)로 변환하여 모델이 학습 데이터에 지나치게 맞춰지는 것을 방지하고, 새로운 데이터에도 잘 작동하도록 도와준다. 규제는 모델의 복잡도를 제한하여 더 안정적이고 일반화된 모델을 만들며, 이는 예측 성능을 향상시키는 데 중요한 역할을 한다.
규제는 크게 L2 방식과 L1 방식으로 나눈다.
L2 규제를 적용한 릿지(Ridge) 회귀, L1 규제를 적용한 라쏘(Lasso) 회귀, 두 가지 규제를 합한 것이 엘라스틱넷(Elastic Net)이며, Ridge와 Lasso는 기존 다중 선형 회귀 모델의 손실 함수에 계수 크기에 대한 페널티를 더한 함수를 사용하여 모델을 학습한다.
Ridge(L2 규제)회귀

알파는 사용자가 정의한 하이퍼파라미터로 모델을 얼마나 규제할지 그 정도를 조절하는 일을 한다. 만일 알파가 0의 값을 가지면 두번째 항 전체가 0이 되므로 원래 비용함수와 동일할 것이다. 반대로 알파가 매우 큰 값을 가지면 모든 파라미터가 거의 0에 가까워 져서 결국 데이터의 평균을 지나는 수평선이 될 것이다.(과소적합) 하지만 릿지 회귀의 경우 회귀 계수를 0으로 만들지는 않는다.
규제가 강해질수록 (α 증가) → 예측 오차/RSS 증가 (덜 민감하게 됨) → 일부 입력 변수의 계수가 0에 가까워져서 사실상 모델이 사용하는 입력변수의 수가 줄어드는 효과
그래서 Ridge의 훈련 데이터는 전체적으로 선형 회귀의 점수보다 낮으나 데이터가 충분히 많으면 규제항은 덜 중요해져서 릿지 회귀와 선형 회귀의 성능은 같아지게 된다. 그래서 벌칙 penalty 라고 부르기도 한다.
Lasso(L1 규제)회귀

L1 규제는 w의 절댓값에 패널티를 부여하는 방식이다. 라쏘 회귀는 전체 입력변수 계수 중 일부를 0으로 만들어 입력 변수를 선택하게 한다. 일반적으로는 Ridge를 선택하지만, 특성이 굉장히 많고 그 중 일부만 중요한 특성인 경우 또한 일부 특성만으로 분석하기 쉬운 모델을 원할 경우 선택하는 것이 라쏘 회귀이다.
가중치 α의 값이 커질수록 규제는 강해지며 모델은 일반화된다.
엘라스틱넷(Elastic Net)회귀
엘라스틱넷은 L1과 L2 규제를 동시에 사용하여 Lasso의 희소성(sparsity)과 Ridge의 안정성(stability)을 모두 얻는 것을 목표로 한다.

오늘은 어제 했던 데이터들을 가지고 뒤이어 규제 회귀 모델에 대해서 직접 코딩해보고 보고서를 작성하였다.
ridge = Ridge(alpha=1) # 규제 강도
ridge.fit(X_train, y_train)
pred_ridge = ridge.predict(X_test)
mse = mean_squared_error(y_test, pred_ridge)
r2 = r2_score(y_test, pred_ridge)
mse, r2
결과는 :
(np.float64(17.206833316177068), np.float64(0.7584907011357223))
lasso = Lasso(alpha=1) # 규제 강도
lasso.fit(X_train, y_train)
pred_lasso = lasso.predict(X_test)
mse = mean_squared_error(y_test, pred_lasso)
r2 = r2_score(y_test, pred_lasso)
mse, r2
결과는 :
(np.float64(22.137098759778443), np.float64(0.6892911611262599))
enet = ElasticNet(alpha=0.1, l1_ratio=0.5)
enet.fit(X_train, y_train)
pred_enet = enet.predict(X_test)
print("엘라스틱넷 회귀")
print(f"MSE : {mean_squared_error(y_test, pred_enet)}")
print(f"R2 : {r2_score(y_test, pred_enet)}")
결과는 :
엘라스틱넷 회귀
MSE : 18.11673827943616
R2 : 0.7457195824951279
이렇게 각 모델의 성능도 비교해보며 이후에는 자전거(bike) 대여 데이터셋을 가지고 대여량(count)를 예측하는 모델 보고서를 직접 작성해보았다. 데이터 컬럼은 다음과 같다.

전처리 진행 후 여러 모델들을 만들어보고, 스케일링도 해보고, 교차검증도 해보았고 그 결과 각 모델들에 대한 성능을 보고서 [결론]부분에 정리해놓았다.

해당 보고서를 내 깃허브에 나름 잘 정리해두었으니 아래에서 확인할 수 있다. 😎
📑 모델예측_자전거 대여량 예측하기
이번 실습과 보고서를 통해 Ridge와 Lasso, ElasticNet을 각각 적용해보며 모델이 과적합되지 않도록 제어하는 역할을 명확히 이해하게 되었다. 또한 다양한 모델을 실험하며 데이터 스케일링, 교차검증, 하이퍼파라미터 조절의 중요성도 다시금 느낄 수 있었다. 자전거(bike) 대여량 예측 모델 보고서를 통해 실제 데이터를 다루는 보고서 작성의 경험도 조금씩 익숙해지는 것 같다. 전체적으로 오늘 수업은 회귀 분석의 실전 감각을 기르는 데 매우 도움이 되었고, 앞으로도 보고서를 작성한다면 오늘 작성했던 보고서를 많이 참고할 것 같다.
오늘은 군집 분석에 대해서 배웠다.
K-means Clustering은 가장 일반적으로 사용하는 알고리즘이다. 군집의 중심(Centroid)이라는 특정한 임의의 지점을 선택하고 해당 중심에 가장 가까운 포인트들을 선택하는 군집과 기법이다. K는 군집 수를 지정하는 하이퍼파라미터이다. 수행 절차는 다음과 같다.
- 각 개체를 가까운 초기값에 할당해서 군집 형성한다.
- 형성한 각 군집의 평균을 재계산한 결과로 초기값을 갱신한다.
- 초기값이 더 이상 갱신 되지 않을 때까지 반복한다.
실루엣(silhouette) 분석은 각 군집 간의 거리를 측정해서, 얼마나 효율적으로 분리되었는지를 나타내는 기법이다.
K-means 알고리즘으로 iris 데이터로 품종 구분하는 실습을 해보았다.
iris = load_iris()
iris_df = pd.DataFrame(data=iris.data, columns=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])
KM = KMeans(n_clusters=3, init='k-means++', max_iter=300, random_state=0)
KM.fit(iris_df)
iris_df['target'] = iris.target # 실제값
iris_df['cluster'] = KM.labels_
iris_df.groupby(['target', 'cluster'])['sepal_length'].count()
결과는 :

그리고 실루엣 계수도 측정하고 차트도 그려보았다.
score_samples = silhouette_samples(iris.data, iris_df['cluster'])
iris_df['silhouette_coeff'] = score_samples
silhouette_score(iris.data, iris_df['cluster'])
y_lower = 10
for i in range(3):
cluster_i = score_samples[iris_df['cluster']==i]
cluster_i.sort()
y_upper = y_lower + len(cluster_i)
plt.barh(range(y_lower, y_upper), cluster_i, label=f'Cluster{i}')
y_lower = y_upper
avg_score = silhouette_score(iris.data, iris_df['cluster'])
plt.axvline(avg_score, color='red', linestyle='--', label='Avg Score')
plt.legend()
plt.show()
결과는 :

이 다음에는 엘보우(Elbow) 기법을 사용해 스크리 차트도 그려보았다.

주성분 분석(PCA)은 상관성이 높은 여러 변수들의 선형 조합으로 새로운 주성분으로 축소, 데이터를 압축하는 분석 기법이다.
마찬가지로 iris 데이터로 PCA를 사용하여 2개의 주성분으로 축소 후 시각화하는 코드를 작성해보았다.
pca = PCA(n_components=2)
pca_transformed = pca.fit_transform(iris.data)
pca_transformed.shape
iris_df['pca_x'] = pca_transformed[:, 0]
iris_df['pca_y'] = pca_transformed[:, 1]
plt.scatter(x=iris_df.loc[iris_df['cluster']==0, 'pca_x'],
y=iris_df.loc[iris_df['cluster']==0, 'pca_y'], marker='o', color='red')
plt.scatter(x=iris_df.loc[iris_df['cluster']==1, 'pca_x'],
y=iris_df.loc[iris_df['cluster']==1, 'pca_y'], marker='o', color='blue')
plt.scatter(x=iris_df.loc[iris_df['cluster']==2, 'pca_x'],
y=iris_df.loc[iris_df['cluster']==2, 'pca_y'], marker='o', color='green')
plt.show()
결과는 :

이후에 스케일링도 해준 후 주성분 2개로 축소하여 그려보기도 하고, cancer(유방암) 데이터로 kmeans, 2개의 주성분, 스케일링, 시각화하는 코딩을 실습해보았다.
K-means로 데이터를 군집화하는 과정과 엘보우 기법으로 최적의 군집 수를 찾는 실습이 흥미로웠다. 또한, PCA(주성분 분석)를 활용해 고차원의 데이터를 2차원으로 축소하여 시각화한 과정이 데이터를 직관적으로 이해하는 데 도움이 되었다. 주성분 개수를 바꿔가며 분석 결과가 달라지는 것도 확인할 수 있었다.
오늘은 중고차 판매 데이터로 보고서를 작성하는 것으로 시간을 보냈다. 우선 가지고 있는 데이터의 컬럼들을 먼저 파악부터 한다. 변수들은 다음과 같다.

결측치가 있는 컬럼은 4개title, no_of_cylinders, year, motors_trim이고 결측값 전처리를 먼저 진행하였다. 우리의 목표인 종속변수는 중고차 가격 price_in_aed이고 결측치들 중 가격에 영향을 미치지 않을 것 같은 title컬럼은 드롭하였다. no_of_cylinders컬럼은 문자열 제거 및 숫자형으로 변환하고 year과 motors_trim의 결측치는 각각 중앙값과, 최빈값으로 채워넣었다.
결측치들은 다 처리하였지만 변수들의 타입을 보면 범주형 변수(Object)가 많다. 그래서 모든 범주형 변수들의 컬럼들을 unique()함수를 사용하여 고유한 값들이 몇 개 존재하는지 파악하고 고유값 개수가 적은 컬럼들은 레이블 인코딩, 많은 컬러들은 원핫인코딩으로 처리하였다. 그 후 상관관계를 파악하기 위한 히트맵도 하나 그렸다.

이 이후에는 저번에 했던 자전거 대여량 보고서와 비슷하게 회귀 모델들을 만들고 성능을 평가해보았다. 그 결과 어떤 모델이 가장 성능이 좋은 지 보고서로 작성하였다.

모델 학습 및 평가 결과, 랜덤 포레스트 회귀 모델이 중고차 가격 예측에 있어 가장 우수한 성능을 보이는 것으로 확인되었다. 특히 교차 검증을 통해 평가된 Random Forest (CV) 모델은 RMSE 1.80e+05로 가장 낮은 오차를 기록했으며, R2 Score 0.82로 가장 높은 설명력을 보여준다. 이는 모델이 중고차 가격의 변동성을 약 82% 설명할 수 있음을 의미하며, 실제 가격을 상당히 정확하게 예측하고 있음을 시사한다.
해당 보고서를 내 깃허브에 나름 잘 정리해두었으니 아래에서 확인할 수 있다. 😎
📑 모델예측_중고차 가격 예측하기
이번주는 보고서 작성에 대부분의 시간을 보내기도 했고 팀원들과 해커톤에 나가기로 하여서 회의도 하고 기획서도 작성하느라 바쁘게 지나갔다. 이번 보고서를 작성하다보니 모든 과정 중에서 전처리 부분이 가장 오래 걸렸고 그만큼 데이터 전처리가 정말 중요하다는 것을 깨달았다. 오늘로 파이썬 관련 과목은 마무리하고 내일부턴 클라우드 기반 데이터 처리에 대해서 새롭게 배운다. 클라우드도 아주 중요한 과목이라고 많이 들어서 내일부터 새로운 마음으로 다시 집중해보겠다.
오늘부터 클라우드 기반 데이터 처리/저장/관리 기술에 대하여 배우기 시작한다. 처음은 우선 이론 위주로 새로운 개념들을 많이 접했다.
컴퓨터 프로그램을 원격에서 호출할 수 있도록 하는 아이디어가 RPC(Remote Procedure Call)이다. 기본적으로 Client - Server간 연결에서 주는 쪽과 받는 쪽에서 보낼 때 Pack, 받을 때 Unpack하는 양방향 통신이다.
분산시스템
분산시스템은 여러 독립적인 컴퓨터 시스템이 네트워크를 통해 서로 통신하고 협력하여 마치 하나의 컴퓨터처럼 동작하는 시스템이다. 이는 scale-up의 물리적 한계를 극복하고 scale-out을 통해 성능, 안정성, 그리고 확장성을 확보하는 아키텍처 접근법이며 시스템 전체의 가용성을 높이는 데 중요한 역할을 한다.
- scale-up : 시스템의 처리 능력을 향상시키기 위해 기존 서버의 성능을 높이는 방식이다. 하지만 이 접근법은 물리적, 비용적 한계가 있어 무한정 확장하기 어렵다는 단점이 존재한다.
- scale-out : 시스템의 처리 능력을 향상시키기 위해 여러 대의 서버를 추가하는 방식이다. 단일 서버의 성능을 높이는 scale-up과 달리, 여러 대의 서버에 부하를 분산시켜 전체 시스템의 성능을 향상시킨다. 이 방식은 효율적이며 높은 확장성과 가용성을 제공하지만, 서버 간 데이터 동기화와 관리의 복잡성이 증가한다는 단점이 존재한다.
CAP 이론은 시스템 장애로 인해 몇몇의 인스턴스가 다른 인스턴스와 통신할 수 없을 때 전체 데이터베이스를 어떻게 제어할 지 결정한다.
- Consistency(일관성)
- 여러 서버에 데이터가 분산되어 있어도, 같은 정보를 요청하면 항상 같은 답을 받을 수 있다.
- 여러 사용자가 동시에 요청해도 모두 같은 결과를 받는다.
- Availability(가용성)
- 시스템은 언제든지 사용할 수 있어야 한다.
- 일부 서버에 문제가 생겨도 전체 시스템은 계속 작동해야 한다.
- Partition-Tolerance(분할내성, 분산허용)
- 서버들 사이에 통신 문제가 생겨도 각 서버는 자기 역할을 계속 수행할 수 있다.
📌하나의 분산 시스템에서 C, A, P를 모두 완벽히 구현할 수 없다.
빅데이터 플랫폼은 기업 내 많은 사용자들이 데이터를 처리하고 분석을 쉽게 할 수 있는 환경을 제공해 주는 시스템을 일컫는다. 그리고 이러한 빅데이터 플랫폼을 구축하기 위해 고려해야 할 것이 많다. 일반적으로 빅데이터 플랫폼을 구축하기 위한 요구 사항은 다음과 같다.
데이터 웨어하우스
데이터 웨어하우스는 빅데이터 적재 시스템 중 하나로 대규모 데이터를 저장하고 필요한 데이터에 대한 쿼리를 실행하기 위해 설계된 데이터베이스이다.
데이터 레이크
데이터 레이크는 빅데이터 아키텍처에서 사용되는 적재 시스템 중 하나로 대규모 데이터를 실시간으로 수집하여, 저장하며, 처리한다.
데이터 플랫폼의 목적은 분석에 활용될 수 있도록 어떤 유형의 데이터든 비용 효과적으로 데이터를 수집, 저장, 처리해서 활용할 수 있도록 제공하는 것이다. 실제 데이터 플랫폼의 아키텍처를 draw.io로 배우면서 아래와 같이 그려보았다.

오늘은 클라우드 기반 데이터 처리 및 저장 기술의 첫 이론 수업으로, 핵심 개념들을 폭넓게 접할 수 있었다. 처음이라서 생소했던 개념들을 이해하는 데 집중했다. 아직은 개념 중심이지만, 앞으로 실습을 통해 이를 어떻게 구현하고 활용하는지를 배울 생각에 기대도 되고 걱정도 된다. 이번 주에는 실습도 하고 보고서도 작성하고 이론도 배우고 해커톤 공모전 기획서도 작성하여 바쁘게 시간을 보냈다. 공모전 기획서는 다음 주에 제출할 예정이고 당연히 잘 됐으면 좋겠지만 안되더라도 실패를 기회 삼아 다음 도전에 열심히 해봐야겠다. 🤗