机器学习04-逻辑回归(python)

注意⚠️:在计算机和机器学习中,对数 log 如果没有写底 那么就表示以自然数 e 为底的对数:\log_e b,即计算机中的 log(没有底) \log 等同于 数学中的:ln 即 log(b) = \log_e b = \ln(b)

因此本文,如果log 没有底,包括对数似然函数中的log 均表示:log(b) = \log_e b = \ln(b),后续将不在重复说明。

​​​​​​​

逻辑回归是一种广泛应用于二分类问题(即是/否,0/1问题)的机器学习算法,也可以用于多分类问题。它不仅在理论上有很强的解释性,在现实生活中的很多场景中也被广泛使用。以下是一些常见的应用场景:

1. 医疗诊断

疾病预测:通过患者的体检数据或症状,预测患者是否患有某种疾病。比如:

• 预测一个人是否患有糖尿病。

• 预测一个肿瘤是否是恶性的(癌症)还是良性的。

健康风险评估:根据病历、生活习惯等信息,评估一个人的健康风险,例如心脏病的发作概率。

2. 金融风险评估

信用评分:根据个人的信用历史、收入水平等,预测贷款申请人是否有可能违约。这类应用广泛用于银行的信用评分系统。

欺诈检测:在支付系统中,基于交易行为和历史记录,预测某笔交易是否是欺诈交易。

3. 市场营销

客户流失预测:通过客户的购买行为、互动记录等数据,预测客户是否有可能停止使用某项服务,帮助企业提前采取措施挽留客户。

点击率预测:在广告投放中,根据用户的浏览历史、兴趣偏好等,预测用户是否会点击某一条广告。

4. 电子商务

推荐系统:根据用户的购买记录、搜索历史,预测用户是否会购买某个商品或点击某个链接。这有助于为用户提供个性化的推荐。

客户分类:根据客户的购买行为,将客户分类为活跃客户和非活跃客户,帮助企业制定有针对性的市场策略。

5. 社交网络

垃圾邮件检测:基于邮件的内容、发送者信息等,预测一封邮件是否是垃圾邮件。

情感分析:通过分析用户的评论、帖子或推文,预测其情感倾向(例如正面、负面或中性)。这在品牌的舆情监控中很常见。

6. 人力资源管理

员工离职预测:基于员工的工作表现、工作年限、薪资等数据,预测员工是否有可能在近期离职,帮助公司制定人才保留计划。

招聘筛选:根据应聘者的背景、教育经历等,预测其是否适合某个岗位,帮助企业自动化初步筛选简历。

7. 交通管理

事故风险预测:通过分析驾驶员的历史驾驶数据和实时的路况信息,预测是否会发生交通事故。

违章行为检测:基于驾驶员的行为数据,预测其是否有可能发生违章行为。

8. 保险行业

保险欺诈检测:基于客户的历史数据和保险索赔的情况,预测某个保险索赔是否可能涉及欺诈行为。

索赔风险预测:通过分析被保险人的年龄、健康状况、车辆状况等,预测其是否可能在未来提出保险索赔。

9. 制造业

质量控制:通过分析生产线上的数据,预测某个产品是否符合质量标准。

设备故障预测:根据机器设备的使用数据和维护记录,预测设备是否会在未来出现故障,从而进行预防性维护。

10. 体育分析

比赛胜负预测:通过球队的历史表现、球员的状态等,预测某场比赛的胜负情况。

运动员表现预测:根据运动员的训练数据,预测其在比赛中的表现,帮助教练制定策略。

11. 投票预测

选举结果预测:根据投票历史和调查数据,预测选民是否会支持某个候选人或某项政策。

总结:

逻辑回归在现实生活中用于解决各种分类问题,特别是那些需要预测二元结果的场景。它不仅具有较好的解释性,而且计算相对简单,因而在医疗、金融、市场营销、电子商务等领域中广泛应用。

1. Sigmoid 函数

在逻辑回归中,Sigmoid 函数的作用是将线性回归的输出结果(一个任意实数)映射到 0 到 1 之间的区间,用来表示预测某个事件发生的概率。

Sigmoid 函数的公式为:

f(x) = \frac{1}{1 + e^{-x}}

它的输出值总是在 (0, 1) 之间。对于逻辑回归来说,输出值可以看作某个事件发生的概率:

    •    当  f(x)  接近 1 时,模型预测事件发生的可能性较高。
    •    当  f(x)  接近 0 时,模型预测事件发生的可能性较低。

下面是这个方程的特点。

igmoid 函数 是一个非常重要的数学工具,尤其在解决分类问题时发挥着关键作用。今天我会用最简单的方式,帮助你理解它的作用,以及为什么在逻辑回归中使用 Sigmoid 函数。

1. 什么是 Sigmoid 函数?

Sigmoid 函数的公式如下:

f(x) = \frac{1}{1 + e^{-x}}

我们先画一下函数图:

return 1 / (1 + np.exp(-x))
import numpy as np
import matplotlib.pyplot as plt

# 定义 Sigmoid 函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 创建 x 轴上的点
x = np.linspace(-10, 10, 100)  # 在 -10 到 10 之间生成 100 个点

# 计算对应的 Sigmoid 函数值
y = sigmoid(x)

# 绘制 Sigmoid 函数曲线
plt.plot(x, y, label='Sigmoid Function')

# 添加标签和标题
plt.title('Sigmoid Function')
plt.xlabel('x')
plt.ylabel('f(x)')

# 标记重要的点
plt.axvline(x=0, color='r', linestyle='--', label='x=0')  # x=0的虚线
plt.axhline(y=0.5, color='g', linestyle='--', label='y=0.5')  # y=0.5的虚线

# 显示图例
plt.legend()

# 显示图形
plt.grid(True)
plt.show()

这个公式看起来复杂,但我们只需要理解它的效果:它把任何输入的数字变成 0 到 1 之间的值。

举个例子:

    •    如果  x = 10 ,那么  f(x)  的输出会非常接近 1。
    •    如果  x = -10 ,那么  f(x)  的输出会非常接近 0。
    •    当  x = 0  时, f(x) = 0.5 ,表示它正好位于中间。

这个函数不会严格等于 1 或 0,但在  x  取极端值时,函数的值会非常接近 1 或 0。让我们详细解释一下:

Sigmoid 函数

公式为:

f(x) = \frac{1}{1 + e^{-x}}


当  x \to +\infty 时

    1.    当  x \to +\infty  时, e^{-x} \to 0 ,因为  e^{-x}  是一个迅速趋近于零的指数衰减函数。
    2.    于是,Sigmoid 函数变成:

f(x) \approx \frac{1}{1 + 0} = 1

但它永远不会真正等于 1,只是无限接近于 1。

x \to -\infty 时

    1.    当  x \to -\infty 时, e^{-x} \to +\infty ,因为  e^{-x}  是一个迅速增长的指数函数。
    2.    于是,Sigmoid 函数变成:

f(x) \approx \frac{1}{1 + \infty} = 0

同样,它不会真正等于 0,而是无限接近于 0。

总结:

    •    当  x \to +\infty  时,Sigmoid 函数趋近于 1,但不会等于 1。
    •    当  x \to -\infty 时,Sigmoid 函数趋近于 0,但不会等于 0。

这个性质使得 Sigmoid 函数非常适合作为二分类问题中的激活函数,因为它能够输出非常接近 0 和 1 的值,用来表示事件的概率。

简而言之,Sigmoid 函数是一个“压缩器”,它把任意大或任意小的数字压缩到 0 到 1 之间。这非常重要,因为我们常常需要用 0 到 1 之间的数来表示某个事件发生的概率,比如某件事情发生概率30%,就是0.3, 百分百发生就是1

2. Sigmoid 函数在逻辑回归中的作用

