本文基于 Scikit-learn 库,演示如何用 Python 构建一个完整的监督学习预测模型。内容涵盖数据集构建、训练/测试集划分、线性回归与决策树(回归+分类)的实现、模型评估指标、完整项目流程以及简单的参数调优。所有代码均可在 Python 3.8+ 环境中运行,无需额外安装第三方库(除 scikit-learn、pandas、numpy 外)。
1. 生成回归任务示例数据
先模拟房价预测场景:根据房屋面积和房龄生成房价。代码使用 numpy 随机生成 200 个样本,面积 50-200 平米,房龄 0-30 年。房价公式为:price = 1.5*area - 2*age + 50 + 噪声。
- import pandas as pd
- import numpy as np
- np.random.seed(42)
- n_samples = 200
- area = np.random.uniform(50, 200, n_samples)
- age = np.random.uniform(0, 30, n_samples)
- price = (1.5 * area - 2 * age + 50 + np.random.normal(0, 15, n_samples))
- df = pd.DataFrame({
- "面积_平米": area,
- "房龄_年": age,
- "房价_万元": price
- })
- print("=== 示例数据:房价预测 ===")
- print(df.head(10))
- print(f"\n数据规模: {len(df)} 条")
- print(df.describe().round(1))
复制代码
2. 训练/测试集划分
为什么要划分?防止模型“背答案”,必须有未见过的数据来评估泛化能力。使用 train_test_split 按 80%/20% 划分,设置 random_state=42 保证可复现。
- from sklearn.model_selection import train_test_split
- X = df[["面积_平米", "房龄_年"]]
- y = df["房价_万元"]
- 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)} 条")
复制代码
3. 线性回归模型
线性回归通过最小化均方误差找到最佳系数。训练后打印出面积和房龄的系数及截距,并给出业务解读。
- from sklearn.linear_model import LinearRegression
- from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
- model = LinearRegression()
- model.fit(X_train, y_train)
- print(f"系数: 面积={model.coef_[0]:.2f}, 房龄={model.coef_[1]:.2f}")
- print(f"截距: {model.intercept_:.2f}")
- y_pred = model.predict(X_test)
- comparison = pd.DataFrame({
- "真实房价": y_test.values,
- "预测房价": y_pred,
- "误差": y_test.values - y_pred
- })
- print("测试集预测结果对比(前10条):")
- print(comparison.head(10).round(1))
复制代码
模型评估使用 MSE、RMSE、MAE 和 R²。RMSE 约为 13.5 万,R² 约 0.87,说明模型解释了 87% 的房价波动。
- mse = mean_squared_error(y_test, y_pred)
- rmse = np.sqrt(mse)
- mae = mean_absolute_error(y_test, y_pred)
- r2 = r2_score(y_test, y_pred)
- print(f"RMSE: {rmse:.2f} 万元")
- print(f"R²: {r2:.4f}")
复制代码
4. 决策树回归与分类
决策树通过一系列 if/else 规则做预测,设置 max_depth=4 防止过拟合。对比线性回归,决策树的 MAE 通常略低,但可解释性更强。
- from sklearn.tree import DecisionTreeRegressor
- dt_model = DecisionTreeRegressor(max_depth=4, random_state=42)
- dt_model.fit(X_train, y_train)
- dt_pred = dt_model.predict(X_test)
- print(f"决策树 MAE: {mean_absolute_error(y_test, dt_pred):.2f} 万元")
- print(f"决策树 R²: {r2_score(y_test, dt_pred):.4f}")
复制代码
分类任务使用 Iris 数据集演示 DecisionTreeClassifier。加载数据、划分、训练并输出准确率(约 97%)、分类报告和混淆矩阵。
- from sklearn.datasets import load_iris
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
- iris = load_iris()
- X_iris, y_iris = iris.data, iris.target
- X_train_ir, X_test_ir, y_train_ir, y_test_ir = train_test_split(
- X_iris, y_iris, test_size=0.3, random_state=42
- )
- clf = DecisionTreeClassifier(max_depth=3, random_state=42)
- clf.fit(X_train_ir, y_train_ir)
- y_pred_ir = clf.predict(X_test_ir)
- print(f"准确率: {accuracy_score(y_test_ir, y_pred_ir):.2%}")
- print(classification_report(y_test_ir, y_pred_ir, target_names=iris.target_names))
- print(confusion_matrix(y_test_ir, y_pred_ir))
复制代码
5. 完整项目:电商用户购买意愿预测
模拟 1000 个用户,6 个特征(浏览时长、浏览次数、加入购物车、收藏数、历史购买次数、距上次访问天数)。标签“购买”由特征线性组合加噪声生成。数据无需单独处理,直接划分并标准化(Scaler)。训练四个模型:逻辑回归、决策树、随机森林、K近邻。
- from sklearn.preprocessing import StandardScaler
- from sklearn.linear_model import LogisticRegression
- from sklearn.ensemble import RandomForestClassifier
- from sklearn.neighbors import KNeighborsClassifier
- # 构造数据略(见原文)
- X = users.drop("购买", axis=1)
- y = users["购买"]
- X_train_u, X_test_u, y_train_u, y_test_u = train_test_split(
- X, y, test_size=0.2, random_state=42, stratify=y
- )
- scaler = StandardScaler()
- X_train_scaled = scaler.fit_transform(X_train_u)
- X_test_scaled = scaler.transform(X_test_u)
- models = {
- "逻辑回归": LogisticRegression(max_iter=1000),
- "决策树": DecisionTreeClassifier(max_depth=5),
- "随机森林": RandomForestClassifier(n_estimators=50),
- "K近邻": KNeighborsClassifier(n_neighbors=5)
- }
- for name, model in models.items():
- model.fit(X_train_scaled, y_train_u)
- acc = model.score(X_test_scaled, y_test_u)
- print(f"{name}: 准确率 = {acc:.2%}")
复制代码
最佳模型(通常是随机森林或逻辑回归)会输出分类报告和混淆矩阵。同时分析特征重要性(随机森林自带)。最后演示对新用户预测:
- new_users = pd.DataFrame({
- "浏览时长_分钟": [15, 5, 30],
- "浏览次数": [10, 3, 20],
- "加入购物车": [3, 0, 5],
- "收藏数": [2, 0, 3],
- "历史购买次数": [5, 1, 10],
- "距上次访问_天": [2, 15, 1]
- })
- new_scaled = scaler.transform(new_users)
- new_pred = best_model.predict(new_scaled)
- new_prob = best_model.predict_proba(new_scaled)[:, 1]
- for i, (pred, prob) in enumerate(zip(new_pred, new_prob)):
- label = "会购买" if pred == 1 else "不会购买"
- print(f"用户{i+1}: 预测结果={label}, 购买概率={prob:.1%}")
复制代码
6. 模型调优:交叉验证与网格搜索
用 cross_val_score 对每个模型做 5 折交叉验证,获得更稳定的性能估计。使用 GridSearchCV 对决策树搜索最佳 max_depth 和 min_samples_split。
- from sklearn.model_selection import cross_val_score, GridSearchCV
- for name, model in models.items():
- scores = cross_val_score(model, X_train_scaled, y_train_u, cv=5, scoring="accuracy")
- print(f"{name}: {scores.mean():.2%} (+/- {scores.std():.2%})")
- param_grid = {
- "max_depth": [3, 5, 7, 10],
- "min_samples_split": [2, 5, 10]
- }
- grid = GridSearchCV(DecisionTreeClassifier(random_state=42), param_grid, cv=5)
- grid.fit(X_train_scaled, y_train_u)
- print(f"最佳参数: {grid.best_params_}")
- print(f"最佳准确率: {grid.best_score_:.2%}")
复制代码
总结
本教程完整展示了用 Scikit-learn 搭建预测模型的关键步骤:数据准备 → 划分 → 训练 → 评估 → 调优。无论是回归还是分类任务,都可以套用这一框架。初学者可以在此基础上替换真实数据集,并进一步学习特征工程和更复杂的模型。 |