Logo

معمل الانحدار الخطي

20 دقيقة قراءة
شرائح الدرس
1 / 16

معمل الانحدار الخطي (Linear Regression)

مقرر AI308 لتعلّم الآلة: من المعادلات المغلقة الشكل إلى مكتبة scikit-learn

تعلم الآلة (AI308)

قسم علوم الحاسب، كلية الحاسبات والمعلومات

جامعة المنصورة


جدول المحتويات

  1. مقدمة في الانحدار الخطي
  2. خوارزمية الانحدار الخطي
  3. الصياغة الرياضية
  4. خطوات الخوارزمية
  5. مثال عددي 1: درجات امتحانات الطلاب
  6. مثال عددي 2: التنبؤ بأسعار المنازل
  7. التنفيذ بلغة Python باستخدام Scikit-Learn
  8. تقييم النموذج
  9. الخلاصة وأهم النقاط

1. مقدمة في الانحدار الخطي

الانحدار الخطي (Linear Regression) هو أسلوب إحصائي أساسي يُستخدم لنمذجة العلاقة بين متغير تابع (dependent variable) (وهو الهدف المراد التنبؤ به) ومتغير مستقل واحد أو أكثر (المتغيرات المستقلة / features). يفترض هذا الأسلوب أن العلاقة بين المتغيرات خطية، ويسعى لإيجاد أفضل خط مستقيم يمر بين نقاط البيانات بأقل قدر من الخطأ.

التطبيقات:

  • التنبؤ بالمبيعات بناءً على الإنفاق الإعلاني
  • توقع أسعار الأسهم
  • تقدير أسعار المنازل بناءً على خصائصها
  • تحليل الاتجاهات (trends) في بيانات السلاسل الزمنية

لماذا الانحدار الخطي؟

  • سهل التنفيذ وسهل التفسير
  • يوفر علاقات كمّية واضحة بين المتغيرات
  • مفيد في التنبؤ وتحليل الاتجاهات
  • يمثل أساسًا تُبنى عليه خوارزميات أكثر تعقيدًا

2. خوارزمية الانحدار الخطي

تهدف خوارزمية الانحدار الخطي إلى إيجاد أفضل خط ممكن (best-fitting line) (أو مستوٍ فائق hyperplane في حالة الأبعاد المتعددة) يُقلّل الفرق بين القيم المتوقَّعة والقيم الفعلية إلى أدنى حد.

معادلة الانحدار الخطي البسيط:

y=β0+β1xy = \beta_0 + \beta_1 x

حيث:

  • yy = المتغير التابع (المُخرَج / الهدف)
  • xx = المتغير المستقل (المُدخَل / الخاصية)
  • β0\beta_0 = نقطة تقاطع المحور y (حد الانحياز bias term)
  • β1\beta_1 = الميل (المُعامل / الوزن)

معادلة الانحدار الخطي المتعدد:

y=β0+β1x1+β2x2+...+βnxny = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + ... + \beta_n x_n

في هذا المعمل، سنركز بشكل أساسي على الانحدار الخطي البسيط (Simple Linear Regression).

3. الصياغة الرياضية

الهدف: تقليل دالة التكلفة (Cost Function)

تقيس دالة التكلفة (cost function) (متوسط مربع الخطأ Mean Squared Error - MSE) متوسط مربع الفرق بين القيم المتوقَّعة والقيم الفعلية:

J(β0,β1)=1ni=1n(yiy^i)2J(\beta_0, \beta_1) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2

=1ni=1n(yi(β0+β1xi))2= \frac{1}{n} \sum_{i=1}^{n} (y_i - (\beta_0 + \beta_1 x_i))^2

حيث:

  • nn = عدد نقاط البيانات
  • yiy_i = القيمة الفعلية
  • y^i\hat{y}_i = القيمة المتوقَّعة

المعادلة الطبيعية (الحل ذو الصيغة المغلقة Closed-Form Solution)

في حالة الانحدار الخطي البسيط، تكون المُعاملات المثلى كالتالي:

الميل (Slope): β1=i=1n(xixˉ)(yiyˉ)i=1n(xixˉ)2=Cov(x,y)Var(x)\beta_1 = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^{n}(x_i - \bar{x})^2} = \frac{Cov(x,y)}{Var(x)}

نقطة التقاطع (Intercept): β0=yˉβ1xˉ\beta_0 = \bar{y} - \beta_1 \bar{x}

حيث:

  • xˉ\bar{x} = متوسط قيم x
  • yˉ\bar{y} = متوسط قيم y

4. خطوات الخوارزمية

الخطوة 1: جمع البيانات وتجهيزها

  • جمع مجموعة البيانات التي تحتوي على المتغير (أو المتغيرات) المستقل xx والمتغير التابع yy
  • تنظيف البيانات (معالجة القيم المفقودة والقيم الشاذة outliers)
  • تنظيم البيانات في صورة جدولية