在逻辑回归中,我们的任务通常是解决二分类问题。什么意思呢?就是我们要判断某件事的概率。比如:

    •    这个人是否会得病?会 /不会
    •    这封邮件是不是垃圾邮件? 是 /不是
    •    明天会不会下雨? 下 /不下

所有这些问题的答案都是“是”或者“否”,也就是二选一的问题。

这些问题的答案要么是“”,要么是“”。但是,我们不只是想得到一个简单的“是”或者“否”,而是希望预测这个事件发生的概率,比如:

• 这个人有 70% 的可能会购买商品。

3. 逻辑回归模型的工作方式

逻辑回归的核心是:我们要预测一个事件发生的概率。为了预测这个概率,我们首先要对输入数据进行计算,得到一个数字结果,比如 2、5、-3 等等。但这些数字并不能直接告诉我们事件发生的概率。所以我们需要用 Sigmoid 函数来把这个数字结果转换为概率,即转换为 0 到 1 之间的值。

1. 为什么要得到一个数字?

逻辑回归首先会对输入的特征进行线性计算,也就是说,把所有的输入数据通过一个简单的线性函数计算出一个“原始的分数”(也叫“线性组合”)。我们把这个过程想象成一个“评分系统”。

举个例子:

假如你在预测一个人是否会购买一件商品,这个过程可能是这样的:

• 如果某个人的年龄、收入和以往购买记录等因素(输入特征)都表明他很可能会购买,那么这个人可能得到一个比较大的分数,比如 5。

• 如果某个人的特征表明他不太可能购买商品,比如收入较低、之前没买过类似商品,他可能得到一个较低的分数,比如 -3。

所以,这一步的线性计算得到的数字结果实际上就是一种“打分系统”,但这些分数不能直接解释成概率。

2. 为什么数字不能直接告诉我们概率?

原因是:这些“分数”可以是任意的,比如 -3、2、10 等等。它们可能很大,也可能很小。显然,你不可能通过这些数字直接判断某个事件发生的概率,因为概率必须在 0 到 1 之间,而这些数字的范围是无穷大的。

这时,我们需要把这个数字转换成一个可以解释为概率的值。而这里的“转换器”就是Sigmoid 函数

3. 为什么用 Sigmoid 函数?

Sigmoid 函数有一个非常特殊的性质:它能把任何数值转换成 0 到 1 之间的值,也就是说,我们通过它可以把“分数”转换为一个可以理解为“概率”的值。

例如:

• 线性计算得到的分数是 5,用 Sigmoid 函数转换后,得到的概率大约是 0.993,这就表示这个人有 99.3% 的可能会购买商品。

• 线性计算得到的分数是 -3,用 Sigmoid 函数转换后,得到的概率大约是 0.047,这表示这个人只有 4.7% 的可能会购买商品。

逻辑回归选择使用 Sigmoid 函数,而不是简单的归一化,主要是由于以下几个原因:

1. Sigmoid 函数的输出范围和概率性质

Sigmoid 函数的公式为:

S(x) = \frac{1}{1 + e^{-x}}

其输出范围在 (0) 到 (1) 之间,完美适合作为概率的表示。这是逻辑回归的核心需求:将任意的线性组合(得分)转换为概率值。而简单的线性归一化(比如将数值压缩到 (0) 到 (1) 的范围)无法处理一些关键问题,例如如何使得较大的数值(例如 100 或 -100)也可以在 (0) 和 (1) 之间快速收敛。

特点:
  • 当 (x) 非常大时,(S(x) ) 接近于 (1);

  • 当 (x) 非常小时,(S(x)) 接近于 (0);

  • 当 (x) 为 (0) 时,(S(x)) 刚好为 (0.5)。

这种特性非常适合分类问题的场景,因为我们希望模型可以在不同的输入特征下给出明确的分类决策(0 或 1),而 Sigmoid 函数通过将所有输出值压缩到 (0) 和 (1) 之间,能够将大数和小数的范围映射到概率上。

2. 非线性特性

Sigmoid 函数是一个非线性函数,这一点很重要。

  • 如果仅使用线性归一化,函数仍然保持线性的特性。也就是说,归一化后的输出只是输入的线性缩放。这无法捕捉输入和输出之间复杂的非线性关系。

而 Sigmoid 的非线性使得逻辑回归模型可以在输入特征与概率输出之间引入复杂的非线性变化。这让模型能够有效捕捉输入特征与输出概率之间的非线性关系,从而使得分类边界更加灵活。

3. 可微性与优化

Sigmoid 函数的一个重要特性是它的可微性,并且其导数公式非常简单:

S'(x) = S(x) \cdot (1 - S(x))

这使得在训练模型时,我们能够通过梯度下降算法来优化逻辑回归的损失函数(通常是交叉熵损失)。梯度下降依赖于可微性,通过计算每个参数的梯度,我们可以逐步优化参数,找到最优解。

如果仅使用线性归一化,这样的非线性和光滑的性质将丢失,从而使得优化过程变得更加复杂或者无法进行。

4. 处理极端值

在实际应用中,线性模型输出的数值可能非常大(如 100 或 -100),但我们需要将它们转换为概率:

  • 线性归一化无法有效处理极端值:如果模型输出一个极大的数(例如 100),归一化后的数值会接近 (1) 或 (0),但不能很好地捕捉极值变化带来的细微差异。

  • Sigmoid 函数能有效压缩极端值:Sigmoid 函数在处理极端值时非常有效。随着输入 (x) 的绝对值增大,Sigmoid 函数的输出迅速逼近 (0) 或 (1),但不会完全等于 (0) 或 (1)。这保证了模型可以稳定地处理极端值,而不会产生数值上的不稳定性。

5. 概率解释的数学基础

Sigmoid 函数有一个天然的概率解释,因为它与Logit 函数紧密相关。逻辑回归实际上是在建模对数几率(),其表达式为:

\text{logit}(p) = \log \left(\frac{p}{1 - p}\right) = x

当我们将对数几率反转为概率时,正好是 Sigmoid 函数:

p = \frac{1}{1 + e^{-x}}

这意味着逻辑回归通过 Sigmoid 函数,实际上是在建模目标的条件概率,反映了分类问题中的真实概率分布。这是简单的归一化无法提供的概率解释。

总结:

  • Sigmoid函数能够将任意的数值(例如,线性组合结果)压缩到 (0) 到 (1) 的范围,适合作为概率。

  • 非线性特性允许模型学习更加复杂的关系,而不仅仅是线性的输入输出映射。

  • 可微性支持梯度下降等优化算法,使得模型训练更加高效。

  • 处理极端值能力强,可以将极大或极小的线性组合结果稳定地转换为近似的 (0) 或 (1)。

  • 概率解释强,直接与概率建模相关联,而不仅仅是数值上的缩放。

因此,逻辑回归选择 Sigmoid 函数而非简单的归一化函数,这是因为它具备了良好的非线性转换能力、数值稳定性、可解释性,以及能够有效用于模型优化的特性。

4. 完整的逻辑回归过程

1. 线性计算:先对输入数据进行线性计算,得到一个“分数”。这个分数可以是任意大或任意小的数字,比如 -3、2、5 等等。

2. 用 Sigmoid 函数将分数转换为概率:通过 Sigmoid 函数,把分数压缩到 0 到 1 之间,用来表示事件发生的概率。

3. 得到最终概率:转换后的结果就是预测的概率值,比如 70% 的可能性会购买商品。

总结:

得到一个数字(分数) 是逻辑回归的第一步。通过输入数据的线性组合,计算出一个分数。(后面内容会详细讲解怎么计算分数)

这个分数不能直接解释成概率,因为它的范围可能非常大,不能用来描述 0 到 1 之间的概率。

Sigmoid 函数 可以将这个分数转换为 0 到 1 之间的概率,用来描述事件发生的可能性。

通过这样的过程,我们就可以利用逻辑回归模型预测某个事件发生的概率了,比如客户购买商品的可能性等。

