[Week 7] My First Predictive Model: Linear Regression Exercise ๐Ÿค–

English translation

Welcome to Week 7!
After 4 weeks of Python basics, we will now build a Machine Learning model ourselves.

Remember the Linear Regression theory from Week 1?
It finds the optimal line (W, b) by minimizing Cost.

Today, using the scikit-learn library,
we will implement this entire process in code.

๐Ÿ› ๏ธ Module 1: The Big Picture of a Machine Learning Project

In Week 1, we compared several candidate lines
to find the optimal W and b that minimize Cost.

scikit-learn handles this complex optimization process
with a single simple command, model.fit().

Standard Machine Learning Workflow:
The standard process we will follow in all future Machine Learning projects.
Remember these 5 steps.

  1. Prepare Data
  2. Split the Data
  3. Train the Model
  4. Evaluate Model
  5. (Application) Predict

๐Ÿš€ Module 2: Linear Regression Modeling Step by Step

We will model California housing price data.

"How does the average number of rooms affect house prices?"

Let's build a predictive model that answers this question, step by step.

Step 1: Prepare the Data

First, load the tools (libraries) and data needed for analysis.

# Import the required libraries.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

# Load the data built into scikit-learn.
housing = fetch_california_housing()

The data has been loaded.
Now specify the inputs (X) and targets (y) we will use from this dataset.

[Supplement] Data Shapes Required by scikit-learn Models

Before feeding data into a model, we need to understand scikit-learn's basic design principles.

1. Basic Equation (Scalar โ†’ Scalar)
The familiar equation of a line is y=wx+by = wx + b.
One input (xx) produces one output (yy).

2. Handling Multiple Data Points (Vector โ†’ Vector)
Real data contain multiple values.
Thus, the input (xx) and output (yy) become Vectors (1-dimensional arrays) holding multiple values.

3. Handling Multiple Features (Matrix โ†’ Vector)
What happens to the input if we add 'hours of sleep' alongside 'hours of study'?
The input becomes a Matrix (2-dimensional array).

In scikit-learn:
Models are designed for the most common case 3 (Matrix โ†’ Vector).
The model input X must always be a 2-dimensional array with Shape (number of data points, number of features).

This is why, even when using only one feature,
we need a 2-dimensional array with n_features equal to 1.

Following the explanation above, specify
the inputs (X) and targets (y) from the dataset in the correct shapes.

# housing.data[:, 2] -> A 1D Vector with shape (20640,)
# housing.data[:, 2:3] -> A 2D Matrix with shape (20640, 1)

# Extract the 'AveRooms' feature (Index 5) as a 2D array
X = housing.data[:, 2:3]
y = housing.target

Before feeding data into a model,
check whether our hypothesis ("Room count and price have a linear relationship") is reasonable
by inspecting the data visually.

This is called Exploratory Data Analysis (EDA),
and visualization is one of its most basic methods.

# Examine the relationship in the data using a scatter plot
plt.figure(figsize=(6, 4))
plt.scatter(X, y, alpha=0.1)

plt.title("Average number of rooms vs. price")
plt.xlim(0,20)
plt.xlabel("AveRooms")
plt.ylabel("MedHouseVal)")
plt.grid(True)
plt.show()

print("์„ ํ˜• ๊ด€๊ณ„์ผ๊นŒ??")
<Figure size 600x400 with 1 Axes>
์‹คํ–‰ ๊ฒฐ๊ณผ
์„ ํ˜• ๊ด€๊ณ„์ผ๊นŒ??

Step 2: Split Data

Now prepare for modeling.
As we learned in Week 1,
evaluating a model's true ability requires splitting data into 'practice problems' and a 'real exam'.
Use the train_test_split function.

# Split the data in an 8:2 ratio
# random_state=42 : Fix the random seed for reproducibility
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

print(f"์—ฐ์Šต ๋ฌธ์ œ ๊ฐœ์ˆ˜: {len(X_train)}๊ฐœ")
print(f"์‹ค์ „ ์‹œํ—˜ ๊ฐœ์ˆ˜: {len(X_test)}๊ฐœ")
์—ฐ์Šต ๋ฌธ์ œ ๊ฐœ์ˆ˜: 16512๊ฐœ
์‹ค์ „ ์‹œํ—˜ ๊ฐœ์ˆ˜: 4128๊ฐœ

Step 3: Train the Model

Data preparation is complete.
Now load scikit-learn's LinearRegression model
and train it on the 'practice problem' data.