الخطوة 2: حساب الإحصائيات الوصفية

  • حساب متوسط xx: xˉ=xin\bar{x} = \frac{\sum x_i}{n}
  • حساب متوسط yy: yˉ=yin\bar{y} = \frac{\sum y_i}{n}

الخطوة 3: حساب الانحرافات

لكل نقطة بيانات ii:

  • حساب انحراف x عن المتوسط: (xixˉ)(x_i - \bar{x})
  • حساب انحراف y عن المتوسط: (yiyˉ)(y_i - \bar{y})

الخطوة 4: حساب حواصل الضرب والمربعات

لكل نقطة بيانات ii:

  • حساب حاصل ضرب الانحرافين: (xixˉ)(yiyˉ)(x_i - \bar{x})(y_i - \bar{y})
  • حساب مربع انحراف x: (xixˉ)2(x_i - \bar{x})^2

الخطوة 5: حساب الميل (β1\beta_1)

β1=(xixˉ)(yiyˉ)(xixˉ)2\beta_1 = \frac{\sum(x_i - \bar{x})(y_i - \bar{y})}{\sum(x_i - \bar{x})^2}

الخطوة 6: حساب نقطة التقاطع (β0\beta_0)

β0=yˉβ1xˉ\beta_0 = \bar{y} - \beta_1 \bar{x}

الخطوة 7: تكوين معادلة الانحدار

y^=β0+β1x\hat{y} = \beta_0 + \beta_1 x

الخطوة 8: إجراء التنبؤات

لأي قيمة لـ xx، يمكن حساب: y^=β0+β1x\hat{y} = \beta_0 + \beta_1 x

الخطوة 9: تقييم أداء النموذج

حساب مقاييس مثل:

  • R2R^2 (معامل التحديد Coefficient of Determination)
  • MSE (متوسط مربع الخطأ)
  • RMSE (الجذر التربيعي لمتوسط مربع الخطأ)

5. مثال عددي 1: درجات امتحانات الطلاب

نص المسألة

يريد أحد المعلمين التنبؤ بدرجات امتحانات الطلاب بناءً على عدد ساعات المذاكرة. بيانات 5 طلاب هي كالتالي:

الطالبساعات المذاكرة (x)درجة الامتحان (y)
112
224
335
444
555

المطلوب: إيجاد معادلة الانحدار الخطي، والتنبؤ بدرجة طالب يذاكر 6 ساعات.

الحل: باتباع خطوات الخوارزمية

الخطوة 1: جمع البيانات ✓

تم جمع البيانات وتنظيمها في الجدول أعلاه. عدد المشاهدات: n=5n = 5

الخطوة 2: حساب الإحصائيات الوصفية

متوسط x (ساعات المذاكرة): xˉ=1+2+3+4+55=155=3\bar{x} = \frac{1 + 2 + 3 + 4 + 5}{5} = \frac{15}{5} = 3

متوسط y (درجة الامتحان): yˉ=2+4+5+4+55=205=4\bar{y} = \frac{2 + 4 + 5 + 4 + 5}{5} = \frac{20}{5} = 4

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
# Data
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])
n = len(x)
 
# Calculate means
x_mean = np.mean(x)
y_mean = np.mean(y)
 
print(f"Mean of x (Hours): {x_mean}")
print(f"Mean of y (Score): {y_mean}")
Mean of x (Hours): 3.0
Mean of y (Score): 4.0

الخطوة 3 و4: حساب الانحرافات وحواصل الضرب والمربعات

ixix_iyiy_i(xixˉ)(x_i - \bar{x})(yiyˉ)(y_i - \bar{y})(xixˉ)(yiyˉ)(x_i - \bar{x})(y_i - \bar{y})(xixˉ)2(x_i - \bar{x})^2
112-2-244
224-1001
3350100
4441001
5552124
Σ610

الحسابات:

  • (xixˉ)(yiyˉ)=4+0+0+0+2=6\sum(x_i - \bar{x})(y_i - \bar{y}) = 4 + 0 + 0 + 0 + 2 = 6
  • (xixˉ)2=4+1+0+1+4=10\sum(x_i - \bar{x})^2 = 4 + 1 + 0 + 1 + 4 = 10
# Calculate deviations
x_dev = x - x_mean
y_dev = y - y_mean
 
# Calculate products and squares
xy_product = x_dev * y_dev
x_squared = x_dev ** 2
 
# Create a DataFrame for visualization
df = pd.DataFrame({
    'x_i': x,
    'y_i': y,
    '(x_i - x̄)': x_dev,
    '(y_i - ȳ)': y_dev,
    '(x_i - x̄)(y_i - ȳ)': xy_product,
    '(x_i - x̄)²': x_squared
})
 