假设我们有一个线性函数:

z = \theta_0 + \theta_1 x  

1. 线性函数是什么?

你可以把线性函数看成是一个简单的数学模型,比如:

y = kx + b

在这个公式里:

    •     k  是斜率,表示  x  变化时, y  变化的速度。
    •     b  是偏移量,决定了直线在图上的位置。

这个公式通过输入  x  和权重 \theta_1  来得到一个数值  z 。但是,这个  z  的范围是从负无穷到正无穷,没法表示概率。

线性函数就是:我们给模型一个输入  x ,模型计算出一个输出  y 。在逻辑回归里,因为会有多个x影响y,我们常用的线性公式是:

z = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \dots + \theta_n x_n

这其实就是多个输入 x_1, x_2, x_3 经过一系列加权计算,最后得到一个数值 z。这个  z 可以理解为对某个事件的打分,比如某个人有多大可能会买某样东西。

2. 为什么这个  z  不适合直接表示概率?

这个打分  z  有个问题:它可以是任何数字,从负无穷到正无穷都可以。而概率应该是在 0 到 1 之间的一个值:

    •    0 表示事件不可能发生。
    •    1 表示事件肯定发生。

例如:

    •    如果  z = -5 ,表示“几乎不可能发生”,但我们不能直接把  z = -5  看作概率,因为概率不能是负数。
    •    如果  z = 10 ,表示“很有可能发生”,但同样也不能把 10 当成概率,因为概率最大也只能是 1。

所以,我们需要把这个  z  转换为 0 到 1 之间的值,来表示事件发生的概率。

3. Sigmoid 函数是怎么转换的?

这时,Sigmoid 函数就派上用场了。它可以把这个  z的任意 值转换为 0 到 1 之间。公式变成:

P(y=1|x) = \frac{1}{1 + e^{-z}}

这样,得到的结果就是一个在 0 和 1 之间的值,可以表示某个事件发生的概率。

所以:我们要强调的是:在逻辑回归中, z  不是最终的输出,而是用来进一步计算概率的中间结果。

3.1  P(y=1|x) 是什么,怎么理解?

假设我们想预测某个人是否会购买商品

  P(y = 1 | x)  的意思就是:在已知这个人的特征  x  的情况下,他会购买商品的概率。

    •     P(y = 1 | x) :表示在给定输入  x  的条件下,事件  y = 1  发生的概率。
    •     y = 1  表示“这个人会购买商品”。
    •     x  表示输入的特征,比如年龄、收入、购买历史等。

所以  P(y = 1 | x)  的意思就是:在已知这个人的特征  x  的情况下,他会购买商品的概率。

这种表示法叫做条件概率,用来表示在已知某些条件下,事件发生的概率。我会用一个通俗易懂的例子和类比来帮助你理解。

1. 条件概率的基本概念

假设你去商店买冰淇淋,但今天的天气对你买冰淇淋的决策有影响。比如,如果是炎热的夏天,你更有可能买冰淇淋,而如果是寒冷的冬天,你可能就不会买。

条件概率表示在某些条件下,某个事件发生的概率。用符号表示就是:

P(A | B)

这读作:“在已知事件 B 发生的条件下,事件 A 发生的概率”。

    •     A :你要预测的事件(比如你买了冰淇淋)。
    •     B :已知的条件(比如今天是夏天)。

所以, P(A | B)  就是:在已知今天是夏天的前提下,你买冰淇淋的概率。

回到逻辑回归的例子,假设我们想预测某个人是否会购买商品。我们可以使用条件概率来表示这个问题:

    •     P(y = 1 | x) :表示在给定输入  x  的条件下,事件  y = 1  发生的概率。
    •     y = 1  表示“这个人会购买商品”。
    •     x  表示输入的特征,比如年龄、收入、购买历史等。

所以  P(y = 1 | x)  的意思就是:在已知这个人的特征  x  的情况下,他会购买商品的概率。

3. 为什么用条件概率?

条件概率帮助我们表达复杂的预测问题。逻辑回归模型的任务是根据给定的输入  x (比如年龄、收入等特征),来预测某件事情  y  是否会发生(比如是否会购买商品)。这时候,条件概率非常适合表示这种基于条件的预测问题。

具体来说,逻辑回归模型使用条件概率来预测一个二分类问题的概率:

P(y=1|x) = \frac{1}{1 + e^{-z}}

这表示,在已知输入特征  x  后,预测  y = 1 (某件事情会发生,比如购买商品)的概率是多少。

4. 通俗类比:冰淇淋购买问题

假设我们要预测一个人在某天是否会买冰淇淋:

    •     y = 1  表示“这个人买了冰淇淋”。
    •     x  是已知的条件,比如当天的温度。

那么  P(y = 1 | x)  就表示在已知天气(温度)的情况下,这个人买冰淇淋的概率是多少。

    •    如果天气非常热(比如  x = 35^\circ),这个概率  P(y = 1 | x)  可能接近 1,表示他非常有可能会买冰淇淋。
    •    如果天气很冷(比如  x = 0^\circ ),这个概率  P(y = 1 | x)  可能接近 0,表示他几乎不可能买冰淇淋。

5. 总结

    •     P(y = 1 | x)  表示在已知条件  x  下,事件  y = 1 (事情发生)的概率。
    •    这种表示法在逻辑回归中用来描述已知输入特征后,事件发生的概率,比如预测一个人在某些特定条件下是否会购买商品。

条件概率表示法帮助我们在给定输入条件的情况下,预测某个事件发生的可能性。这种表示法非常直观,用来解决现实中的很多预测问题。

4. 为什么 Sigmoid 函数适合逻辑回归?

简单来说,Sigmoid 函数之所以适合逻辑回归,是因为它具有以下特性:

    1.    输出值范围是 0 到 1:在逻辑回归中,我们需要得到一个概率值,表示某件事发生的可能性,而概率范围正好是 0 到 1。
    2.    平滑的曲线:Sigmoid 函数的曲线非常平滑,可以把线性计算结果转换为概率,这样模型可以很容易找到最佳解。
    3.    可以设置阈值:通过设置阈值(比如 0.5),我们可以很方便地判断某个事件更有可能发生还是不发生。如果预测的概率大于 0.5,就判断为“是”,如果小于 0.5,就判断为“否”。

5. 通俗类比

可以这样理解:假如你在玩一个游戏,游戏中要求你预测某件事情发生的可能性,比如这个篮球能不能投进篮筐。

    •    当你的计算结果  z  很大时(比如 10),Sigmoid 函数会输出一个接近 1 的结果,意思是“很有可能投进”。
    •    当你的计算结果  z  很小时(比如 -10),Sigmoid 函数会输出一个接近 0 的结果,意思是“几乎不可能投进”。
    •    如果计算结果是  z = 0 ,Sigmoid 函数会输出 0.5,意思是“可能性各半”。

这个过程就像是给计算结果上了一个“概率尺”,帮助我们做出最终的判断。

总结:

    •    Sigmoid 函数能够将任意数值压缩到 0 和 1 之间,适合用来表示概率。
    •    在逻辑回归中,Sigmoid 函数帮助我们将模型的输出转换为概率,用来判断某个事件发生的可能性。
    •    逻辑回归用它来解决二分类问题,比如判断某个邮件是不是垃圾邮件,某个人是否生病等。

通过这些特点,Sigmoid 函数成为逻辑回归的核心函数,帮助我们解决现实中的很多二分类问题。

学习逻辑回归需要了解概率知识。下面我们简单讲解下

1. 概率(Probability)

概率是表示某个事件发生可能性的度量。事件发生的概率  P  总是在 0 和 1 之间,其中:

    •     P = 0  表示事件不可能发生。
    •     P = 1  表示事件必然发生。

例如:

    •    在北京上午乘车的概率  P_A = 0.7 ,表示周一早上乘车的概率是 70%。