The model.fit() function performs this training.

# 1. Create a Linear Regression model object (instance)
model = LinearRegression()

# 2. Train the model on 'practice problems' (fit)
# This code automatically finds the optimal W and b.
model.fit(X_train, y_train)

print("๋ชจ๋ธ ํ•™์Šต์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!")
๋ชจ๋ธ ํ•™์Šต์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!

When training is complete,
the model has found the optimal slope (WW) and intercept (bb).

You can inspect the learned results using model.coef_ and model.intercept_.

# Inspect the optimal W and b found by the trained model
W = model.coef_[0]
b = model.intercept_

print(f"ํ•™์Šต๋œ ๊ธฐ์šธ๊ธฐ(W): {W:.4f}")
print(f"ํ•™์Šต๋œ ์ ˆํŽธ(b): {b:.4f}")
print(f"\n=> ์ตœ์ข… ๋ชจ๋ธ: y = {W:.4f} * x + {b:.4f}")
ํ•™์Šต๋œ ๊ธฐ์šธ๊ธฐ(W): 0.0768
ํ•™์Šต๋œ ์ ˆํŽธ(b): 1.6548

=> ์ตœ์ข… ๋ชจ๋ธ: y = 0.0768 * x + 1.6548

๐Ÿ’ฏ Module 3: How Good Is This Model?

Step 4: Evaluate Performance

The model has found an optimal formula.
We must now evaluate its usefulness with an objective score.

Evaluate the regression model using R-squared (coefficient of determination) on the 'actual exam' data.

In general, if the magnitude of the coefficient of determination is at least 0.3,
the regression model is considered reasonably well fitted.

# Evaluate the model's R-squared score on the 'real exam' data
r2_score = model.score(X_test, y_test)

print(f"๋ชจ๋ธ์˜ R-squared ์ ์ˆ˜: {r2_score:.4f}")
print(f"\n=> ์šฐ๋ฆฌ ๋ชจ๋ธ์€ ๋ฐฉ ๊ฐœ์ˆ˜๋งŒ์œผ๋กœ")
print(f"   ์ฃผํƒ ๊ฐ€๊ฒฉ ๋ณ€๋™์˜ ์•ฝ {r2_score*100:.2f}%๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.")
๋ชจ๋ธ์˜ R-squared ์ ์ˆ˜: 0.0138

=> ์šฐ๋ฆฌ ๋ชจ๋ธ์€ ๋ฐฉ ๊ฐœ์ˆ˜๋งŒ์œผ๋กœ
   ์ฃผํƒ ๊ฐ€๊ฒฉ ๋ณ€๋™์˜ ์•ฝ 1.38%๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Now that we have checked the evaluation score,
plot the line learned by the model to see how well it explains the data.

# Visualize the final results
plt.figure(figsize=(6, 4))

# Scatter plot of the actual data
plt.scatter(X_train, y_train, alpha=0.1, label='Train Data')
plt.scatter(X_test, y_test, alpha=0.1,
            label='Test Data', color='red')

# The optimal line learned by the model
plt.plot(X, model.predict(X), color='black',
         linewidth=3, label='Learned Regression Line')
plt.xlim(0, 20)
plt.ylim(0, 5.5)
plt.title("Linear Regression Model Result")
plt.xlabel("AveRoom)")
plt.ylabel("MedHouseVal")
plt.legend()
plt.grid(True)
plt.show()
<Figure size 600x400 with 1 Axes>
์‹คํ–‰ ๊ฒฐ๊ณผ

Step 5: Predict

The ultimate purpose of a well-trained and validated model is prediction on new data.

Use model.predict() to predict future values.

# What if a house has an average of 5 rooms?
# Model inputs must always be 2D arrays.
new_house_rooms = np.array([[5]])
predicted_price = model.predict(new_house_rooms)

print(f"๋ฐฉ 5๊ฐœ ์ง‘์˜ ์˜ˆ์ธก ๊ฐ€๊ฒฉ: ${predicted_price[0] * 100000:,.2f}")
print(f"(๋‹จ์œ„ ๋ณ€ํ™˜ ์ „ ๊ฐ’: {predicted_price[0]:.2f})")
๋ฐฉ 5๊ฐœ ์ง‘์˜ ์˜ˆ์ธก ๊ฐ€๊ฒฉ: $203,854.02
(๋‹จ์œ„ ๋ณ€ํ™˜ ์ „ ๊ฐ’: 2.04)