print("\nCalculation Table:")
print(df.to_string(index=False))
print(f"\nΣ(x_i - x̄)(y_i - ȳ) = {np.sum(xy_product)}")
print(f"Σ(x_i - x̄)² = {np.sum(x_squared)}")
 
Calculation Table:
 x_i  y_i  (x_i - x̄)  (y_i - ȳ)  (x_i - x̄)(y_i - ȳ)  (x_i - x̄)²
   1    2        -2.0       -2.0                  4.0          4.0
   2    4        -1.0        0.0                 -0.0          1.0
   3    5         0.0        1.0                  0.0          0.0
   4    4         1.0        0.0                  0.0          1.0
   5    5         2.0        1.0                  2.0          4.0
 
Σ(x_i - x̄)(y_i - ȳ) = 6.0
Σ(x_i - x̄)² = 10.0

الخطوة 5: حساب الميل (β1\beta_1)

β1=(xixˉ)(yiyˉ)(xixˉ)2=610=0.6\beta_1 = \frac{\sum(x_i - \bar{x})(y_i - \bar{y})}{\sum(x_i - \bar{x})^2} = \frac{6}{10} = 0.6

التفسير: مقابل كل ساعة إضافية من المذاكرة، ترتفع درجة الامتحان بمقدار 0.6 نقطة.

# Calculate slope (beta_1)
beta_1 = np.sum(xy_product) / np.sum(x_squared)
print(f"Slope (β₁) = {beta_1}")
print(f"\nInterpretation: For every additional hour of study, the exam score increases by {beta_1} points.")
Slope (β₁) = 0.6
 
Interpretation: For every additional hour of study, the exam score increases by 0.6 points.

الخطوة 6: حساب نقطة التقاطع (β0\beta_0)

β0=yˉβ1xˉ=4(0.6×3)=41.8=2.2\beta_0 = \bar{y} - \beta_1 \bar{x} = 4 - (0.6 \times 3) = 4 - 1.8 = 2.2

التفسير: من المتوقع أن يحصل الطالب الذي لا يذاكر مطلقًا (0 ساعة) على 2.2 نقطة (كقيمة أساسية baseline).

# Calculate intercept (beta_0)
beta_0 = y_mean - beta_1 * x_mean
print(f"Intercept (β₀) = {beta_0}")
print(f"\nInterpretation: A student who studies 0 hours would be expected to score {beta_0} points (baseline).")
Intercept (β₀) = 2.2
 
Interpretation: A student who studies 0 hours would be expected to score 2.2 points (baseline).

الخطوة 7: تكوين معادلة الانحدار

y^=β0+β1x\hat{y} = \beta_0 + \beta_1 x y^=2.2+0.6x\hat{y} = 2.2 + 0.6x

المعادلة النهائية: y^=2.2+0.6x\hat{y} = 2.2 + 0.6x

print(f"\nRegression Equation: ŷ = {beta_0} + {beta_1}x")
print(f"Or: ŷ = {beta_0} + {beta_1} * (Hours Studied)")
 
Regression Equation: ŷ = 2.2 + 0.6x
Or: ŷ = 2.2 + 0.6 * (Hours Studied)

الخطوة 8: إجراء التنبؤ

التنبؤ عند x = 6 ساعات: y^=2.2+0.6(6)=2.2+3.6=5.8\hat{y} = 2.2 + 0.6(6) = 2.2 + 3.6 = 5.8

الإجابة: من المتوقع أن يحصل الطالب الذي يذاكر 6 ساعات على 5.8 نقطة.

# Make prediction for 6 hours
x_new = 6
y_pred_new = beta_0 + beta_1 * x_new
print(f"\nPrediction for {x_new} hours of study: {y_pred_new} points")
 
Prediction for 6 hours of study: 5.8 points

الخطوة 9: تقييم أداء النموذج

حساب التنبؤات لجميع نقاط البيانات:

xix_iyiy_i (فعلية)y^i\hat{y}_i (متوقَّعة)(yiy^i)(y_i - \hat{y}_i)(yiy^i)2(y_i - \hat{y}_i)^2
122.8-0.80.64
243.40.60.36
354.01.01.00
444.6-0.60.36
555.2-0.20.04
Σ2.40
# Calculate predictions for all data points
y_pred = beta_0 + beta_1 * x
 
# Calculate residuals
residuals = y - y_pred
residuals_squared = residuals ** 2
 
# Create evaluation DataFrame
eval_df = pd.DataFrame({
    'x_i': x,
    'y_i (Actual)': y,
    'ŷ_i (Predicted)': y_pred,
    '(y_i - ŷ_i)': residuals,
    '(y_i - ŷ_i)²': residuals_squared
})
 
print("\nEvaluation Table:")
print(eval_df.to_string(index=False))
print(f"\nΣ(y_i - ŷ_i)² = {np.sum(residuals_squared)}")
 