2. 联合概率(Joint Probability)

联合概率是指两个或多个随机事件同时发生的概率。它表示多个事件一起发生的可能性。例如,周一早上和周二早上同时乘车的概率,可以通过两个事件的概率乘积来计算。

公式:

P(A \cap B) = P_A \cdot P_B

举例:

    •    周一早上乘车的概率  P_A = 0.7 ,周二早上乘车的概率  P_B = 0.7 ,那么两天早上都乘车的概率是:

P(A \cap B) = 0.7 \times 0.7 = 0.49

这意味着两天早上同时乘车的概率是 49%。

3. 条件概率(Conditional Probability)

条件概率是指事件 A 在另一个事件 B 已经发生的条件下发生的概率,表示为  P(A|B) 。它用于衡量在已知某一事件发生的情况下,另一个事件发生的可能性。

公式:

P(A|B) = \frac{P(A \cap B)}{P(B)}

它表示事件 B 已经发生的情况下,事件 A 发生的概率。

举例:

    •    如果我们知道周一早上乘车的概率是 P_A = 0.7 ,周一中午乘车的概率  P_B = 0.3 ,那么在已经知道早上乘车的情况下,周一中午乘车的概率  P(B|A)  依然等于  P_B = 0.3

4. 应用场景:

在逻辑回归中,概率是用于计算某个事件(例如某个类别)的发生可能性的基础。例如,在预测一个病人是否患病时,模型输出的概率值表示病人患病的可能性。如果该概率大于某个阈值(例如 0.5),则可以判断病人患病,否则则认为没有患病。

5. 总结:

    •    联合概率表示多个事件同时发生的概率。
    •    条件概率表示在另一个事件已经发生的条件下某事件发生的概率。

这些概率概念在逻辑回归中被广泛使用,帮助模型估计不同类别的事件发生的可能性。

逻辑回归需要了解 “极大似然估计” 思想
极大似然估计(Maximum Likelihood Estimation, MLE) 是一种用于估计统计模型参数的常用方法。它的核心思想是,给定观测到的样本数据,选择最有可能使这些观测结果发生的参数值。极大似然估计在各种统计模型和机器学习算法中广泛应用,如逻辑回归、线性回归、朴素贝叶斯等。(即用已经观察到的结果,估计概率)

极大似然估计(Maximum Likelihood Estimation, MLE),目的是通过已知的观测数据来估计模型中的未知参数。以在这个图片例子,假设有一个硬币,其正面和反面出现的概率可能不同,我们希望通过掷硬币的实验结果来估计硬币正面朝上的概率  \theta,也就是说,我不知道一个事件的概率  \theta是多少,但是我通过我得到的样本现象D,我去找当我的样本现象D 发生的概率最大的时候,通过求极大值点(偏导方式)求出概率\theta是多少?

案例中为什么要求极大值?

    1.    核心思想:
    •    极大似然估计的核心思想是:找到最可能导致当前观测结果发生的参数。换句话说,基于现有的观测数据,找到使得该数据最可能发生的参数值。
    2.    似然函数:
    •    在极大似然估计中,我们首先构建一个似然函数,这个函数描述了在给定某个参数 \theta 的情况下,观测数据  D  发生的可能性(概率)。在这个例子中,硬币正面朝上的概率为 \theta,反面朝上的概率为 1 - \theta
    •    根据观测到的掷硬币结果  D = {正面, 反面, 反面, 正面, 正面, 正面},我们可以写出这个似然函数:

P(D|\theta) = \theta^4(1 - \theta)^2

这里,正面出现了 4 次,反面出现了 2 次。
    3.    为什么要求极大值:
    •    既然似然函数描述了观测数据在给定参数 \theta 下发生的概率,我们的目标是找到使得似然函数最大的那个 \theta  值。也就是说,哪个 \theta  值能够使观测到的结果最有可能发生。
    •    在数学上,极大似然估计就是通过对似然函数求导,找到使得导数为 0 的点,也就是极大值点。
    4.    实际操作:
    •    在图中的例子中,似然函数  f(\theta) = \theta^4(1 - \theta)^2 ,然后通过对这个函数求导,找到函数的极大值。通过计算导数并解方程,最终得出  \theta = 2/3 (因为方程解出来一共3个解:0,1,2/3 ,很明显如果0或者1 的话不符合正反面出现的现象。),这表示硬币正面朝上的概率的估计值是  2/3 。

总结:

极大似然估计的目标是通过观察到的数据来估计模型中的未知参数。我们通过构建似然函数,然后求其极大值来找到最有可能的参数值。在这个硬币掷出的例子中,我们希望找到最能解释观察到的正反面结果的硬币正面出现概率  \theta ,因此我们求似然函数的极大值。

极大似然估计的步骤

    1.    构建似然函数:
似然函数是一个关于参数的函数,它表示在给定参数  \theta  下,观测到的数据 D 发生的概率。对于独立同分布(iid)的数据,似然函数 L(\theta) 通常是样本中各个点的联合概率:

L(\theta | D) = P(D|\theta) = \prod_{i=1}^{n} P(x_i|\theta)

其中, P(x_i|\theta) 是每个观测数据 x_i在参数 \theta 给定的情况下的概率。


这就是\prod 的意思:累积乘法。

1. 定义似然函数

给定一个模型及其参数,我们首先需要定义一个似然函数。似然函数表示的是,在给定数据的前提下,模型参数的取值能使数据出现的概率。简单来说,它是参数与观测数据之间的概率关系。

假设我们有一个数据集X = \{x_1, x_2, \dots, x_n\}​​​​​​​,其每个数据点 x_i 是独立同分布的。假设这些数据点的概率分布由参数 \theta 控制,似然函数L(\theta; X) 表示在给定参数 \theta 下观测到这组数据的概率。由于数据点是独立的,我们可以将似然函数表示为每个数据点在参数 \theta 下的联合概率的乘积:


L(\theta; X) = P(X | \theta) = \prod_{i=1}^{n} P(x_i | \theta)


这就是通常情况下的似然函数,表示观测到数据 X 的概率是由参数 \theta 控制的。

即每个数据点在参数 \theta 下的概率的乘积。

\prod_{i=1}^{n}  这个是数学符号中的连乘符号

举例:

如果 a_1 = 2, a_2 = 3, a_3 = 4,那么:

\prod_{i=1}^{3} a_i = 2 \cdot 3 \cdot 4 = 24

2. 构建对数似然函数

由于似然函数通常是多个概率值的乘积,而乘积操作在数学上不如加法容易处理(尤其是在求导的过程中)。可能会出现以下问题:

数值稳定性:概率值通常比较小(在 0 和 1 之间),尤其当数据量很大时,多个小数的乘积会变得非常小,可能导致数值下溢出,甚至无法准确表示。因此,处理乘积操作容易产生数值误差。

计算复杂性:乘法运算在数学上不如加法容易处理,特别是在求导的过程中。加法比乘法更容易处理,因为乘积的导数涉及到链式法则,而和的导数则直接等于各项的导数之和。

为了解决这些问题,我们对似然函数取对数,转化为对数似然函数。取对数的好处是,将乘法操作转化为加法操作,同时对数是单调递增的,不会改变最大值的取值点位置。

推导对数似然函数

对似然函数  L(\theta; X) = \prod_{i=1}^{n} P(x_i | \theta) 取对数:


\ell(\theta; X) = \log L(\theta; X) = \log \left( \prod_{i=1}^{n} P(x_i | \theta) \right)


根据对数的性质,乘积的对数等于各项对数之和:

\ell(\theta; X) = \sum_{i=1}^{n} \log P(x_i | \theta)


这就是对数似然函数的公式。通过取对数,我们将原本的乘法操作转化成了加法操作,使得后续计算更加简单和稳定。

因此对数似然函数定义为:

