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

逻辑回归

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

线性回归

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

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

yp​red,以完成各种预测连续型变量的任务(比如预测产品销量,预测股价等等)。那如果我们的标签是离散型变量,尤其是,如果是满足

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)就是我们逻辑回归返回的标签值。

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

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/48681f5f9b.html