Evaluation Table:
 x_i  y_i (Actual)  ŷ_i (Predicted)  (y_i - ŷ_i)  (y_i - ŷ_i)²
   1             2              2.8         -0.8          0.64
   2             4              3.4          0.6          0.36
   3             5              4.0          1.0          1.00
   4             4              4.6         -0.6          0.36
   5             5              5.2         -0.2          0.04
 
Σ(y_i - ŷ_i)² = 2.3999999999999995

متوسط مربع الخطأ (MSE):

MSE=(yiy^i)2n=2.405=0.48MSE = \frac{\sum(y_i - \hat{y}_i)^2}{n} = \frac{2.40}{5} = 0.48

الجذر التربيعي لمتوسط مربع الخطأ (RMSE):

RMSE=MSE=0.480.69RMSE = \sqrt{MSE} = \sqrt{0.48} \approx 0.69

# Calculate MSE and RMSE
mse = np.sum(residuals_squared) / n
rmse = np.sqrt(mse)
 
print(f"\nMean Squared Error (MSE): {mse}")
print(f"Root Mean Squared Error (RMSE): {rmse:.2f}")
 
Mean Squared Error (MSE): 0.47999999999999987
Root Mean Squared Error (RMSE): 0.69

حساب R2R^2 (معامل التحديد):

أولاً، نحسب مجموع المربعات الكلي (Total Sum of Squares - SST): SST=(yiyˉ)2=(2)2+02+12+02+12=4+0+1+0+1=6SST = \sum(y_i - \bar{y})^2 = (-2)^2 + 0^2 + 1^2 + 0^2 + 1^2 = 4 + 0 + 1 + 0 + 1 = 6

مجموع مربعات البواقي (Sum of Squared Residuals - SSR): SSR=(yiy^i)2=2.40SSR = \sum(y_i - \hat{y}_i)^2 = 2.40

حساب R2R^2: R2=1SSRSST=12.406=10.4=0.6R^2 = 1 - \frac{SSR}{SST} = 1 - \frac{2.40}{6} = 1 - 0.4 = 0.6

التفسير: يفسّر النموذج 60% من التباين (variance) في درجات الامتحان بناءً على ساعات المذاكرة.

# Calculate R²
sst = np.sum((y - y_mean) ** 2)
ssr = np.sum(residuals_squared)
r_squared = 1 - (ssr / sst)
 
print(f"\nTotal Sum of Squares (SST): {sst}")
print(f"Sum of Squared Residuals (SSR): {ssr}")
print(f"R² (Coefficient of Determination): {r_squared}")
print(f"\nInterpretation: The model explains {r_squared*100:.0f}% of the variance in exam scores.")
 
Total Sum of Squares (SST): 6.0
Sum of Squared Residuals (SSR): 2.3999999999999995
R² (Coefficient of Determination): 0.6000000000000001
 
Interpretation: The model explains 60% of the variance in exam scores.

تصور النتائج بيانيًا (Visualization)

# Visualization
plt.figure(figsize=(10, 6))
 
# Plot actual data points
plt.scatter(x, y, color='blue', s=100, alpha=0.6, label='Actual Data', zorder=3)
 
# Plot regression line
x_line = np.linspace(0, 7, 100)
y_line = beta_0 + beta_1 * x_line
plt.plot(x_line, y_line, color='red', linewidth=2, label=f'Regression Line: ŷ = {beta_0} + {beta_1}x')
 
# Plot prediction for 6 hours
plt.scatter([x_new], [y_pred_new], color='green', s=200, marker='*', 
            label=f'Prediction (x={x_new}): ŷ={y_pred_new}', zorder=4)
 
# Formatting
plt.xlabel('Hours Studied', fontsize=12)
plt.ylabel('Exam Score', fontsize=12)
plt.title('Linear Regression: Study Hours vs Exam Score', fontsize=14, fontweight='bold')
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
 