\ell(\theta; X) = \log L(\theta; X) = \sum_{i=1}^{n} \log P(x_i | \theta)

为什么要使用对数似然函数?

    •    数值稳定性:对数操作可以避免多个小数相乘导致的下溢出问题,因为对数可以将小数转换为负数,从而防止结果接近 0。
    •    计算便利性:取对数后,乘法转换为加法,简化了求导计算。因为:
    •    乘法时:\prod  的导数较复杂,涉及多个变量的连锁反应。
    •    加法时:\sum 的导数是简单的逐项求导,然后将各项相加。
在实际使用中,我们往往需要对似然函数求导以找到参数\theta 的最优解。在对数似然函数的情形下,求导会变得更加简单。

3. 最大化对数似然函数

接下来,我们需要找到使得对数似然函数取得最大值的参数 \theta。为此,我们需要对对数似然函数求导,并找到其极值点。

具体步骤是:

    •    对对数似然函数关于参数 \theta​​​​​​​求导数,得到导数(也称为得分函数):

\frac{\partial \ell(\theta; X)}{\partial \theta}

    •    将这个导数设为零,得到一个关于\theta的方程:

\frac{\partial \ell(\theta; X)}{\partial \theta} = 0

    •    解这个方程,求出参数 \theta 的值,即为极大似然估计的解。

4. 验证极值

在找到使得导数为零的 \theta​​​​​​​ 值后,我们需要确认它确实是对数似然函数的最大值,而不是最小值或其他情况。一般方法是:

    •    计算对 \theta的二阶导数,检查它在该点的符号。如果二阶导数为负,说明在该点取得最大值:

\frac{\partial^2 \ell(\theta; X)}{\partial \theta^2} < 0

    •    如果二阶导数为负,则说明该点是最大值,可以将其作为最终估计的参数。

1. 二阶导数法则的原理

当我们说函数在某点的一阶导数为 0 时,意味着函数在这个点的斜率是 0,曲线在该点处“水平”,这说明可能是极大值、极小值或拐点。

然而,一阶导数等于 0 并不能告诉我们这是极大值还是极小值。为了确定这一点,我们使用二阶导数来判断函数在该点的凹凸性。

    •    二阶导数 f{\prime}{\prime}(x)  用来描述函数的曲率,也就是说它告诉我们函数在某点是向上还是向下弯曲。

具体来说:

    •    如果  f{\prime}{\prime}(x) > 0 ,那么函数在该点是向上弯曲的(像一个“碗”),这意味着函数在该点取得极小值。
    •    如果 f{\prime}{\prime}(x) < 0 ,那么函数在该点是向下弯曲的(像一个“倒碗”),这意味着函数在该点取得极大值。
    •    如果 f{\prime}{\prime}(x) = 0,二阶导数不能提供足够的信息来判断,我们可能需要更高阶的导数来判断该点是否为极值。

3. 举例说明

我们以一个简单的二次函数为例来说明这个过程。考虑函数:


f(x) = x^2 - 4x + 3


(1) 一阶导数

首先,我们对 f(x) 求一阶导数:


f{\prime}(x) = 2x - 4


将一阶导数设为 0,求解方程:

2x - 4 = 0 \implies x = 2

这说明 x = 2 是一个驻点,可能是极大值、极小值或拐点。接下来我们需要使用二阶导数来进一步判断。

(2) 二阶导数

对 f(x) 再求一次导数,得到二阶导数:


f{\prime}{\prime}(x) = 2


注意这里f{\prime}{\prime}(x) = 2,是一个常数大于 0,这意味着函数在 x = 2 处是向上弯曲的,因此这个点是一个极小值。

(3) 验证极小值

我们将 x = 2 代入原函数 f(x) 中:

f(2) = (2)^2 - 4(2) + 3 = 4 - 8 + 3 = -1


所以,函数在 x = 2 处取极小值,值为 -1。

4. 扩展:泰勒展开的解释

如果从更深入的角度来理解二阶导数法则,可以通过泰勒展开来看。在x_0附近,我们可以使用泰勒展开式来近似函数:


f(x) \approx f(x_0) + f{\prime}(x_0)(x - x_0) + \frac{f{\prime}{\prime}(x_0)}{2}(x - x_0)^2​​​​​​​


f{\prime}(x_0) = 0  时,展开式简化为:

f(x) \approx f(x_0) + \frac{f{\prime}{\prime}(x_0)}{2}(x - x_0)^2


这说明函数在 x_0 附近的变化趋势由 f{\prime}{\prime}(x_0) 决定:

    •    如果f{\prime}{\prime}(x_0) > 0,则 (x - x_0)^2 使函数的值增大,说明函数在该点是极小值。
    •    如果 f{\prime}{\prime}(x_0) < 0,则 (x - x_0)^2 使函数的值减小,说明函数在该点是极大值。

5. 应用实例


举个例子

假设我们有一枚硬币,我们想知道它正面朝上的概率是多少。我们可以通过抛硬币多次,记录正反面结果,来估计这个概率。

假设

    •    我们抛了硬币 10 次,得到了 7 次正面和 3 次反面。
    •    我们设硬币正面朝上的概率为 \theta,反面朝上的概率为 1 - \theta

构建似然函数

根据抛硬币的实验数据,观测结果为 7 次正面,3 次反面。我们可以写出似然函数:

这个函数表示,在正面概率为  \theta 时,观测到 7 次正面和 3 次反面的概率。

取对数似然函数


最大化对数似然函数

为了找到使对数似然函数最大的  \theta,我们对  \ell(\theta)  求导并令其等于 0,来找到极值点:

\frac{d}{d\theta} \left(7\log(\theta) + 3\log(1-\theta)\right) = 0

1. 对数似然函数的求导过程

首先,我们将对似然函数 L(\theta) 对 \theta 求导。注意⚠️:此处log(\theta) 是没有底的,表示log_e(\theta)


\frac{d}{d\theta} \left(7\log(\theta) + 3\log(1-\theta)\right)


我们将分别对两个部分求导:

    •    对 7\log(\theta) 求导:

\frac{d}{d\theta} 7\log(\theta) = 7 \cdot \frac{1}{\theta}

    •    对 3\log(1-\theta)求导:
这里我们要用链式法则,因为 \log(1-\theta) 是一个复合函数。首先对\log(1-\theta)求导:

\frac{d}{d\theta} \log(1-\theta) = \frac{-1}{1-\theta}

乘上前面的系数 3:

3 \cdot \frac{-1}{1-\theta} = \frac{-3}{1-\theta}


所以整个对数似然函数的导数为:

\frac{d}{d\theta} L(\theta) = \frac{7}{\theta} - \frac{3}{1-\theta}


2. 将导数设为 0

为了找到最大值或最小值,我们将导数设为 0:


\frac{7}{\theta} - \frac{3}{1-\theta} = 0


3. 解这个方程

我们现在解这个方程:


\frac{7}{\theta} = \frac{3}{1-\theta}


通过交叉相乘,我们得到:


7(1-\theta) = 3\theta


展开并整理方程:


7 - 7\theta = 3\theta


将所有含\theta 的项移到一边:


7 = 10\theta


解出 \theta


\theta = \frac{7}{10} = 0.7


4. 结论

通过求导并解方程,我们找到了使对数似然函数最大化的参数 \theta = 0.7

至此我们就通过这个案例了解到,当我们不清楚事件概率\theta = ? 的时候,通过观察到的一个事件合集D,求导之后得到了独立事件发生的概率了\theta = 0.7,以上就是极大似然的思想

极大似然估计(MLE)的优点

    •    直观性:极大似然估计基于我们希望选择使观测数据最可能发生的参数,因此容易理解。
    •    通用性:MLE 可以用于各种不同的统计模型,只要能够构建似然函数。
    •    一致性:当样本量足够大时,MLE 能够收敛到真值。

