实现一个简单的机器学习分类器:从零开始构建逻辑回归模型
在当今的数据科学领域,机器学习(Machine Learning, ML)已经成为处理和分析大量数据的关键技术。通过机器学习算法,我们可以从数据中提取有价值的信息,并用于预测未来趋势或做出决策。本文将介绍如何从零开始构建一个简单的逻辑回归(Logistic Regression)分类器,重点在于理解其背后的数学原理以及如何使用Python代码实现这一过程。
1. 逻辑回归简介
逻辑回归是一种广泛应用于二分类问题的线性模型。尽管名字中有“回归”二字,但它实际上是一个分类算法。逻辑回归的目标是根据给定的输入特征(features),预测输出变量(通常是0或1)。它通过计算输入特征与权重之间的线性组合,并将其通过Sigmoid函数转换为概率值来实现这一点。
Sigmoid函数的形式如下:[P(y=1|x) = \frac{1}{1 + e^{-(w^T x + b)}}]其中,( w ) 是权重向量,( b ) 是偏置项,( x ) 是输入特征向量。
2. 数据准备
为了演示逻辑回归的实现,我们将使用一个简单的二维数据集。这个数据集包含两个特征(x1, x2),每个样本属于两类之一(0或1)。我们首先生成一些合成数据,并将其可视化以直观地理解数据分布。
import numpy as npimport matplotlib.pyplot as plt# 生成合成数据np.random.seed(42)X = np.random.randn(100, 2)y = (X[:, 0] + X[:, 1] > 0).astype(int)# 可视化数据点plt.scatter(X[y == 0, 0], X[y == 0, 1], label='Class 0', color='blue')plt.scatter(X[y == 1, 0], X[y == 1, 1], label='Class 1', color='red')plt.xlabel('Feature 1')plt.ylabel('Feature 2')plt.legend()plt.title('Synthetic Data for Logistic Regression')plt.show()
这段代码生成了100个二维数据点,并根据它们的线性组合是否大于0来分配类别标签。然后,我们使用Matplotlib库将这些数据点可视化,蓝色表示类别0,红色表示类别1。
3. 模型训练
接下来,我们需要定义逻辑回归模型的核心部分——Sigmoid函数和损失函数(Loss Function)。我们将使用梯度下降法(Gradient Descent)来最小化损失函数,从而更新权重和偏置项。
def sigmoid(z): return 1 / (1 + np.exp(-z))def compute_loss(y_true, y_pred): m = len(y_true) loss = -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) return lossdef gradient_descent(X, y, learning_rate=0.01, iterations=1000): m, n = X.shape w = np.zeros(n) b = 0 losses = [] for i in range(iterations): # 计算预测值 z = np.dot(X, w) + b y_pred = sigmoid(z) # 计算损失 loss = compute_loss(y, y_pred) losses.append(loss) # 更新参数 dw = np.dot(X.T, (y_pred - y)) / m db = np.sum(y_pred - y) / m w -= learning_rate * dw b -= learning_rate * db if i % 100 == 0: print(f"Iteration {i}, Loss: {loss:.4f}") return w, b, losses
上述代码实现了Sigmoid函数、损失函数的计算以及梯度下降算法。sigmoid
函数将线性组合的结果映射到[0, 1]区间;compute_loss
函数计算交叉熵损失;gradient_descent
函数执行梯度下降,迭代更新权重和偏置项。
4. 模型评估
完成模型训练后,我们需要对模型进行评估,以确保其具有良好的泛化能力。为此,我们可以使用测试数据集并计算准确率(Accuracy)、精确率(Precision)、召回率(Recall)等指标。
from sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score, precision_score, recall_score# 划分训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 训练模型w, b, losses = gradient_descent(X_train, y_train)# 预测测试集z_test = np.dot(X_test, w) + by_pred_prob = sigmoid(z_test)y_pred = (y_pred_prob >= 0.5).astype(int)# 计算评估指标accuracy = accuracy_score(y_test, y_pred)precision = precision_score(y_test, y_pred)recall = recall_score(y_test, y_pred)print(f"Accuracy: {accuracy:.4f}")print(f"Precision: {precision:.4f}")print(f"Recall: {recall:.4f}")# 绘制损失变化曲线plt.plot(losses)plt.xlabel('Iteration')plt.ylabel('Loss')plt.title('Loss over Iterations')plt.show()
在这段代码中,我们首先将数据划分为训练集和测试集。然后,使用训练集训练模型,并在测试集上进行预测。最后,我们计算并输出模型的准确率、精确率和召回率,并绘制损失随迭代次数的变化曲线。
5. 总结
通过本文,我们从零开始实现了一个简单的逻辑回归分类器,涵盖了数据生成、模型训练、参数更新以及模型评估等多个方面。虽然这是一个非常基础的实现,但它为我们理解逻辑回归的工作原理提供了宝贵的实践经验。在未来的工作中,可以进一步优化模型,例如引入正则化项、调整学习率或尝试不同的优化算法(如Adam、RMSprop等),以提高模型性能。
此外,逻辑回归作为线性模型,对于复杂的数据分布可能表现不佳。在这种情况下,可以考虑使用更复杂的非线性模型,如支持向量机(SVM)、神经网络等。希望本文能为你提供一个良好的起点,帮助你在机器学习领域不断探索和进步。