# Print summary
print("\n" + "="*50)
print("SUMMARY OF EXAMPLE 1")
print("="*50)
print(f"Equation: ŷ = {beta_0} + {beta_1}x")
print(f"R²: {r_squared:.4f}")
print(f"MSE: {mse:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"Prediction for {x_new} hours: {y_pred_new} points")
print("="*50)
 
==================================================
SUMMARY OF EXAMPLE 1
==================================================
Equation: ŷ = 2.2 + 0.6x
R²: 0.6000
MSE: 0.4800
RMSE: 0.6928
Prediction for 6 hours: 5.8 points
==================================================

6. مثال عددي 2: التنبؤ بأسعار المنازل

نص المسألة

التنبؤ بأسعار المنازل بناءً على المساحة (بالقدم المربع).

بيانات العينة:

مساحة المنزل (قدم مربع)السعر (بالآلاف $)
800140
1200210
1500280
1800350
2200420
# House price data
house_size = np.array([800, 1200, 1500, 1800, 2200])
house_price = np.array([140, 210, 280, 350, 420])
 
# Calculate parameters manually
n_houses = len(house_size)
x_mean_house = np.mean(house_size)
y_mean_house = np.mean(house_price)
 
# Deviations
x_dev_house = house_size - x_mean_house
y_dev_house = house_price - y_mean_house
 
# Calculate slope and intercept
beta_1_house = np.sum(x_dev_house * y_dev_house) / np.sum(x_dev_house ** 2)
beta_0_house = y_mean_house - beta_1_house * x_mean_house
 
print("House Price Prediction Model")
print("="*50)
print(f"Slope (β₁): {beta_1_house:.4f}")
print(f"Intercept (β₀): {beta_0_house:.2f}")
print(f"\nEquation: Price = {beta_0_house:.2f} + {beta_1_house:.4f} × Size")
print(f"\nInterpretation: For every additional square foot, the price increases by ${beta_1_house*1000:.2f}")
House Price Prediction Model
==================================================
Slope (β₁): 0.2052
Intercept (β₀): -27.76
 
Equation: Price = -27.76 + 0.2052 × Size
 
Interpretation: For every additional square foot, the price increases by $205.17
# Make predictions
y_pred_house = beta_0_house + beta_1_house * house_size
 
# Calculate metrics
residuals_house = house_price - y_pred_house
mse_house = np.mean(residuals_house ** 2)
rmse_house = np.sqrt(mse_house)
sst_house = np.sum((house_price - y_mean_house) ** 2)
ssr_house = np.sum(residuals_house ** 2)
r2_house = 1 - (ssr_house / sst_house)
 
print(f"\nModel Performance:")
print(f"R²: {r2_house:.4f}")
print(f"MSE: {mse_house:.2f}")
print(f"RMSE: {rmse_house:.2f}")
 
# Predict for a new house
new_house_size = 2000
predicted_price = beta_0_house + beta_1_house * new_house_size
print(f"\nPrediction for {new_house_size} sq ft house: ${predicted_price:.2f}k")
 
Model Performance:
R²: 0.9966
MSE: 33.79
RMSE: 5.81
 
Prediction for 2000 sq ft house: $382.59k
# Visualization
plt.figure(figsize=(10, 6))
 
# Plot actual data
plt.scatter(house_size, house_price, color='blue', s=100, alpha=0.6, label='Actual Data')
 
# Plot regression line
x_line_house = np.linspace(700, 2300, 100)
y_line_house = beta_0_house + beta_1_house * x_line_house
plt.plot(x_line_house, y_line_house, color='red', linewidth=2, 
         label=f'Regression Line')
 
# Plot prediction
plt.scatter([new_house_size], [predicted_price], color='green', s=200, marker='*',
            label=f'Prediction ({new_house_size} sq ft)', zorder=4)
 
# Formatting
plt.xlabel('House Size (Square Feet)', fontsize=12)
plt.ylabel('Price ($1000s)', fontsize=12)
plt.title('Linear Regression: House Price Prediction', fontsize=14, fontweight='bold')
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
 
# Show residuals
print(f"\nResiduals (Actual - Predicted):")
for i, (size, actual, pred, resid) in enumerate(zip(house_size, house_price, y_pred_house, residuals_house), 1):
    print(f"  House {i}: Size={size} sq ft, Actual=${actual}k, Predicted=${pred:.2f}k, Residual=${resid:.2f}k")
 
Residuals (Actual - Predicted):
  House 1: Size=800 sq ft, Actual=$140k, Predicted=$136.38k, Residual=$3.62k
  House 2: Size=1200 sq ft, Actual=$210k, Predicted=$218.45k, Residual=$-8.45k
  House 3: Size=1500 sq ft, Actual=$280k, Predicted=$280.00k, Residual=$0.00k
  House 4: Size=1800 sq ft, Actual=$350k, Predicted=$341.55k, Residual=$8.45k
  House 5: Size=2200 sq ft, Actual=$420k, Predicted=$423.62k, Residual=$-3.62k

7. التنفيذ بلغة Python باستخدام Scikit-Learn

والآن سننفّذ نفس الأمثلة باستخدام مكتبة scikit-learn، وهي أشهر مكتبة تعلم آلة في بايثون.

from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error
 
# Example 1: Student Exam Scores with scikit-learn
print("="*60)
print("EXAMPLE 1: STUDENT EXAM SCORES (Scikit-Learn Implementation)")
print("="*60)
 
# Reshape data (scikit-learn requires 2D array for X)
X_study = x.reshape(-1, 1) # from [1,2,3,4,5] to [ [1],[2],[3],[4],[5] ] => From shape (5,) to shape (5, 1)
y_study = y
 
# Create and fit the model
model_study = LinearRegression()
model_study.fit(X_study, y_study)
 
# Get parameters
slope_study = model_study.coef_[0]
intercept_study = model_study.intercept_
 
print(f"\nEquation: y = {intercept_study:.2f} + {slope_study:.2f}x")
print(f"Slope (β₁): {slope_study:.2f}")
print(f"Intercept (β₀): {intercept_study:.2f}")
 
# Make predictions
y_pred_sklearn = model_study.predict(X_study)
 
# Calculate metrics
r2_sklearn = r2_score(y_study, y_pred_sklearn)
mse_sklearn = mean_squared_error(y_study, y_pred_sklearn)
rmse_sklearn = np.sqrt(mse_sklearn)
 
print(f"\nModel Performance:")
print(f"R-squared: {r2_sklearn:.4f}")
print(f"Mean Squared Error: {mse_sklearn:.4f}")
print(f"Root Mean Squared Error: {rmse_sklearn:.4f}")
 
# Make prediction for new data
new_hours = 6
predicted_score = model_study.predict([[new_hours]])[0]
print(f"\nPrediction for {new_hours} hours: {predicted_score:.2f} points")
============================================================
EXAMPLE 1: STUDENT EXAM SCORES (Scikit-Learn Implementation)
============================================================
 
Equation: y = 2.20 + 0.60x
Slope (β₁): 0.60
Intercept (β₀): 2.20
 
Model Performance:
R-squared: 0.6000
Mean Squared Error: 0.4800
Root Mean Squared Error: 0.6928
 
Prediction for 6 hours: 5.80 points
# Example 2: House Prices with scikit-learn
print("\n" + "="*60)
print("EXAMPLE 2: HOUSE PRICE PREDICTION (Scikit-Learn Implementation)")
print("="*60)
 
# Reshape data
X_house = house_size.reshape(-1, 1)
y_house = house_price
 
# Create and fit the model
model_house = LinearRegression()
model_house.fit(X_house, y_house)
 
# Get parameters
slope_house_sklearn = model_house.coef_[0]
intercept_house_sklearn = model_house.intercept_
 
print(f"\nEquation: y = {intercept_house_sklearn:.2f} + {slope_house_sklearn:.4f}x")
print(f"Slope (β₁): {slope_house_sklearn:.4f}")
print(f"Intercept (β₀): {intercept_house_sklearn:.2f}")
 
# Make predictions
y_pred_house_sklearn = model_house.predict(X_house)
 
# Calculate metrics
r2_house_sklearn = r2_score(y_house, y_pred_house_sklearn)
mse_house_sklearn = mean_squared_error(y_house, y_pred_house_sklearn)
rmse_house_sklearn = np.sqrt(mse_house_sklearn)
 
print(f"\nModel Performance:")
print(f"R-squared: {r2_house_sklearn:.4f}")
print(f"Mean Squared Error: {mse_house_sklearn:.2f}")
print(f"Root Mean Squared Error: {rmse_house_sklearn:.2f}")
 
# Make prediction for new data
new_size = 2000
predicted_price_sklearn = model_house.predict([[new_size]])[0]
print(f"\nPrediction for {new_size} sq ft house: ${predicted_price_sklearn:.2f}k")
 
============================================================
EXAMPLE 2: HOUSE PRICE PREDICTION (Scikit-Learn Implementation)
============================================================
 
Equation: y = -27.76 + 0.2052x
Slope (β₁): 0.2052
Intercept (β₀): -27.76
 
Model Performance:
R-squared: 0.9966
Mean Squared Error: 33.79
Root Mean Squared Error: 5.81
 
Prediction for 2000 sq ft house: $382.59k

مقارنة جنبًا إلى جنب: الحساب اليدوي مقابل Scikit-Learn

# Comparison table
comparison_data = {
    'Metric': ['Slope (β₁)', 'Intercept (β₀)', 'R²', 'MSE', 'RMSE'],
    'Manual Calculation': [
        f"{beta_1:.4f}",
        f"{beta_0:.4f}",
        f"{r_squared:.4f}",
        f"{mse:.4f}",
        f"{rmse:.4f}"
    ],
    'Scikit-Learn': [
        f"{slope_study:.4f}",
        f"{intercept_study:.4f}",
        f"{r2_sklearn:.4f}",
        f"{mse_sklearn:.4f}",
        f"{rmse_sklearn:.4f}"
    ]
}
 
comparison_df = pd.DataFrame(comparison_data)
print("\n" + "="*60)
print("COMPARISON: Manual Calculation vs Scikit-Learn")
print("(Example 1: Student Exam Scores)")
print("="*60)
print(comparison_df.to_string(index=False))
print("\nNote: Both methods produce identical results!")
 
============================================================
COMPARISON: Manual Calculation vs Scikit-Learn
(Example 1: Student Exam Scores)
============================================================
        Metric Manual Calculation Scikit-Learn
    Slope (β₁)             0.6000       0.6000
Intercept (β₀)             2.2000       2.2000
            R²             0.6000       0.6000
           MSE             0.4800       0.4800
          RMSE             0.6928       0.6928
 
Note: Both methods produce identical results!

8. تقييم النموذج

أهم مقاييس الأداء

1. متوسط مربع الخطأ (MSE)

MSE=1ni=1n(yiy^i)2MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2

  • يقيس متوسط مربع الفرق بين القيم الفعلية والقيم المتوقَّعة
  • القيم الأقل تدل على ملاءمة (fit) أفضل للنموذج
  • حساس تجاه القيم الشاذة (outliers) بسبب عملية التربيع

2. الجذر التربيعي لمتوسط مربع الخطأ (RMSE)

RMSE=MSERMSE = \sqrt{MSE}

  • له نفس وحدة قياس المتغير الهدف
  • أسهل في التفسير من MSE
  • يمثل مقدار الخطأ النموذجي المتوقَّع في التنبؤ

3. معامل التحديد (R2R^2)

R2=1(yiy^i)2(yiyˉ)2=1SSRSSTR^2 = 1 - \frac{\sum(y_i - \hat{y}_i)^2}{\sum(y_i - \bar{y})^2} = 1 - \frac{SSR}{SST}

  • يتراوح بين 0 و1 (ويمكن أن يكون سالبًا في حالة النماذج الضعيفة جدًا)
  • يمثل نسبة التباين (variance) التي يفسّرها النموذج
  • R2=0.6R^2 = 0.6 يعني أن النموذج يفسّر 60% من التباين
  • القيم الأعلى تدل على ملاءمة أفضل للنموذج
# Comprehensive evaluation function
def evaluate_regression_model(y_true, y_pred, model_name="Model"):
    """
    Evaluate regression model performance with multiple metrics
    """
    # Calculate metrics
    mse = mean_squared_error(y_true, y_pred)
    rmse = np.sqrt(mse)
    r2 = r2_score(y_true, y_pred)
    
    # Calculate additional metrics
    mae = np.mean(np.abs(y_true - y_pred))  # Mean Absolute Error
    mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100  # Mean Absolute Percentage Error
    
    print(f"\n{'='*60}")
    print(f"EVALUATION METRICS: {model_name}")
    print(f"{'='*60}")
    print(f"R² (Coefficient of Determination): {r2:.4f}")
    print(f"Mean Squared Error (MSE):          {mse:.4f}")
    print(f"Root Mean Squared Error (RMSE):    {rmse:.4f}")
    print(f"Mean Absolute Error (MAE):         {mae:.4f}")
    print(f"Mean Absolute Percentage Error:    {mape:.2f}%")
    print(f"{'='*60}")
    
    return {'R2': r2, 'MSE': mse, 'RMSE': rmse, 'MAE': mae, 'MAPE': mape}
 
# Evaluate both models
metrics_study = evaluate_regression_model(y, y_pred_sklearn, "Student Exam Scores")
metrics_house = evaluate_regression_model(house_price, y_pred_house_sklearn, "House Price Prediction")
 
============================================================
EVALUATION METRICS: Student Exam Scores
============================================================
R² (Coefficient of Determination): 0.6000
Mean Squared Error (MSE):          0.4800
Root Mean Squared Error (RMSE):    0.6928
Mean Absolute Error (MAE):         0.6400
Mean Absolute Percentage Error:    18.80%
============================================================
 
============================================================
EVALUATION METRICS: House Price Prediction
============================================================
R² (Coefficient of Determination): 0.9966
Mean Squared Error (MSE):          33.7931
Root Mean Squared Error (RMSE):    5.8132
Mean Absolute Error (MAE):         4.8276
Mean Absolute Percentage Error:    1.98%
============================================================

تحليل البواقي (Residuals)

يساعد تحليل البواقي (residuals / الأخطاء) في التحقق من صحة افتراضات النموذج:

  • يجب أن تكون البواقي موزعة بشكل عشوائي
  • عدم وجود أنماط واضحة في مخططات البواقي
  • تباين شبه ثابت (تجانس التباين homoscedasticity)
# Residual plots
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
 
# Residual plot for Example 1
residuals_1 = y - y_pred_sklearn
axes[0].scatter(y_pred_sklearn, residuals_1, color='blue', alpha=0.6)
axes[0].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[0].set_xlabel('Predicted Values', fontsize=11)
axes[0].set_ylabel('Residuals', fontsize=11)
axes[0].set_title('Residual Plot: Student Exam Scores', fontsize=12, fontweight='bold')
axes[0].grid(True, alpha=0.3)
 
# Residual plot for Example 2
residuals_2 = house_price - y_pred_house_sklearn
axes[1].scatter(y_pred_house_sklearn, residuals_2, color='green', alpha=0.6)
axes[1].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[1].set_xlabel('Predicted Values', fontsize=11)
axes[1].set_ylabel('Residuals', fontsize=11)
axes[1].set_title('Residual Plot: House Prices', fontsize=12, fontweight='bold')
axes[1].grid(True, alpha=0.3)
 
plt.tight_layout()
plt.show()
 
print("\nResidual Analysis:")
print("- Points randomly scattered around zero line indicate good model fit")
print("- Patterns in residuals suggest model assumptions may be violated")
print("- Consistent spread indicates homoscedasticity (constant variance)")
 
Residual Analysis:
- Points randomly scattered around zero line indicate good model fit
- Patterns in residuals suggest model assumptions may be violated
- Consistent spread indicates homoscedasticity (constant variance)

9. الخلاصة وأهم النقاط

ملخص

الانحدار الخطي أسلوب قوي وقابل للتفسير لنمذجة العلاقات بين المتغيرات. وتسير الخوارزمية وفق خطوات رياضية واضحة:

  1. حساب المتوسطات (means) للمتغيرات المستقلة والتابعة
  2. حساب الانحرافات (deviations) عن المتوسط
  3. حساب الميل من التغاير (covariance) والتباين (variance)
  4. حساب نقطة التقاطع باستخدام المتوسطات والميل
  5. تكوين معادلة التنبؤ
  6. تقييم الأداء باستخدام المقاييس المناسبة

أهم النقاط:

سهل التنفيذ والتفسير - يوفر الانحدار الخطي رؤى واضحة وقابلة للتطبيق العملي

يوفر علاقات كمّية - تُظهر المُعاملات (coefficients) التأثير الدقيق لكل خاصية

مفيد في التنبؤ وتحليل الاتجاهات - فعّال في التوقع وفهم الأنماط

يعتمد الأداء على جودة البيانات - نظافة البيانات ووجود علاقة خطية أمران أساسيان

تحقق دائمًا من صحة الافتراضات - تأكد من الخطية والاستقلالية وثبات التباين

قيّم أداء النموذج - استخدم عدة مقاييس (R²، وMSE، وRMSE) لتقييم الجودة

متى نستخدم الانحدار الخطي؟

يكون مناسبًا عندما:

  • تكون العلاقة بين المتغيرات خطية تقريبًا
  • تحتاج إلى نتائج قابلة للتفسير
  • تحتوي البيانات على أقل قدر من القيم الشاذة
  • تكون الخصائص (features) مستقلة عن بعضها

لا يكون مناسبًا عندما:

  • تكون العلاقات غير خطية بدرجة كبيرة
  • تحتوي البيانات على قيم شاذة كثيرة
  • ترتبط الخصائص ببعضها بشكل قوي (تعدد الخطية multicollinearity)
  • يكون المطلوب رصد تفاعلات معقدة بين المتغيرات

الخطوات التالية:

  • استكشاف الانحدار الخطي المتعدد (Multiple Linear Regression) (خصائص متعددة)
  • تعلّم الانحدار متعدد الحدود (Polynomial Regression) للعلاقات غير الخطية
  • دراسة تقنيات التنظيم (Regularization) مثل Ridge وLasso لتحسين التعميم (generalization)
  • التدرب باستخدام مجموعات بيانات واقعية

تمارين تطبيقية

جرّب هذه التمارين لترسيخ فهمك:

التمرين 1: تحويل درجات الحرارة

ابنِ نموذج انحدار خطي لتحويل درجة الحرارة من مئوية إلى فهرنهايت باستخدام هذه البيانات:

  • مئوية (Celsius): [0, 10, 20, 30, 40]
  • فهرنهايت (Fahrenheit): [32, 50, 68, 86, 104]

التمرين 2: العمر والطول

تنبأ بالطول بناءً على العمر باستخدام مجموعة البيانات التالية:

  • العمر (بالسنوات): [2, 4, 6, 8, 10]
  • الطول (سم): [85, 100, 115, 130, 140]

التمرين 3: التنبؤ بالمبيعات

تنبأ بالمبيعات بناءً على الإنفاق الإعلاني:

  • الإنفاق الإعلاني (بالآلاف $): [1, 2, 3, 4, 5]
  • المبيعات (بالآلاف $): [10, 25, 35, 48, 55]

لكل تمرين:

  1. احسب الميل ونقطة التقاطع يدويًا
  2. تحقق من النتيجة باستخدام scikit-learn
  3. أجرِ تنبؤات لقيم جديدة
  4. قيّم أداء النموذج
  5. أنشئ تصورات بيانية (visualizations)
# Space for your practice exercises
# Exercise 1: Temperature Conversion
 
# Your code here...
# Exercise 2: Age and Height
 
# Your code here...
# Exercise 3: Sales Prediction
 
# Your code here...

المراجع ومصادر إضافية للقراءة


نهاية المعمل