极大似然估计的缺点

    •    计算复杂性:对于复杂的模型,似然函数可能非常复杂,求极大值的计算成本较高。
    •    局限性:如果样本量较小,MLE 可能会产生偏差。
    •    过拟合:在复杂模型中,MLE 可能会出现过拟合的情况,因此通常需要配合正则化方法来避免。

总结

极大似然估计是一种强大且广泛应用的方法,用于通过最大化观测数据发生的概率来估计模型参数。它在许多统计模型和机器学习算法中起到关键作用。

逻辑回归需要了解数学

对数函数的概念和性质,这些知识对理解指数增长、概率论以及信息理论等都有帮助,因此在逻辑回归算法中需要学习。接下来,我会用简单易懂的方式详细讲解这些内容。

1. 什么是对数函数?

对数函数是指数函数的逆运算。简单来说,对数就是求指数的操作。

如果有一个等式  a^b = N ,那么  b  就是以 a 为底数,N 的对数,记作:

b = \log_a N


    •     a  是对数的底数,必须大于 0 且不等于 1。
    •     N  是对数的结果。
    •     b  是指数。

例子:

    •     \log_{10} 100 = 2,因为  10^2 = 100
    •     \log_2 16 = 4 ,因为  2^4 = 16

对数函数的一个重要特性是:它将指数函数翻转过来,我们通过对数函数可以从结果推导出对应的指数。

2. 对数函数的图像

​​​​​​​

图片中展示了对数函数的图像,例如\log_2 x\log_3 x 和其他对数函数的图像。

    •    当底数  a > 1  时,图像呈现出上升的趋势,随着  x  变大,函数值也缓慢变大。
    •    当底数  a < 1  时,图像呈现出下降的趋势,随着  x  增大,函数值变得更小。

这反映了对数函数的一个重要特性:增长速度减缓。这在描述一些实际情况时非常有用,比如人口增长和复利效应。

3. 对数函数的性质

对数函数有三个非常重要的运算性质,它们帮助我们简化对数计算。分别是:

性质 1:对数的乘法法则


\log_a(MN) = \log_a M + \log_a N​​​​​​​


    •    这意味着乘积的对数等于各自对数的和。

例子:

\log_2(4 \times 8) = \log_2 4 + \log_2 8 = 2 + 3 = 5

因为  2^2 = 42^3 = 8 ,而  2^5 = 32

性质 2:对数的除法法则


\log_a\left(\frac{M}{N}\right) = \log_a M - \log_a N


    •    这意味着商的对数等于被除数的对数减去除数的对数。

例子:

\log_2\left(\frac{8}{4}\right) = \log_2 8 - \log_2 4 = 3 - 2 = 1

因为  2^3 = 82^2 = 4 ,而  2^1 = 2

性质 3:对数的幂法则


\log_a(M^n) = n \log_a M​​​​​​​


    •    这意味着幂的对数等于指数乘以底数的对数。

例子:

\log_2(8^3) = 3 \log_2 8 = 3 \times 3 = 9

因为  2^3 = 8,而  2^9 = 512

4. 对数函数在实际中的应用

对数函数在现实中有很多应用,特别是在处理指数增长和复合现象时,例如:

    •    地震强度:地震的强度(里氏震级)是通过对数表示的,每多 1 级表示强度增大 10 倍。
    •    声音的分贝:声音的强度也是对数单位,分贝(dB)就是通过对数计算的。
    •    金融领域中的复利:当利息是复利时,最终的金额增长也可以用对数函数来表示。

总结

    •    对数函数是指数函数的逆运算,它能帮助我们理解指数增长和衰减的关系。
    •    对数有三个重要性质,乘法、除法和幂法则,可以简化对数的计算。
    •    对数函数广泛应用于自然界、金融、地震学等多个领域,帮助我们描述增长、强度等现象。

输出的是(0,1)之间的值。

​​​​​​​

逻辑回归概念 - 概述

逻辑回归(Logistic Regression)是一种用于二分类问题的模型,通常用于预测某个事件的发生概率。虽然名字叫“回归”,但它实际上是一个分类模型。逻辑回归的输出是一个概率值,这个概率值被压缩到 [0, 1] 之间,用来决定样本属于哪个类别。

    •    输入:特征值(也就是样本的特征矩阵)。
    •    输出:事件发生的概率,范围在 (0, 1) 之间。

基本思想

    1.    逻辑回归首先通过线性回归的思想计算一个线性组合的值:

f(x) = w^T x + b

这里,w 是权重向量,x 是特征向量,b 是偏置项。这个结果  f(x)  可以看作一个“打分系统”。

1. 逐项相加形式 f(x) = w_1 x_1 + w_2 x_2 + w_3 x_3 + b

这个公式是显式地将每个特征x_1, x_2, x_3和对应的权重 w_1, w_2, w_3分别相乘,然后加起来,再加上偏置项 b。这是逐项展开的形式,非常直观地展示了每个特征如何对结果进行贡献。

2. 矩阵形式 f(x) = w^T x + b

在机器学习中,输入特征可以用向量(矩阵)来表示,权重也可以用向量表示。

    •     x  是一个特征向量:x = \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix}
    •     w  是一个权重向量: w = \begin{bmatrix} w_1 \\ w_2 \\ w_3 \end{bmatrix}

当我们进行矩阵的点积运算(或称内积)时,实际上就是将向量的每个元素逐项相乘并加和。即:

w^T x = w_1 x_1 + w_2 x_2 + w_3 x_3
其中, w^T 是权重向量的转置,它将  w  从一个列向量变成一个行向量,这样可以和  x (列向量)做矩阵乘法(即点积)。

因此, f(x) = w^T x + b 就是矩阵形式的简写,它和逐项相加的形式完全等价,表示的也是将特征和权重逐项相乘并加和,再加上偏置项  b 。

这两种形式只是写法上的不同,表示的过程是完全一样的。在机器学习的实现中,矩阵形式  w^T x + b 更为通用,因为它可以适用于任意数量的特征,不需要显式写出每个特征的加法。


    2.    将线性组合的结果输入到 Sigmoid 函数中,将其映射到 0 到 1 之间,作为事件发生的概率。Sigmoid函数的公式为:

\sigma(z) = \frac{1}{1 + e^{-z}}

    3.    然后通过设置阈值来判断样本属于哪个类别。例如,如果 Sigmoid 输出的概率大于某个阈值(例如 0.6),则将样本分类为类别 1,否则为类别 0。

逻辑回归的假设函数

逻辑回归的假设函数是将线性回归的输出经过 Sigmoid 函数转换为概率:

h(w) = \sigma(w^T x + b)

本案例讲解(阈值为 0.6)

    •    图中的样本有不同的特征值输入,通过线性计算  W ,然后经过 Sigmoid 函数,得出一个概率值。
    •    比如第一个样本的线性回归结果是 82.4,Sigmoid 函数输出 0.4,预测为类别 B。
    •    当 Sigmoid 输出的概率大于 0.6 时,比如第二个样本的 0.68,则被预测为类别 A。

逻辑回归的损失函数,也就是交叉熵损失函数,来源于极大似然估计。在这里,我将详细讲解逻辑回归损失函数是如何推导出来的。

1. 逻辑回归的目标

在逻辑回归中,我们要预测一个样本属于正类( y = 1)的概率。模型通过以下公式计算概率:


p_i = P(y_i = 1 | x_i) = \frac{1}{1 + e^{-(w^T x_i + b)}}


这个公式来源于 Sigmoid 函数,它将线性模型  w^T x_i + b  映射到一个 [0, 1] 之间的值,表示  x_i属于正类的概率。对应地,样本属于负类( y = 0 )的概率就是  1 - p_i

​​​​​​​

1. 问题背景

假设我们有一个训练数据集\{(x_1, y_1), (x_2, y_2),..., (x_m, y_m)\},其中 y_i是每个样本的标签,取值为 0 或 1(表示分类问题)。我们希望使用逻辑回归模型对这些样本进行分类,模型的输出是每个样本属于某一类别的概率。

