在模式识别问题中,所输出的结果是分类,比如是否是猫,这时候无法通过简单的线性回归来实现问题。同时,与线性回归不同的是,逻辑回归是一种名为回归的线性分类器,并常用于二分类,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。要理解逻辑回归,需要先理解线性回归。
线性回归是机器学习中最简单的回归算法,它写作一个几乎人人熟悉的方程:
z = \theta_0 +\theta_1 x_1 +\theta_2 x_2 + ....+\theta_n x_n
θ \theta θ被统称为模型的参数,其中 θ 0 \theta_0 θ0 被称为截距(intercept), θ 1 θ n \theta_1 ~ \theta_n θ1 θn被称为系数(coefficient),这个表达式,其实就和我们小学时就无比熟悉的 y = a x + b y = ax+b y=ax+b是同样的性质。我们可以使用矩阵来表示这个方程,其中x和 都可以被看做是一 个列矩阵,则有:
z = [\theta_0,\theta_1,\theta_2,...,\theta_n] * \begin{bmatrix}
x_0\\
x_1\\
x_2\\
...\\
x_n
\end{bmatrix} = \theta^T x (x_0=1)
线性回归的任务,就是构造一个预测函数 z z z来映射输入的特征矩阵 x x x和标签值 y y y的线性关系,而构造预测函数的核心就是通过找出模型的参数: θ T \theta^T θT和 θ 0 \theta^0 θ0。
通过函数 z z z,线性回归使用输入的特征矩阵 X X X来输出一组连续型的标签值 y p r e d y_pred ypred,以完成各种预测连续型变量的任务(比如预测产品销量,预测股价等等)。那如果我们的标签是离散型变量,尤其是,如果是满足 0 − 1 0-1 0−1分布的离散型变量,我们要怎么办呢?我们可以通过引入联系函数(link function),将线性回归方程 z z z变换为 g ( z ) g(z) g(z),并且令 g ( z ) g(z) g(z)的值 分布在 ( 0 , 1 ) (0,1) (0,1)之间,且当 g ( z ) g(z) g(z)接近0时样本的标签为类别0,当 g ( z ) g(z) g(z)接近1时样本的标签为类别1,这样就得到了一个分类模型。而这个联系函数对于逻辑回归来说,就是 S i g m o i d Sigmoid Sigmoid函数:
g(z) = \frac{1}{1+e^{-z}}
将线性回归中的 z = θ T x z=\theta^T x z=θTx带入函数中,就得到了二元逻辑回归模型的一般形式:
g(z) =y(x)= \frac{1}{1+e^{-\theta^T x}}
而 g ( z ) g(z) g(z)就是我们逻辑回归返回的标签值。
import numpy as np
import matplotlib.pyplot as plt
# 设置随机种子,以便结果可复现
np.random.seed(42)
# 生成随机数据
# 两个特征的均值和方差
mean_1 = [2, 2]
cov_1 = [[2, 0], [0, 2]]
mean_2 = [-2, -2]
cov_2 = [[1, 0], [0, 1]]
# 生成类别1的样本
X1 = np.random.multivariate_normal(mean_1, cov_1, 50)
y1 = np.zeros(50)
# 生成类别2的样本
X2 = np.random.multivariate_normal(mean_2, cov_2, 50)
y2 = np.ones(50)
# 合并样本和标签
X = np.concatenate((X1, X2), axis=0)
y = np.concatenate((y1, y2))
# 绘制散点图
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1, edgecolor='k')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Logistic Regression Dataset')
plt.show()
def sigmoid(x):
if x>0:
return 1.0/(1.0+np.exp(-x))
else:
return np.exp(x)/(1.0+np.exp(x))
class LogisticRegression:
def __init__(self, learning_rate=0.01, num_iterations=1000):
self.learning_rate = learning_rate
self.num_iterations = num_iterations
self.weights = None
self.bias = None
def fit(self, X, y):
num_samples, num_features = X.shape
# 初始化权重和偏置
self.weights = np.zeros(num_features)
self.bias = 0
# 梯度下降
for _ in range(self.num_iterations):
linear_model = np.dot(X, self.weights) + self.bias
y_pred = sigmoid(linear_model)
dw = (1 / num_samples) * np.dot(X.T, (y_pred - y))
db = (1 / num_samples) * np.sum(y_pred - y)
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
def predict_prob(self, X):
linear_model = np.dot(X, self.weights) + self.bias
y_pred = sigmoid(linear_model)
return y_pred
def predict(self, X, threshold=0.5):
y_pred_prob = self.predict_prob(X)
y_pred = np.zeros_like(y_pred_prob)
y_pred[y_pred_prob >= threshold] = 1
return y_pred
# 创建 Logistic 回归模型
logreg = LogisticRegression()
# 训练模型
logreg.fit(X, y)
# 预测样本
X_new = np.array([[2.5, 2.5], [-6.0, -4.0]])
y_pred_prob = logreg.predict_prob(X_new)
y_pred = logreg.predict(X_new)
print("Predicted Probabilities:", y_pred_prob)
print("Predicted Labels:", y_pred)
logistic回归可以用于分类非线性可分的数据。尽管logistic回归本身是一个线性分类器,但可以通过引入多项式特征、交互特征、组合特征等方法来扩展其能力,从而处理非线性的分类问题。
具体来说,可以通过特征工程的方式将原始特征进行变换,以引入非线性关系。例如,可以通过添加多项式特征,将原始特征的高阶项加入到模型中,例如原始特征的平方项、立方项等。还可以引入交互特征,将不同特征之间的乘积或分割点(例如,做差或做除)作为新的特征。
通过引入这些非线性特征,logistic回归可以更好地捕捉到数据中的非线性关系,从而能够更好地分类非线性可分的数据。需要注意的是,在引入非线性特征时,可能需要进行正则化或其他模型调优技巧,以避免过拟合问题。
https://blog.csdn.net/weixin_50744311/article/details/131523136