机器学习-逻辑回归【手撕】

逻辑回归

在模式识别问题中,所输出的结果是分类,比如是否是猫,这时候无法通过简单的线性回归来实现问题。同时,与线性回归不同的是,逻辑回归是一种名为回归的线性分类器,并常用于二分类,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。要理解逻辑回归,需要先理解线性回归。

线性回归

线性回归是机器学习中最简单的回归算法,它写作一个几乎人人熟悉的方程:

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 01分布的离散型变量,我们要怎么办呢?我们可以通过引入联系函数(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)就是我们逻辑回归返回的标签值。

python实现

通过代码生成一个数据集
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()

定义 S i g m o i d Sigmoid Sigmoid函数:
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

你可能感兴趣的:(机器学习,机器学习,逻辑回归,人工智能)