逻辑回归的目标是找到参数\theta(包括权重 w 和偏置 b),使得模型生成观测数据的概率最大。为此,我们需要构建似然函数。

2. 逻辑回归输出的概率

对于每个样本 x_i,逻辑回归的模型输出是样本属于正类(y = 1)的概率 p_i


p_i = P(y_i = 1 | x_i) = \frac{1}{1 + e^{-(w^T x_i + b)}}


这是由 sigmoid 函数将线性组合 w^T x_i + b 映射到 [0, 1] 的概率值。与此对应,样本属于负类(y = 0)的概率就是 1 - p_i


1 - p_i = P(y_i = 0 | x_i)


3. 单个样本的似然函数

对每个样本 x_i来说,生成该样本的概率是:

    •    当 y_i = 1 时,生成 y_i = 1的概率是 p_i
    •    当y_i = 0时,生成 y_i = 0 的概率是 1 - p_i

我们可以把这两种情况写成一个统一的公式:


P(y_i | x_i) = p_i^{y_i} \cdot (1 - p_i)^{1 - y_i}​​​​​​​


    •    当y_i = 1时,这个公式变为 p_i;
    •    当 y_i = 0时,这个公式变为 1 - p_i。

这个公式的作用是:无论 y_i 是 0 还是 1,都可以通过这个公式计算对应的概率。
 

3. 整体似然函数

假设训练数据集 \{(x_1, y_1), (x_2, y_2), …, (x_m, y_m)\} 是独立同分布的,我们可以将所有样本的联合概率表示为所有样本条件概率的乘积:


L(\theta; X) = \prod_{i=1}^{m} P(y_i | x_i) = \prod_{i=1}^{m} p_i^{y_i} (1 - p_i)^{1 - y_i}


这个式子称为似然函数。极大似然估计的目标是最大化这个似然函数,从而找到最优的参数  \theta  (包括  w  和  b )。

4. 构建对数似然函数

由于乘积形式的似然函数在数学处理上不方便,特别是在求导的过程中,所以我们通常对似然函数取对数,构建对数似然函数:


\ell(\theta) = \log L(\theta; X) = \sum_{i=1}^{m} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]


对数似然函数通过将乘法转换为加法,方便后续的求导和优化。

5. 最大化对数似然函数

我们的目标是通过最大化对数似然函数来找到最优的参数  \theta 。这就转化为最小化负对数似然函数:


-\ell(\theta) = -\sum_{i=1}^{m} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]


这个公式就是逻辑回归的损失函数,也称为交叉熵损失函数。

6. 损失函数的解释

损失函数的每一项都对应一个样本的损失:

    •    当  y_i = 1  时,损失函数希望  p_i  越大越好,因为 \log(p_i) 越大,负号前的值越小;
    •    当  y_i = 0  时,损失函数希望  p_i  越小越好,因为 \log(1 - p_i) 越大,负号前的值越小。

因此,损失函数的设计本质上是为了惩罚那些错误的预测,同时鼓励模型的输出接近真实标签。

7. 总结

    •    逻辑回归的损失函数是通过极大似然估计推导出来的,它是负对数似然函数。
    •    通过最大化对数似然函数,我们希望找到最优的模型参数。
    •    损失函数的设计是为了鼓励模型预测出正确的概率,并对错误的预测进行惩罚。

​​​​​​​

损失函数

在逻辑回归中,损失函数(Loss Function)用于衡量模型的预测值与真实值之间的差距。常用的损失函数是对数损失函数,其公式为:

\text{Loss}(L) = - \sum_{i=1}^{m} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]


其中, p_i  是通过 Sigmoid 函数计算得到的概率, y_i  是真实标签。损失函数的作用是鼓励模型输出的概率值接近真实的类别。

损失函数的计算例子

PPT 中的例子展示了如何计算每个样本的损失。具体来说:

    •    第一个样本的真实值为 1,逻辑回归输出为 0.4,所以对应的损失为:

1 \log(0.4) + (1-1)\log(1-0.4) = \log(0.4)

    •    第二个样本的真实值为 0,逻辑回归输出为 0.68,所以对应的损失为:

0 \log(0.68) + (1-0)\log(1-0.68) = \log(0.32)


每个样本的损失最终累加,作为总的损失值。

补充讲解:

    •    关于阈值:阈值的选择可以根据实际应用场景来调整。常用的阈值是 0.5,如果希望更加严格的分类,可以提高阈值,比如 0.6 或 0.7。
    •    损失函数的作用:对数损失函数(Log Loss)能够很好地处理分类问题,尤其是在不平衡数据集中,它能够通过概率值对每个样本进行精确的判断。

总结来说,逻辑回归通过线性回归计算一个“分数”,再通过 Sigmoid 函数将这个分数转换为概率,最终通过设定阈值判断分类。同时,使用对数损失函数来衡量模型的性能,确保预测的概率尽可能接近真实分类结果。

# 导入所需库
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report

# 1. 在线读取数据
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data'
# 数据没有表头,因此需要手动指定列名
column_names = ['ID', 'Diagnosis', 'Feature1', 'Feature2', 'Feature3', 'Feature4', 'Feature5', 
                'Feature6', 'Feature7', 'Feature8', 'Feature9', 'Feature10', 'Feature11', 
                'Feature12', 'Feature13', 'Feature14', 'Feature15', 'Feature16', 'Feature17', 
                'Feature18', 'Feature19', 'Feature20', 'Feature21', 'Feature22', 'Feature23', 
                'Feature24', 'Feature25', 'Feature26', 'Feature27', 'Feature28', 'Feature29', 
                'Feature30']

# 读取数据并指定列名
data = pd.read_csv(url, header=None, names=column_names)

# 2. 数据预处理
# 删除ID列,因为ID不作为特征
data.drop('ID', axis=1, inplace=True)

# 替换数据中的缺失值 '?' 为 NaN,并删除含有 NaN 的行
data = data.replace(to_replace='?', value=np.NaN)
data = data.dropna()

# 将目标变量 Diagnosis (诊断) 转换为二进制 (0, 1),方便分类
data['Diagnosis'] = data['Diagnosis'].map({'M': 1, 'B': 0})

# 3. 分割特征和目标变量
# X 为特征值,去掉目标列 Diagnosis
X = data.iloc[:, 1:]  # 从第1列开始作为特征
# y 为目标值,即 Diagnosis 列
y = data['Diagnosis']

# 4. 数据集划分为训练集和测试集
# 使用 train_test_split 函数按 75% 训练集,25% 测试集划分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=22)

# 5. 特征工程 - 数据标准化
# 初始化标准化器 StandardScaler
scaler = StandardScaler()
# 对训练数据进行标准化
X_train_scaled = scaler.fit_transform(X_train)
# 对测试数据进行相同的标准化
X_test_scaled = scaler.transform(X_test)

# 6. 创建和训练逻辑回归模型
# 初始化逻辑回归模型
logistic_model = LogisticRegression(max_iter=10000)
# 使用训练数据拟合模型
logistic_model.fit(X_train_scaled, y_train)

# 7. 模型预测和评估
# 使用训练好的模型对测试数据进行预测
y_pred = logistic_model.predict(X_test_scaled)

# 8. 打印预测结果
print("预测结果:", y_pred)

# 9. 模型评估
# 计算并打印模型的准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {accuracy:.4f}")

# 生成分类报告,显示精确度、召回率、F1分数等评估指标
report = classification_report(y_test, y_pred, target_names=['Benign', 'Malignant'])
print("分类报告:\n", report)

代码详细注释:

1. 导入库:导入 pandas、numpy、sklearn 中的逻辑回归、数据集划分、标准化以及评估相关的库。

