scikit-learn으로 LinearRegression 훈련
sklearn.linear_model.LinearRegression을 사용해 훈련 데이터에 모델을 적합하고, 예측을 수행하며, 학습된 계수를 확인합니다.
scikit-learn으로 LinearRegression 훈련은(는) CoddyKit의 무료 Machine Learning Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Machine Learning Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Machine Learning Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
scikit-learn's LinearRegression API
Scikit-learn's LinearRegression class provides a clean, consistent API for fitting ordinary least-squares linear regression. Like all scikit-learn estimators, it follows the same pattern: instantiate, fit, predict.
Under the hood, it uses the Normal Equation (or a numerically stable SVD decomposition for large feature matrices) to find the exact optimal weights in a single computation — no iterative training loop is needed. This makes it extremely fast even on large datasets with many features.
from sklearn.linear_model import LinearRegression
import numpy as np
# Instantiate with optional parameters
model = LinearRegression(
fit_intercept=True, # default: add bias term
copy_X=True, # don't modify input arrays
n_jobs=-1 # use all CPU cores
)
print(model) # shows default parametersPreparing the Data
Before training, your data must be in the correct shape. scikit-learn expects:
- X — a 2D array of shape
(n_samples, n_features) - y — a 1D array of shape
(n_samples,)
The most common shape error is passing a 1D array for X when you have one feature. The fix is to reshape with .reshape(-1, 1). Always split into training and test sets before any fitting — evaluation on training data gives misleadingly perfect scores.
import numpy as np
from sklearn.model_selection import train_test_split
# Simulate housing data
np.random.seed(42)
sqft = np.random.uniform(500, 3000, 200)
price = 150 * sqft + 50000 + np.random.normal(0, 25000, 200)
# Reshape X to 2D (n_samples, n_features)
X = sqft.reshape(-1, 1) # shape (200, 1)
y = price # shape (200,)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print('Train size:', X_train.shape, '| Test size:', X_test.shape)Fitting the Model
Calling model.fit(X_train, y_train) computes the optimal weights using the Normal Equation and stores them inside the model object. After fitting, two attributes become available:
model.coef_— an array of weights, one per featuremodel.intercept_— the bias term (scalar)
The trailing underscore in attribute names is a scikit-learn convention indicating that the attribute was set during fitting — it does not exist before fit() is called.
from sklearn.linear_model import LinearRegression
import numpy as np
from sklearn.model_selection import train_test_split
np.random.seed(42)
X = np.random.uniform(500, 3000, 200).reshape(-1, 1)
y = 150 * X.ravel() + 50000 + np.random.normal(0, 25000, 200)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = LinearRegression()
model.fit(X_train, y_train)
print(f'Slope (coef_): {model.coef_[0]:.2f}') # should be ~150
print(f'Intercept: {model.intercept_:.2f}') # should be ~50000Making Predictions
After fitting, call model.predict(X) to generate predictions. This computes the dot product of the feature matrix with the learned weights, plus the intercept. You can predict on training data, test data, or entirely new data.
Remember: evaluating on training data is not a valid performance estimate. Always evaluate on the held-out test set to get an honest estimate of how well the model will perform on unseen data.
# Predict on test set
y_pred = model.predict(X_test)
print('First 5 predictions vs actual:')
for actual, pred in zip(y_test[:5], y_pred[:5]):
print(f' Actual: ${actual:,.0f} | Predicted: ${pred:,.0f} | Error: ${actual-pred:,.0f}')
# Predict a single new house
new_house = np.array([[1750]]) # must be 2D
print(f'\nPrediction for 1750 sqft: ${model.predict(new_house)[0]:,.0f}')Evaluating on the Test Set
Use scikit-learn's metrics functions to quantify test-set performance. The model.score(X_test, y_test) shortcut returns R² directly. For the full picture, also compute RMSE and MAE.
Comparing these metrics across different models (e.g., linear regression vs random forest) allows you to objectively select the best approach for your dataset. Always include a naive baseline (like always predicting the mean of y) to confirm your model is actually adding value.
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
y_pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f'Test RMSE: ${rmse:,.0f}')
print(f'Test MAE: ${mae:,.0f}')
print(f'Test R2: {r2:.3f}')
# Baseline: always predict the mean
baseline_rmse = np.sqrt(((y_test - y_train.mean()) ** 2).mean())
print(f'Baseline RMSE: ${baseline_rmse:,.0f} (must beat this!)')Visualising the Regression Line
After fitting, plot the learned regression line on top of the training data scatter plot. This visual check answers: does the line make sense? Is it in roughly the right place? Are there large groups of outliers that the model consistently misses?
For a single-feature model this is straightforward. For multi-feature models you will need to plot predictions vs actual values (a residual plot or a 'predicted vs actual' scatter plot) instead, since the decision boundary lives in high-dimensional space.
import matplotlib.pyplot as plt
import numpy as np
# Plot training data and the fitted line
plt.figure(figsize=(8, 5))
plt.scatter(X_train, y_train, alpha=0.4, label='Training data')
plt.scatter(X_test, y_test, alpha=0.4, color='orange', label='Test data')
# Draw the regression line across the full range
x_range = np.linspace(500, 3000, 100).reshape(-1, 1)
y_range = model.predict(x_range)
plt.plot(x_range, y_range, 'r-', linewidth=2, label='Regression line')
plt.xlabel('Square Footage')
plt.ylabel('Price ($)')
plt.legend()
plt.title('Linear Regression Fit')
plt.show()Interpreting the Coefficients
The learned coef_ values carry direct business interpretation. For a house-price model with multiple features, each coefficient tells you how much the predicted price changes when that feature increases by one unit, holding all other features constant (the ceteris paribus interpretation).
However, this interpretation is only valid when features are on similar scales. If one feature is in metres and another is in kilometres, their coefficients are not directly comparable. Always scale features before interpreting coefficients in multi-feature models.
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
import numpy as np
import pandas as pd
# Multi-feature housing data
features = ['sqft', 'bedrooms', 'bathrooms', 'age']
np.random.seed(0)
X_data = pd.DataFrame({
'sqft': np.random.randint(600, 3000, 100),
'bedrooms': np.random.randint(1, 6, 100),
'bathrooms': np.random.randint(1, 4, 100),
'age': np.random.randint(1, 50, 100)
})
y_data = 150*X_data['sqft'] + 8000*X_data['bedrooms'] - 500*X_data['age'] + 30000
model = LinearRegression().fit(X_data, y_data)
for feat, coef in zip(features, model.coef_):
print(f'{feat}: {coef:.1f}')Residual Analysis
Plotting residuals against predicted values is a critical diagnostic step. For a well-fit model, residuals should be randomly scattered around zero with no discernible pattern. Systematic patterns indicate a problem:
- A funnel shape (residuals spread more for larger predictions) indicates heteroscedasticity — the variance of errors is not constant.
- A curved pattern indicates the true relationship is non-linear and a linear model is under-fitting.
- Residuals that are systematically positive or negative for certain prediction ranges mean the model is biased in that region.
import matplotlib.pyplot as plt
import numpy as np
y_pred = model.predict(X_test)
residuals = y_test - y_pred
plt.figure(figsize=(8, 5))
plt.scatter(y_pred, residuals, alpha=0.5)
plt.axhline(y=0, color='red', linestyle='--', linewidth=1.5)
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
plt.title('Residual Plot (should be random scatter around 0)')
plt.show()
print(f'Mean residual: {residuals.mean():.2f} (should be ~0)')
print(f'Std of residuals: {residuals.std():.2f}')Regularised Linear Regression
Plain LinearRegression can overfit when you have many features relative to training examples, or when features are highly correlated (multicollinearity). Scikit-learn provides two regularised variants:
- Ridge (L2 regularisation) — shrinks all coefficients towards zero proportionally, keeping all features but reducing their magnitude.
- Lasso (L1 regularisation) — shrinks some coefficients all the way to zero, effectively performing feature selection.
The alpha parameter controls regularisation strength: higher alpha = more shrinkage = simpler model.
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
import numpy as np
np.random.seed(42)
X = np.random.randn(100, 20) # 20 features, many irrelevant
y = 3*X[:, 0] + 2*X[:, 1] + np.random.randn(100)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
for name, model in [('OLS', LinearRegression()),
('Ridge', Ridge(alpha=1.0)),
('Lasso', Lasso(alpha=0.1))]:
model.fit(X_train, y_train)
print(f'{name} R2: {r2_score(y_test, model.predict(X_test)):.3f}')Cross-Validation Score
A single train-test split can give a misleadingly high or low estimate of model performance depending on which examples happen to land in the test set. Cross-validation gives a more reliable estimate by averaging performance across multiple folds.
Use cross_val_score for a quick k-fold evaluation without manually splitting data. The returned scores are one per fold; report the mean and standard deviation to convey both expected performance and variability.
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
import numpy as np
np.random.seed(42)
X = np.random.randn(200, 3)
y = 2*X[:, 0] - X[:, 1] + np.random.randn(200)*0.5
model = LinearRegression()
scores = cross_val_score(
model, X, y,
cv=5, # 5-fold cross-validation
scoring='r2' # use R2 as the metric
)
print('CV R2 scores per fold:', scores.round(3))
print(f'Mean R2: {scores.mean():.3f} (+/- {scores.std():.3f})')End-to-End Pipeline
In professional ML workflows, preprocessing and the model are always combined into a Pipeline. This prevents data leakage during cross-validation (the scaler is fitted on each training fold separately) and simplifies deployment (one object to save and load).
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
import numpy as np
np.random.seed(42)
X = np.random.randn(200, 3)
y = 2*X[:, 0] - X[:, 1] + np.random.randn(200)*0.5
# Scale + Fit in one object
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', LinearRegression())
])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='r2')
print(f'Pipeline CV R2: {scores.mean():.3f} (+/- {scores.std():.3f})')
# Fit once for deployment
pipeline.fit(X, y)
print('Pipeline fitted and ready for deployment.')Quick Check
Test your understanding of Machine Learning with Python concepts from this lesson.
Lesson Recap
In this lesson you learned: fit() computes optimal weights stored in coef_ and intercept_, predict() applies the learned line to new data, and residual plots reveal whether the linear assumption holds or a more complex model is needed. Next up we extend linear regression to multiple features, learn how to interpret each coefficient as a measure of feature importance, and evaluate with R-squared.
자주 묻는 질문
“scikit-learn으로 LinearRegression 훈련” 강의는 무료인가요?
네 — “scikit-learn으로 LinearRegression 훈련” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Machine Learning Academy 강의 전체를 잠금 해제할 수 있습니다. Machine Learning Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“scikit-learn으로 LinearRegression 훈련”에서 뭘 배우나요?
sklearn.linear_model.LinearRegression을 사용해 훈련 데이터에 모델을 적합하고, 예측을 수행하며, 학습된 계수를 확인합니다. 브라우저에서 직접 실행하는 실습 코드로 Machine Learning Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Machine Learning Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Machine Learning Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“scikit-learn으로 LinearRegression 훈련” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Machine Learning Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Machine Learning Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 직선의 방정식: 기울기, 절편, 예측
- 비용 함수와 최소제곱법
- scikit-learn으로 LinearRegression 훈련
- 다중 선형 회귀와 특성 중요도