在机器学习领域,回归和分类算法是两大核心任务,它们构成了监督学习的基础。无论是预测房价、股票走势,还是识别图像中的物体、判断邮件是否为垃圾邮件,都离不开这两类算法。本文将深入探讨回归和分类算法的核心知识点,并通过详细的代码实例帮助读者全面理解这些算法。
一、机器学习基础概念
在深入讨论具体算法之前,我们先了解一些基础概念:
监督学习:通过已有标记数据训练模型,使模型能够预测新数据的输出。回归和分类都属于监督学习。
特征(Feature):描述数据的属性或变量,是模型的输入。
标签(Label):我们希望预测的结果,是模型的输出。
训练集:用于训练模型的数据集。
测试集:用于评估模型性能的数据集。
二、回归算法详解
回归算法用于预测连续值输出,如房价、温度、销售额等。下面我们详细介绍几种常见的回归算法。
2.1 线性回归
线性回归是最简单、最基础的回归算法,它假设特征和标签之间存在线性关系。
数学模型 :
对于简单线性回归(单特征):
y=β0+β1x+ϵy=β0+β1x+ϵ
对于多元线性回归(多特征):
y=β0+β1x1+β2x2+...+βnxn+ϵy=β0+β1x1+β2x2+...+βnxn+ϵ
其中:
-
y:预测值
-
\\beta_0:截距
-
\\beta_1, \\beta_2, ..., \\beta_n:系数
-
x_1, x_2, ..., x_n:特征值
-
\\epsilon:误差项
损失函数 :均方误差(MSE)
MSE=1n∑i=1n(yi−yi^)2MSE=n1∑i=1n(yi−yi^)2
参数估计:通常使用最小二乘法或梯度下降法来估计参数。
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import make_regression
# 生成回归数据集
X, y = make_regression(n_samples=100, n_features=1, noise=10, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并训练线性回归模型
lr = LinearRegression()
lr.fit(X_train, y_train)
# 预测
y_pred = lr.predict(X_test)
# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"线性回归结果:")
print(f"斜率: {lr.coef_[0]:.4f}")
print(f"截距: {lr.intercept_:.4f}")
print(f"均方误差: {mse:.4f}")
print(f"R²分数: {r2:.4f}")
# 可视化结果
plt.figure(figsize=(10, 6))
plt.scatter(X_test, y_test, color='blue', label='实际值')
plt.plot(X_test, y_pred, color='red', linewidth=2, label='预测值')
plt.xlabel('特征值')
plt.ylabel('目标值')
plt.title('线性回归示例')
plt.legend()
plt.show()
2.2 多项式回归
当数据关系不是简单的线性关系时,可以使用多项式回归,它是线性回归的扩展。
python
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
# 生成非线性数据
np.random.seed(42)
X = np.linspace(-3, 3, 100).reshape(-1, 1)
y = 0.5 * X**3 + X**2 - 2*X + np.random.normal(0, 2, 100).reshape(-1, 1)
# 创建多项式回归模型
degree = 3
poly_model = Pipeline([
('poly', PolynomialFeatures(degree=degree)),
('linear', LinearRegression())
])
# 训练模型
poly_model.fit(X, y)
# 预测
X_test = np.linspace(-3, 3, 50).reshape(-1, 1)
y_pred = poly_model.predict(X_test)
# 可视化
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', alpha=0.6, label='实际数据')
plt.plot(X_test, y_pred, color='red', linewidth=2, label=f'{degree}次多项式拟合')
plt.xlabel('X')
plt.ylabel('y')
plt.title('多项式回归示例')
plt.legend()
plt.show()
2.3 决策树回归
决策树不仅可以用于分类,也可以用于回归任务。它通过创建树状模型进行预测。
python
from sklearn.tree import DecisionTreeRegressor, plot_tree
from sklearn.datasets import fetch_california_housing
# 加载加州房价数据集
housing = fetch_california_housing()
X, y = housing.data, housing.target
# 只使用前两个特征以便可视化
X = X[:, :2]
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建决策树回归模型
dt_reg = DecisionTreeRegressor(max_depth=3, random_state=42)
dt_reg.fit(X_train, y_train)
# 预测
y_pred = dt_reg.predict(X_test)
# 评估
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"决策树回归结果:")
print(f"均方误差: {mse:.4f}")
print(f"R²分数: {r2:.4f}")
# 可视化决策树
plt.figure(figsize=(15, 10))
plot_tree(dt_reg, feature_names=housing.feature_names[:2], filled=True, rounded=True)
plt.title('决策树回归树结构')
plt.show()
2.4 随机森林回归
随机森林通过集成多个决策树来提高预测性能和稳定性。
python
from sklearn.ensemble import RandomForestRegressor
# 创建随机森林回归模型
rf_reg = RandomForestRegressor(n_estimators=100, random_state=42)
rf_reg.fit(X_train, y_train)
# 预测
y_pred_rf = rf_reg.predict(X_test)
# 评估
mse_rf = mean_squared_error(y_test, y_pred_rf)
r2_rf = r2_score(y_test, y_pred_rf)
print(f"随机森林回归结果:")
print(f"均方误差: {mse_rf:.4f}")
print(f"R²分数: {r2_rf:.4f}")
# 特征重要性
feature_importance = rf_reg.feature_importances_
plt.figure(figsize=(8, 6))
plt.barh(housing.feature_names[:2], feature_importance)
plt.xlabel('特征重要性')
plt.title('随机森林特征重要性')
plt.show()
2.5 支持向量回归(SVR)
SVR是支持向量机在回归问题上的应用,通过寻找一个超平面使得大部分数据点落在间隔内。
python
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 重新划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 创建SVR模型
svr = SVR(kernel='rbf', C=1.0, epsilon=0.1)
svr.fit(X_train, y_train)
# 预测
y_pred_svr = svr.predict(X_test)
# 评估
mse_svr = mean_squared_error(y_test, y_pred_svr)
r2_svr = r2_score(y_test, y_pred_svr)
print(f"支持向量回归结果:")
print(f"均方误差: {mse_svr:.4f}")
print(f"R²分数: {r2_svr:.4f}")
三、分类算法详解
分类算法用于预测离散类别输出,如图像分类、垃圾邮件检测等。下面我们详细介绍几种常见的分类算法。
3.1 逻辑回归
尽管名字中有"回归",但逻辑回归是一种分类算法,特别适用于二分类问题。
数学模型 :
p=11+e−(β0+β1x1+...+βnxn)p=1+e−(β0+β1x1+...+βnxn)1
其中p是样本属于正类的概率。
损失函数 :交叉熵损失
J(θ)=−1m∑i=1m[yilog(pi)+(1−yi)log(1−pi)]J(θ)=−m1∑i=1m[yilog(pi)+(1−yi)log(1−pi)]
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.datasets import make_classification
import seaborn as sns
# 生成二分类数据集
X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
n_informative=2, n_clusters_per_class=1, random_state=42)
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建并训练逻辑回归模型
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
# 预测
y_pred = log_reg.predict(X_test)
y_pred_proba = log_reg.predict_proba(X_test)
# 评估模型
accuracy = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
print(f"逻辑回归结果:")
print(f"准确率: {accuracy:.4f}")
print("分类报告:")
print(classification_report(y_test, y_pred))
# 可视化决策边界
plt.figure(figsize=(12, 5))
# 左图:实际类别
plt.subplot(1, 2, 1)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='bwr', alpha=0.7)
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.title('实际类别')
plt.colorbar()
# 右图:预测类别
plt.subplot(1, 2, 2)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='bwr', alpha=0.7)
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.title('预测类别')
plt.colorbar()
plt.tight_layout()
plt.show()
# 混淆矩阵热力图
plt.figure(figsize=(6, 5))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('混淆矩阵')
plt.ylabel('实际类别')
plt.xlabel('预测类别')
plt.show()
3.2 K近邻分类(K-NN)
K-NN是一种基于实例的学习算法,它根据最近邻居的类别来预测新样本的类别。
python
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 重新划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# 寻找最优K值
k_range = range(1, 20)
accuracies = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
accuracies.append(accuracy_score(y_test, y_pred))
# 绘制K值与准确率关系
plt.figure(figsize=(10, 6))
plt.plot(k_range, accuracies, marker='o')
plt.xlabel('K值')
plt.ylabel('准确率')
plt.title('K值与模型准确率关系')
plt.grid(True)
plt.show()
# 使用最优K值
best_k = k_range[np.argmax(accuracies)]
print(f"最优K值: {best_k}")
knn_best = KNeighborsClassifier(n_neighbors=best_k)
knn_best.fit(X_train, y_train)
y_pred_best = knn_best.predict(X_test)
accuracy_best = accuracy_score(y_test, y_pred_best)
print(f"最优K近邻准确率: {accuracy_best:.4f}")
3.3 决策树分类
决策树通过一系列规则对数据进行分割,形成树状结构。
python
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
X, y = iris.data, iris.target
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建决策树分类模型
dt_clf = DecisionTreeClassifier(max_depth=3, random_state=42)
dt_clf.fit(X_train, y_train)
# 预测
y_pred = dt_clf.predict(X_test)
# 评估
accuracy = accuracy_score(y_test, y_pred)
print(f"决策树分类准确率: {accuracy:.4f}")
# 可视化决策树
plt.figure(figsize=(15, 10))
plot_tree(dt_clf, feature_names=iris.feature_names,
class_names=iris.target_names, filled=True, rounded=True)
plt.title('决策树分类器')
plt.show()
# 特征重要性
feature_importance = dt_clf.feature_importances_
plt.figure(figsize=(8, 6))
plt.barh(iris.feature_names, feature_importance)
plt.xlabel('特征重要性')
plt.title('决策树特征重要性')
plt.show()
3.4 随机森林分类
随机森林通过集成多个决策树来提高分类性能。
python
from sklearn.ensemble import RandomForestClassifier
# 创建随机森林分类模型
rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)
rf_clf.fit(X_train, y_train)
# 预测
y_pred_rf = rf_clf.predict(X_test)
# 评估
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print(f"随机森林分类准确率: {accuracy_rf:.4f}")
# 特征重要性
feature_importance_rf = rf_clf.feature_importances_
plt.figure(figsize=(8, 6))
plt.barh(iris.feature_names, feature_importance_rf)
plt.xlabel('特征重要性')
plt.title('随机森林特征重要性')
plt.show()
3.5 支持向量机(SVM)
SVM通过寻找最大间隔超平面来区分不同类别。
python
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 重新划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# 创建SVM模型
svm = SVC(kernel='rbf', probability=True)
svm.fit(X_train, y_train)
# 预测
y_pred_svm = svm.predict(X_test)
# 评估
accuracy_svm = accuracy_score(y_test, y_pred_svm)
print(f"SVM分类准确率: {accuracy_svm:.4f}")
# 比较不同核函数性能
kernels = ['linear', 'poly', 'rbf', 'sigmoid']
kernel_accuracies = []
for kernel in kernels:
svm_temp = SVC(kernel=kernel, random_state=42)
svm_temp.fit(X_train, y_train)
y_pred_temp = svm_temp.predict(X_test)
kernel_accuracies.append(accuracy_score(y_test, y_pred_temp))
# 绘制不同核函数性能比较
plt.figure(figsize=(8, 6))
plt.bar(kernels, kernel_accuracies)
plt.xlabel('核函数')
plt.ylabel('准确率')
plt.title('不同核函数SVM性能比较')
plt.show()
3.6 朴素贝叶斯
朴素贝叶斯基于贝叶斯定理,假设特征之间相互独立。
python
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_breast_cancer
# 加载乳腺癌数据集
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建朴素贝叶斯模型
nb = GaussianNB()
nb.fit(X_train, y_train)
# 预测
y_pred_nb = nb.predict(X_test)
# 评估
accuracy_nb = accuracy_score(y_test, y_pred_nb)
print(f"朴素贝叶斯分类准确率: {accuracy_nb:.4f}")
# 绘制概率分布
y_proba = nb.predict_proba(X_test)
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.hist(y_proba[y_test==0, 1], bins=20, alpha=0.7, label='实际为0', color='red')
plt.hist(y_proba[y_test==1, 1], bins=20, alpha=0.7, label='实际为1', color='blue')
plt.xlabel('预测概率')
plt.ylabel('频数')
plt.title('类别概率分布')
plt.legend()
plt.subplot(1, 2, 2)
plt.scatter(range(len(y_proba)), y_proba[:, 1], c=y_test, cmap='bwr', alpha=0.7)
plt.xlabel('样本索引')
plt.ylabel('预测为1的概率')
plt.title('样本预测概率')
plt.colorbar()
plt.tight_layout()
plt.show()
四、模型评估与比较
4.1 回归模型评估指标
-
均方误差(MSE):预测值与真实值之差的平方的平均值
-
均方根误差(RMSE):MSE的平方根
-
平均绝对误差(MAE):预测值与真实值之差的绝对值的平均值
-
R²分数:模型可解释的方差比例
4.2 分类模型评估指标
-
准确率:正确预测的样本比例
-
精确率:正类预测中实际为正类的比例
-
召回率:实际正类中被正确预测的比例
-
F1分数:精确率和召回率的调和平均
-
AUC-ROC:ROC曲线下的面积
python
from sklearn.metrics import roc_curve, auc, precision_recall_curve
from sklearn.model_selection import cross_val_score
# 比较不同分类算法的性能
classifiers = {
'逻辑回归': LogisticRegression(),
'K近邻': KNeighborsClassifier(n_neighbors=5),
'决策树': DecisionTreeClassifier(max_depth=3),
'随机森林': RandomForestClassifier(n_estimators=100),
'SVM': SVC(probability=True),
'朴素贝叶斯': GaussianNB()
}
# 使用乳腺癌数据集进行性能比较
cancer = load_breast_cancer()
X, y = cancer.data, cancer.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
results = {}
for name, clf in classifiers.items():
# 训练模型
clf.fit(X_train, y_train)
# 预测
y_pred = clf.predict(X_test)
y_proba = clf.predict_proba(X_test)[:, 1] if hasattr(clf, "predict_proba") else clf.decision_function(X_test)
# 计算指标
accuracy = accuracy_score(y_test, y_pred)
# 交叉验证
cv_scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
# ROC曲线
fpr, tpr, _ = roc_curve(y_test, y_proba)
roc_auc = auc(fpr, tpr)
results[name] = {
'accuracy': accuracy,
'cv_mean': cv_scores.mean(),
'cv_std': cv_scores.std(),
'fpr': fpr,
'tpr': tpr,
'roc_auc': roc_auc
}
print(f"{name}: 准确率={accuracy:.4f}, 交叉验证={cv_scores.mean():.4f}±{cv_scores.std():.4f}")
# 绘制ROC曲线比较
plt.figure(figsize=(10, 8))
for name, result in results.items():
plt.plot(result['fpr'], result['tpr'],
label=f'{name} (AUC = {result["roc_auc"]:.3f})')
plt.plot([0, 1], [0, 1], 'k--', label='随机分类器')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.title('不同分类算法的ROC曲线比较')
plt.legend()
plt.grid(True)
plt.show()
五、实际应用案例
5.1 房价预测(回归案例)
python
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import GridSearchCV
# 加载加州房价数据集
housing = fetch_california_housing()
X, y = housing.data, housing.target
# 创建DataFrame便于分析
df = pd.DataFrame(X, columns=housing.feature_names)
df['Price'] = y
print("数据集基本信息:")
print(df.info())
print("\n描述性统计:")
print(df.describe())
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 使用梯度提升回归树
gbr = GradientBoostingRegressor(random_state=42)
# 超参数调优
param_grid = {
'n_estimators': [100, 200],
'max_depth': [3, 4],
'learning_rate': [0.1, 0.05]
}
grid_search = GridSearchCV(gbr, param_grid, cv=5, scoring='neg_mean_squared_error', n_jobs=-1)
grid_search.fit(X_train, y_train)
# 最佳模型
best_gbr = grid_search.best_estimator_
y_pred = best_gbr.predict(X_test)
# 评估
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"\n梯度提升回归树结果:")
print(f"最佳参数: {grid_search.best_params_}")
print(f"均方误差: {mse:.4f}")
print(f"均方根误差: {rmse:.4f}")
print(f"R²分数: {r2:.4f}")
# 特征重要性
feature_importance = best_gbr.feature_importances_
feature_importance_df = pd.DataFrame({
'feature': housing.feature_names,
'importance': feature_importance
}).sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
plt.barh(feature_importance_df['feature'], feature_importance_df['importance'])
plt.xlabel('特征重要性')
plt.title('梯度提升回归树特征重要性')
plt.show()
5.2 信用卡欺诈检测(分类案例)
python
from sklearn.ensemble import IsolationForest
from sklearn.metrics import classification_report, confusion_matrix
import pandas as pd
# 生成模拟的信用卡交易数据(在实际应用中应使用真实数据)
np.random.seed(42)
n_samples = 10000
n_features = 5
# 生成正常交易数据
normal_transactions = np.random.normal(0, 1, (int(n_samples * 0.99), n_features))
# 生成欺诈交易数据(与正常交易有明显差异)
fraud_transactions = np.random.normal(3, 1.5, (int(n_samples * 0.01), n_features))
# 合并数据
X = np.vstack([normal_transactions, fraud_transactions])
y = np.hstack([np.zeros(len(normal_transactions)), np.ones(len(fraud_transactions))])
# 打乱数据
shuffle_idx = np.random.permutation(len(X))
X, y = X[shuffle_idx], y[shuffle_idx]
print(f"数据集形状: {X.shape}")
print(f"欺诈交易比例: {y.mean():.4f}")
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# 使用多种算法进行欺诈检测
fraud_models = {
'逻辑回归': LogisticRegression(class_weight='balanced'),
'随机森林': RandomForestClassifier(n_estimators=100, class_weight='balanced', random_state=42),
'孤立森林': IsolationForest(contamination=0.01, random_state=42)
}
fraud_results = {}
for name, model in fraud_models.items():
if name == '孤立森林':
# 孤立森林是无监督算法,需要特殊处理
model.fit(X_train)
y_pred = model.predict(X_test)
# 将孤立森林的输出转换为0/1(-1表示异常,1表示正常)
y_pred = (y_pred == -1).astype(int)
else:
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
fraud_results[name] = {
'accuracy': accuracy,
'confusion_matrix': cm
}
print(f"\n{name}结果:")
print(f"准确率: {accuracy:.4f}")
print("混淆矩阵:")
print(cm)
print("分类报告:")
print(classification_report(y_test, y_pred))
# 可视化比较
model_names = list(fraud_results.keys())
accuracies = [result['accuracy'] for result in fraud_results.values()]
plt.figure(figsize=(10, 6))
plt.bar(model_names, accuracies)
plt.xlabel('算法')
plt.ylabel('准确率')
plt.title('不同算法在欺诈检测中的性能比较')
plt.ylim(0.9, 1.0)
plt.show()
六、总结与展望
本文详细介绍了回归和分类算法的核心知识点,包括:
-
回归算法:线性回归、多项式回归、决策树回归、随机森林回归、支持向量回归等
-
分类算法:逻辑回归、K近邻、决策树、随机森林、支持向量机、朴素贝叶斯等
-
模型评估:各种评估指标和可视化方法
-
实际应用:房价预测和欺诈检测案例
算法选择建议:
-
对于线性关系明显的数据,线性回归和逻辑回归是良好的起点
-
对于复杂非线性关系,树模型(决策树、随机森林)和SVM通常表现更好
-
当数据量较大且特征间关系复杂时,集成学习方法(随机森林、梯度提升)往往最优
-
对于高维稀疏数据,朴素贝叶斯和线性模型可能更合适
未来发展趋势:
-
自动化机器学习:自动选择算法和调参
-
可解释AI:提高模型透明度和可解释性
-
联邦学习:在保护隐私的前提下进行分布式模型训练
-
元学习:让模型学会如何学习,快速适应新任务
回归和分类算法是机器学习的基石,掌握这些算法对于任何数据科学家或机器学习工程师都至关重要。通过理论学习和实践结合,我们能够更好地理解这些算法的原理和应用场景,从而在实际问题中选择合适的算法并取得良好的预测效果。