2. 在线读取数据:数据通过 URL 从 UCI 机器学习仓库下载,并手动添加列名。ID 列被删除,因为它并不作为特征使用。

3. 数据预处理

• 将 ? 替换为 NaN 并删除包含 NaN 的行。

• 将诊断列 Diagnosis(表示良性或恶性肿瘤)转换为 0 和 1 的二元分类(0 表示良性,1 表示恶性)。

4. 特征值和目标值的分离

• X 是特征值矩阵,y 是目标值向量。

5. 划分数据集:通过 train_test_split 函数,将数据划分为 75% 的训练集和 25% 的测试集。

6. 数据标准化

• 使用 StandardScaler 进行标准化,使得每个特征的均值为 0,方差为 1。训练集和测试集都需要标准化。

7. 模型训练

• 使用逻辑回归模型 LogisticRegression 进行模型拟合,max_iter=10000 是为了确保迭代次数足够大,模型能够收敛。

8. 模型预测

• 使用训练好的模型对测试集进行预测,得到预测结果 y_pred。

9. 模型评估

• 使用 accuracy_score 函数计算模型的准确率。

• 使用 classification_report 函数生成详细的分类报告,包括精确度(precision)、召回率(recall)、F1 分数等。

可见我们的模型A / 模型B 都是 70% 准确率

from sklearn.metrics import confusion_matrix,accuracy_score
import pandas as pd

# 真实值
y_true = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '良性','良性','良性','良性']

# 预测值
y_predict_A = ['恶性', '恶性', '恶性', '良性', '良性', '良性', '良性','良性','良性','良性']
y_predict_B = ['恶性', '恶性', '恶性', '恶性', '恶性', '恶性', '恶性','恶性','恶性','良性']

# 构建混淆矩阵
m_A = confusion_matrix(y_true, y_predict_A,labels=['恶性','良性'])
m_B = confusion_matrix(y_true, y_predict_B,labels=['恶性','良性'])

dataframe_labels = ['恶性(正例)','良性(反例)']
print(pd.DataFrame(m_A,index=dataframe_labels,columns=dataframe_labels))
print(pd.DataFrame(m_B,index=dataframe_labels,columns=dataframe_labels))

result = recall_score(y_true, y_pred2, pos_label="恶性")

​​​​​​​

评分系统可以使用这个函数,绿色是我们关心的


​​​​​​​

当然,以下是代码的详细注释、变量和方法名称的优化,使得代码更加清晰易读。

### 优化后的代码与详细注释:

```python
# 导入必要的库
from sklearn.metrics import accuracy_score, roc_auc_score, classification_report
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 读取客户流失数据集
# 通过 pandas 读取 churn.csv 数据,并加载到 DataFrame 中
data = pd.read_csv('./data/churn.csv')

# 显示数据集的基本信息,包括每列的名称、数据类型、非空值数量等
data.info()

# 2. 数据预处理
# 2.1 将类别型数据转换为独热编码(One-Hot Encoding)
# get_dummies 将所有类别型数据列转化为多个二进制列(例如,'Churn' 列被转换为 'Churn_Yes' 和 'Churn_No')
data = pd.get_dummies(data, dtype=np.uint8)

# 2.2 删除冗余列
# 删除 'Churn_No' 和 'gender_Male' 列,因为它们与 'Churn_Yes' 和 'gender_Female' 相互冗余
data.drop(['Churn_No', 'gender_Male'], axis=1, inplace=True)

# 2.3 重命名列名
# 为了方便理解,将 'Churn_Yes' 重命名为 'label',表示是否流失;将 'gender_Female' 重命名为 'gender'
data.rename(columns={'Churn_Yes': 'label', 'gender_Female': 'gender'}, inplace=True)

# 3. 样本分布检查
# 打印标签 'label' 的分布,查看流失(1)与未流失(0)的样本比例,确保数据是否平衡
print("标签分布:")
print(data['label'].value_counts(normalize=True))

# 4. 特征选择与数据集拆分
# 4.1 选择模型训练所需的特征
# 选择与客户流失相关的三列特征:'Contract_Month'(合同月份)、'internet_other'(互联网服务)和 'PaymentElectronic'(电子支付)
features = data[['Contract_Month', 'internet_other', 'PaymentElectronic']]

# 标签列 'label' 表示客户是否流失(1 表示流失,0 表示未流失)
labels = data['label']

# 4.2 数据集拆分
# 使用 train_test_split 按 80/20 比例将数据集拆分为训练集(80%)和测试集(20%)
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)

# 5. 逻辑回归模型训练与预测
# 5.1 初始化逻辑回归模型
# 设置 class_weight='balanced' 以应对数据集中类别不平衡问题(平衡类别权重)
logistic_regression_model = LogisticRegression(class_weight='balanced')

# 5.2 在训练集上训练逻辑回归模型
logistic_regression_model.fit(X_train, y_train)

# 5.3 在测试集上进行预测
# 使用 predict() 方法根据模型对测试集进行预测,返回的是预测的二分类结果(0 或 1)
y_pred = logistic_regression_model.predict(X_test)

# 6. 模型评估
# 6.1 计算并打印模型的准确率
# 使用 accuracy_score() 计算模型在测试集上的准确率(即预测正确的比例)
print("模型准确率:")
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")

# 6.2 计算并打印 ROC-AUC 分数
# ROC-AUC 分数衡量模型在区分正类(流失)和负类(未流失)时的表现,分数越高越好
roc_auc = roc_auc_score(y_test, y_pred)
print(f"ROC AUC 分数: {roc_auc:.4f}")

# 6.3 输出详细的分类报告
# classification_report() 生成模型的分类报告,包括精确率(Precision)、召回率(Recall)和 F1 分数(F1-score)
# target_names 参数用来指定类别的名称,'0' 对应未流失,'1' 对应流失
print("分类报告:")
print(classification_report(y_test, y_pred, target_names=['未流失', '流失']))
```

为什么代码中没有明确体现阈值的设置?

• 默认情况下,LR.predict() 会根据 0.5 的阈值进行预测,因此在代码中没有明确设置阈值是因为你使用了 predict(),它隐含了这个默认的 0.5 阈值。

• 如果你想要使用不同的阈值,比如 0.6 或 0.4,你需要先获取预测的概率,然后根据阈值进行分类。

如何设置自定义阈值?

1. 使用 predict_proba() 获取预测概率。

2. 根据自定义的阈值,将预测概率转换为二分类结果。

修改代码来手动设置阈值

以下是如何手动设置不同阈值的示例,使用 predict_proba() 获取模型对每个样本属于正类(即 1)的概率,然后根据阈值进行分类。

from sklearn.metrics import accuracy_score, roc_auc_score
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

import matplotlib.pyplot as plt
import seaborn as sns

# 假设 churn_data 数据已经加载并进行了处理
# 特征选择
x = churn_data[['Contract_Month','internet_other','PaymentElectronic']]
y = churn_data['label']

# 分割训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# 实例化模型并训练
LR = LogisticRegression(class_weight='balanced')
LR.fit(x_train, y_train)

# 使用 predict_proba() 获取每个样本属于类 1 的概率
y_proba = LR.predict_proba(x_test)[:, 1]  # 只取第二列,即预测为 1 的概率

# 设置一个自定义阈值,比如 0.4
threshold = 0.4
y_pred_custom = (y_proba >= threshold).astype(int)  # 如果概率大于等于 0.4 则预测为 1,否则为 0

# 模型评估
print("自定义阈值下的分类报告 (阈值 = 0.4):")
print(classification_report(y_test, y_pred_custom, target_names=['0', '1']))

# 计算准确率和 ROC-AUC 分数
my_accuracy_score = accuracy_score(y_test, y_pred_custom)
roc_auc = roc_auc_score(y_test, y_proba)

print("Accuracy:", my_accuracy_score)
print("ROC AUC Score:", roc_auc)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值