机器学习基础例子篇
经典机器学习知识总结(列子篇)
- 1 线性回归
- 2 逻辑回归
- 2.1 介绍
- 2.2 计算例子
- 2.3 程序实现
- 3 决策树
- 3.1 介绍
- 3.2. 需要的背景知识
- 2.1 熵(Entropy)
- 2.2 信息增益(Information Gain)
- 2.3 增益比率(Gain Ratio)
- 3.3 计算例子
- 3.4 程序例子
- 4 朴素贝叶斯
- 4.1 概述
- 4.2 数学基础
- 4.3 例子
- 4.4 代码实现
- 5 关联规则
- 5.1 概述
- 5.2具体例子
- 5.3代码实现
- 6 聚类
- 6.1 概述
- 6.2 数学基础
- 6.3 具体例子
- 6.4 代码实现
1 线性回归
线性回归是一种简单但非常重要的机器学习算法,用于预测一个变量(目标值)与另一个或多个变量(特征)之间的关系。它的核心思想是用一条直线来拟合数据点,找到特征和目标值之间的最佳线性关系。
数学上,线性回归的模型公式为:
y
=
w
1
x
1
+
w
2
x
2
+
…
+
w
n
x
n
+
b
y = w_1x_1 + w_2x_2 + \ldots + w_nx_n + b
y=w1x1+w2x2+…+wnxn+b
其中,
y
y
y是预测值,
x
i
x_i
xi是特征值,
w
i
w_i
wi是权重(回归系数),
b
b
b 是偏置(截距)。
线性回归的目标是通过最小化预测值和实际值之间的误差(通常使用均方误差,MSE)来找到最佳的
w
w
w 和
b
b
b。
2 逻辑回归
2.1 介绍
逻辑回归是一种用于分类问题的机器学习算法,尽管名字里有“回归”,它的主要目标是解决二分类问题(例如,预测邮件是否为垃圾邮件)。
它的核心思想是利用线性回归的输出值,通过一个S型函数(Sigmoid函数),将结果映射到0到1之间,作为属于某一类别的概率。
Sigmoid函数公式为:
σ
(
z
)
=
1
1
+
e
−
z
\sigma(z) = \frac{1}{1 + e^{-z}}
σ(z)=1+e−z1
其中,
z
z
z 是输入特征和权重的线性组合。
逻辑回归的优点在于简单高效,尤其适合线性可分数据,且结果容易解释(通过权重判断特征的重要性)。但对于复杂的非线性关系,它的表现可能不足.
2.2 计算例子
下面通过一个简单的例子,帮助理解逻辑回归的工作流程。
假设我们有一个数据集,用于预测某人是否会购买产品(1=购买,0=不购买)。数据集包含两个特征:
- 年龄(Age)
- 月收入(Income)
Age | Income | Purchased (Label) |
---|---|---|
25 | 3000 | 0 |
35 | 4000 | 0 |
45 | 5000 | 1 |
50 | 7000 | 1 |
首先构建逻辑回归模型,假设我们将特征
X
=
[
A
g
e
,
I
n
c
o
m
e
]
X=[Age,Income]
X=[Age,Income]与模型的权重
W
=
[
w
1
,
w
2
]
W=[w_1,w_2]
W=[w1,w2] 做线性组合:
z
=
w
0
+
w
1
⋅
Age
+
w
2
⋅
Income
z = w_0 + w_1 \cdot \text{Age} + w_2 \cdot \text{Income}
z=w0+w1⋅Age+w2⋅Income
其中,
w
0
w_0
w0是偏置项,初始权重可以随机设定。假设初始值为:
w
0
=
−
8
,
w
1
=
0.1
,
w
2
=
0.001
w_0 = -8, \quad w_1 = 0.1, \quad w_2 = 0.001
w0=−8,w1=0.1,w2=0.001
接下来:计算预测值(概率)将
z
z
z 输入 Sigmoid 函数,计算概率:
σ
(
z
)
=
1
1
+
e
−
z
\sigma(z) = \frac{1}{1 + e^{-z}}
σ(z)=1+e−z1
以第一个样本为例:
z
=
−
8
+
0.1
⋅
25
+
0.001
⋅
3000
=
−
8
+
2.5
+
3
=
−
2.5
z = -8 + 0.1 \cdot 25 + 0.001 \cdot 3000 = -8 + 2.5 + 3 = -2.5
z=−8+0.1⋅25+0.001⋅3000=−8+2.5+3=−2.5
σ ( z ) = 1 1 + e 2.5 ≈ 0.075 \sigma(z) = \frac{1}{1 + e^{2.5}} \approx 0.075 σ(z)=1+e2.51≈0.075
类似地,计算其他样本的预测概率:
Age | Income | Purchased | z z z | s i g m a ( z ) sigma(z) sigma(z) |
---|---|---|---|---|
25 | 3000 | 0 | -2.5 | 0.075 |
35 | 4000 | 0 | -1.4 | 0.198 |
45 | 5000 | 1 | -0.3 | 0.426 |
50 | 7000 | 1 | 1.0 | 0.731 |
最后设定分类规则,逻辑回归一般将概率阈值设为 0.5:
•
σ
(
z
)
\sigma(z)
σ(z)>=0.5,预测为“1”(购买)。
•
σ
(
z
)
\sigma(z)
σ(z)<0.5, 预测为“0”(不购买)。
根据结果,样本 1 和 2 ,3被预测为“未购买”,样本4 被预测为“已购买”。
如果模型的预测与真实标签一致,说明权重设置初步合理。但为了提高精度,实际中会通过梯度下降法优化权重,最小化损失函数(如交叉熵损失)。最终,逻辑回归通过概率输出,使分类更加灵活,并且可以解释特征的重要性。
2.3 程序实现
import numpy as np
# 数据集
data = np.array([
[25, 3000, 0], # [Age, Income, Purchased]
[35, 4000, 0],
[45, 5000, 1],
[50, 7000, 1]
])
# 提取特征和标签
X = data[:, :-1] # Age and Income
y = data[:, -1] # Purchased (label)
# 初始权重和偏置
w = np.array([0.1, 0.001]) # w1 for Age, w2 for Income
b = -8 # 偏置项
# Sigmoid 函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 计算 z 和预测概率
def predict(X, w, b):
z = np.dot(X, w) + b # z = w1*Age + w2*Income + b
probs = sigmoid(z) # 转为概率
return probs
# 分类规则
def classify(probs, threshold=0.5):
return (probs >= threshold).astype(int)
# 计算预测概率
probs = predict(X, w, b)
predictions = classify(probs)
# 打印结果
print("Feature Matrix (X):")
print(X)
print("\nTrue Labels (y):")
print(y)
print("\nPredicted Probabilities (probs):")
print(probs)
print("\nPredicted Labels (predictions):")
print(predictions)
3 决策树
3.1 介绍
决策树分类是一种基于树结构的机器学习算法,常用于分类问题。它的工作原理类似于一个二十问游戏,通过一系列的“是”或“否”问题,将数据逐步分割成更小的子集,直到这些子集足够纯净,能明确属于某一类别。
树的节点表示特征,分支代表决策规则,叶子节点则是最终的分类结果。例如,要预测一个西瓜是否是好瓜,决策树可能先问“西瓜纹理怎么样”,再进一步问“西瓜的耕地是蜷缩,稍卷还是硬挺的”,通过这些条件一步步确定分类。
决策树的优点是直观、易于解释,对数据的预处理需求较低;但它容易过拟合,尤其是树过深时。因此,常用剪枝技术或集成算法(如随机森林)来提升泛化能力。
3.2. 需要的背景知识
2.1 熵(Entropy)
熵是用来衡量数据不确定性的一种指标。假设某数据集
D
D
D 有
k
k
k 个类别,其熵公式为:
H
(
D
)
=
−
∑
i
=
1
k
p
i
log
2
p
i
H(D) = -\sum_{i=1}^{k} p_i \log_2 p_i
H(D)=−i=1∑kpilog2pi
其中,
p
i
p_i
pi 是类别
i
i
i 的比例。熵越高,数据的不确定性越大。例如,硬币两面概率均为 0.5 时,熵最大;若一面概率为 1,则熵为 0。
2.2 信息增益(Information Gain)
信息增益表示通过某特征分裂数据后,不确定性减少的程度。其公式为:
信息增益
=
H
(
D
)
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
H
(
D
v
)
\text{信息增益} = H(D) - \sum_{v=1}^{V} \frac{|D_v|}{|D|} H(D_v)
信息增益=H(D)−v=1∑V∣D∣∣Dv∣H(Dv)
其中,
D
v
D_v
Dv 是按照某特征取值
v
v
v 划分出的子集,
∣
D
v
∣
|D_v|
∣Dv∣是子集大小。信息增益大的特征更有助于分类。
2.3 增益比率(Gain Ratio)
为了避免信息增益偏向于取值多的特征(例如身份证号),引入增益比率,公式为:
增益比率
=
信息增益
固有值
\text{增益比率} = \frac{\text{信息增益}}{\text{固有值}}
增益比率=固有值信息增益
固有值(Intrinsic Value, IV)计算方式类似熵:
IV
=
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
log
2
∣
D
v
∣
∣
D
∣
\text{IV} = -\sum_{v=1}^{V} \frac{|D_v|}{|D|} \log_2 \frac{|D_v|}{|D|}
IV=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
增益比率通过标准化,避免了信息增益的偏向性。
总结来说 熵就是衡量数据混乱度。信息增益则代表了分类效果的提升。增益比率:对信息增益进行校正,避免偏差。
3.3 计算例子
问题描述
我们有一个小型数据集,目标是根据天气条件预测是否适合去郊游。
天气 (Weather) | 温度 (Temperature) | 湿度 (Humidity) | 是否适合郊游 (Go Out) |
---|---|---|---|
晴天 (Sunny) | 高 (High) | 高 (High) | 否 (No) |
晴天 (Sunny) | 高 (High) | 正常 (Normal) | 是 (Yes) |
阴天 (Overcast) | 高 (High) | 高 (High) | 是 (Yes) |
雨天 (Rainy) | 温 (Mild) | 高 (High) | 是 (Yes) |
雨天 (Rainy) | 低 (Low) | 正常 (Normal) | 是 (Yes) |
雨天 (Rainy) | 低 (Low) | 高 (High) | 否 (No) |
我们目标是构建一棵决策树,根据特征(天气、温度、湿度)预测是否适合郊游。
步骤一:计算数据集熵
熵
H
(
D
)
H(D)
H(D)衡量数据的混乱程度。目标变量
G
o
O
u
t
Go Out
GoOut 的熵公式为:
H
(
D
)
=
−
∑
i
=
1
k
p
i
log
2
p
i
H(D) =-\sum_{i=1}^{k}{p_i\log{_2p_i}}
H(D)=−i=1∑kpilog2pi
在数据集中,有 4条记录为“是”,2条记录为“否”:
H
(
D
)
=
−
(
4
6
log
2
4
6
+
2
6
log
2
2
6
)
≈
0.918
H(D) = -\left(\frac{4}{6} \log_2 \frac{4}{6} + \frac{2}{6} \log_2 \frac{2}{6}\right) \approx 0.918
H(D)=−(64log264+62log262)≈0.918
步骤二:按特征计算信息增益
信息增益公式为:
信息增益
=
H
(
D
)
−
∑
v
=
1
V
∣
D
v
∣
∣
D
∣
H
(
D
v
)
\text{信息增益} = H(D) - \sum_{v=1}^{V} \frac{|D_v|}{|D|} H(D_v)
信息增益=H(D)−v=1∑V∣D∣∣Dv∣H(Dv)
-
按“天气”分裂
将数据集按天气分成 3 组:• 晴天 (Sunny): 2 条记录,1 否,1 是,熵 H = 1.0 H = 1.0 H=1.0
• 阴天 (Overcast): 1 条记录,全部是,熵 H = 0.0 H = 0.0 H=0.0
• 雨天 (Rainy): 3 条记录,1 否,2 是,熵 H = 0.918 H = 0.918 H=0.918
计算分裂后的熵:
H 天气 = 2 6 ⋅ 1.0 + 1 6 ⋅ 0.0 + 3 6 ⋅ 0.918 ≈ 0.699 H_{\text{天气}} = \frac{2}{6} \cdot 1.0 + \frac{1}{6} \cdot 0.0 + \frac{3}{6} \cdot 0.918 \approx 0.699 H天气=62⋅1.0+61⋅0.0+63⋅0.918≈0.699信息增益:
信息增益 天气 = 0.918 − 0.699 ≈ 0.219 \text{信息增益}_{\text{天气}} = 0.918 - 0.699 \approx 0.219 信息增益天气=0.918−0.699≈0.219 -
按其他特征分裂
类似计算,可得:
• 信息增益 温度 = 0.918 − 0.838 = 0.080 \text{信息增益}_{\text{温度}} = 0.918 - 0.838 = 0.080 信息增益温度=0.918−0.838=0.080
• 信息增益 湿度 = 0.918 − 0.550 = 0.368 \text{信息增益}_{\text{湿度}} = 0.918 - 0.550 = 0.368 信息增益湿度=0.918−0.550=0.368
步骤三:选择最优分裂特征
信息增益最大的特征为“湿度”,因此第一个分裂点为“湿度”。
• 如果湿度为高:
H
=
0.0
H = 0.0
H=0.0((已完全分类)。
• 如果湿度为正常:包含记录为全是“是”,不再需要分裂。
构建决策树
根据以上分析,生成的决策树如下:
湿度
/ \
高 正常
否 是
根据构建的决策树:
• 如果湿度为“高”,预测为“不适合郊游(No)”。
• 如果湿度为“正常”,预测为“适合郊游(Yes)”。
该决策树简洁清晰,对训练数据准确率达到 100 % 100\% 100%。如果遇到更多数据,树可以进一步扩展和优化,例如剪枝处理避免过拟合。
3.4 程序例子
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.preprocessing import LabelEncoder
import numpy as np
# 数据集定义
data = [
['Sunny', 'High', 'High', 'No'], # 样本 1
['Sunny', 'High', 'Normal', 'Yes'], # 样本 2
['Overcast', 'High', 'High', 'Yes'], # 样本 3
['Rainy', 'Mild', 'High', 'Yes'], # 样本 4
['Rainy', 'Low', 'Normal', 'Yes'], # 样本 5
['Rainy', 'Low', 'High', 'No'], # 样本 6
]
# 特征和标签提取
X = [row[:-1] for row in data] # 提取特征 ['Weather', 'Temperature', 'Humidity']
y = [row[-1] for row in data] # 提取标签 ['Go Out']
# 将分类变量转换为数值
encoders = []
X_encoded = []
for col in np.array(X).T:
le = LabelEncoder()
X_encoded.append(le.fit_transform(col))
encoders.append(le)
X_encoded = np.array(X_encoded).T
label_encoder = LabelEncoder()
y_encoded = label_encoder.fit_transform(y)
# 创建并训练决策树模型
model = DecisionTreeClassifier(criterion='entropy', random_state=42)
model.fit(X_encoded, y_encoded)
# 打印决策树结构
tree_rules = export_text(model, feature_names=['Weather', 'Temperature', 'Humidity'])
print("Decision Tree Rules:\n")
print(tree_rules)
# 测试数据
test_data = [['Sunny', 'High', 'High'], # 应预测为 'No'
['Rainy', 'Low', 'Normal']] # 应预测为 'Yes'
# 测试数据编码
test_encoded = []
for i, col in enumerate(np.array(test_data).T):
test_encoded.append(encoders[i].transform(col))
test_encoded = np.array(test_encoded).T
# 预测结果
predictions = model.predict(test_encoded)
decoded_predictions = label_encoder.inverse_transform(predictions)
print("\nPredictions for Test Data:")
for i, test in enumerate(test_data):
print(f"Input: {test}, Prediction: {decoded_predictions[i]}")
4 朴素贝叶斯
4.1 概述
朴素贝叶斯是一种基于概率的机器学习算法,常用于分类任务,如垃圾邮件识别和情感分析。它的核心是贝叶斯定理,通过计算每个类别的概率,选择概率最大的类别作为预测结果。
“朴素”的意思是假设所有特征之间是独立的(尽管在现实中这种假设不总是成立)。算法会根据每个特征对某类别的贡献来综合判断。例如,要判断一封邮件是否是垃圾邮件,算法会分析关键词(如“免费”、“中奖”)的出现概率,并结合这些概率进行分类。
朴素贝叶斯的优点是速度快、效果好,尤其适合处理高维数据(如文本数据)。然而,当特征之间相关性较强时,其表现可能会受到影响。
4.2 数学基础
- 贝叶斯定理
贝叶斯定理是朴素贝叶斯算法的核心,用于计算后验概率。公式如下:
P ( y ∣ X ) = P ( X ∣ y ) ⋅ P ( y ) P ( X ) P(y|X) = \frac{P(X|y) \cdot P(y)}{P(X)} P(y∣X)=P(X)P(X∣y)⋅P(y)
•
P
(
y
∣
X
)
P(y|X)
P(y∣X):给定特征
X
X
X的情况下,属于类别
y
y
y的概率(后验概率)。
•
P
(
X
∣
y
)
P(X|y)
P(X∣y):类别 y下特征 X出现的概率(似然)。
•
P
(
y
)
P(y)
P(y) :类别 y的先验概率,即该类别出现的频率。
•
P
(
X
)
P(X)
P(X):特征
X
X
X出现的概率(归一化常量,可忽略)。
朴素贝叶斯只关注使 P ( y ∣ X ) P(y|X) P(y∣X)最大的类别,因此 P ( X ) P(X) P(X)可以不计算。
- 朴素假设
“朴素”的意思是假设特征之间是独立的。在实际中,特征可能相关,但这种假设简化了计算:
P ( X ∣ y ) = P ( x 1 ∣ y ) ⋅ P ( x 2 ∣ y ) ⋅ … ⋅ P ( x n ∣ y ) P(X|y) = P(x_1|y) \cdot P(x_2|y) \cdot \ldots \cdot P(x_n|y) P(X∣y)=P(x1∣y)⋅P(x2∣y)⋅…⋅P(xn∣y)
其中 x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,…,xn 是特征值。通过独立性假设,我们能用每个特征的条件概率计算总体概率,减少了复杂度。 - 分类决策
目标是找到使 P ( y ∣ X ) P(y|X) P(y∣X)最大的类别 y y y。去掉 P ( X ) P(X) P(X)后,分类决策公式为:
y ^ = arg max y P ( X ∣ y ) ⋅ P ( y ) \hat{y} = \arg\max_y P(X|y) \cdot P(y) y^=argmaxyP(X∣y)⋅P(y)
这意味着:
• P ( X ∣ y ) P(X|y) P(X∣y):根据类别 y y y计算特征的条件概率。
• P ( y ) P(y) P(y):类别的先验概率(可以从训练数据中统计得到)。
4.3 例子
问题描述
我们有一个简单数据集,目标是预测天气条件下是否适合打球。
天气 (Weather) | 温度 (Temperature) | 湿度 (Humidity) | 打球 (Play) |
---|---|---|---|
晴天 (Sunny) | 高 (High) | 高 (High) | 否 (No) |
晴天 (Sunny) | 高 (High) | 正常 (Normal) | 否 (No) |
阴天 (Overcast) | 高 (High) | 高 (High) | 是 (Yes) |
雨天 (Rainy) | 温 (Mild) | 高 (High) | 是 (Yes) |
雨天 (Rainy) | 低 (Low) | 正常 (Normal) | 是 (Yes) |
雨天 (Rainy) | 低 (Low) | 高 (High) | 否(No) |
目标:用朴素贝叶斯算法预测新样本
[Weather=Sunny, Temperature=High, Humidity=High]
\text{[Weather=Sunny, Temperature=High, Humidity=High]}
[Weather=Sunny, Temperature=High, Humidity=High] 是否适合打球。
统计频率
先计算各类别
Play=Yes
\text{Play=Yes}
Play=Yes 和
Play=No
\text{Play=No}
Play=No 的先验概率:
P ( Yes ) = Yes 的样本数 总样本数 = 3 6 = 0.5 P(\text{Yes}) = \frac{\text{Yes 的样本数}}{\text{总样本数}} = \frac{3}{6} = 0.5 P(Yes)=总样本数Yes 的样本数=63=0.5
P
(
No
)
=
No 的样本数
总样本数
=
3
6
=
0.5
P(\text{No}) = \frac{\text{No 的样本数}}{\text{总样本数}} = \frac{3}{6} = 0.5
P(No)=总样本数No 的样本数=63=0.5
计算条件概率
针对每个类别,计算特征的条件概率。这里使用拉普拉斯平滑(平滑值为 1),以避免概率为 0。
- 条件概率 P ( Sunny|Yes ) P(\text{Sunny|Yes}) P(Sunny|Yes)和 P ( Sunny|No ) P(\text{Sunny|No}) P(Sunny|No):
P ( Sunny|Yes ) = Yes 中 Weather=Sunny 的次数 + 1 Yes 的样本数 + Weather 取值数 = 0 + 1 3 + 3 = 1 6 P(\text{Sunny|Yes}) = \frac{\text{Yes 中 Weather=Sunny 的次数 + 1}}{\text{Yes 的样本数 + Weather 取值数}} = \frac{0 + 1}{3 + 3} = \frac{1}{6} P(Sunny|Yes)=Yes 的样本数 + Weather 取值数Yes 中 Weather=Sunny 的次数 + 1=3+30+1=61
P
(
Sunny|No
)
=
No 中 Weather=Sunny 的次数 + 1
No 的样本数 + Weather 取值数
=
2
+
1
3
+
3
=
3
6
=
0.5
P(\text{Sunny|No}) = \frac{\text{No 中 Weather=Sunny 的次数 + 1}}{\text{No 的样本数 + Weather 取值数}} = \frac{2 + 1}{3 + 3} = \frac{3}{6} = 0.5
P(Sunny|No)=No 的样本数 + Weather 取值数No 中 Weather=Sunny 的次数 + 1=3+32+1=63=0.5
2.条件概率
P
(
High|Yes
)
P(\text{High|Yes})
P(High|Yes)和
P
(
High|No
)
P(\text{High|No})
P(High|No):
P
(
High|Yes
)
=
Yes 中 Temperature=High 的次数 + 1
Yes 的样本数 + Temperature 取值数
=
1
+
1
3
+
3
=
2
6
=
0.333
P(\text{High|Yes}) = \frac{\text{Yes 中 Temperature=High 的次数 + 1}}{\text{Yes 的样本数 + Temperature 取值数}} = \frac{1 + 1}{3 + 3} = \frac{2}{6} = 0.333
P(High|Yes)=Yes 的样本数 + Temperature 取值数Yes 中 Temperature=High 的次数 + 1=3+31+1=62=0.333
P
(
High|No
)
=
No 中 Temperature=High 的次数 + 1
No 的样本数 + Temperature 取值数
=
2
+
1
3
+
3
=
0.5
P(\text{High|No}) = \frac{\text{No 中 Temperature=High 的次数 + 1}}{\text{No 的样本数 + Temperature 取值数}} = \frac{2 + 1}{3 + 3} = 0.5
P(High|No)=No 的样本数 + Temperature 取值数No 中 Temperature=High 的次数 + 1=3+32+1=0.5
3. 条件概率
P
(
Humidity=High
∣
Yes
)
P(\text{Humidity=High}|\text{Yes})
P(Humidity=High∣Yes)和
P
(
Humidity=High
∣
No
)
P(\text{Humidity=High}|\text{No})
P(Humidity=High∣No) :
P
(
High|Yes
)
=
Yes 中 Humidity=High 的次数 + 1
Yes 的样本数 + Humidity 取值数
=
2
+
1
3
+
2
=
3
5
=
0.6
P(\text{High|Yes}) = \frac{\text{Yes 中 Humidity=High 的次数 + 1}}{\text{Yes 的样本数 + Humidity 取值数}} = \frac{2 + 1}{3 + 2} = \frac{3}{5} = 0.6
P(High|Yes)=Yes 的样本数 + Humidity 取值数Yes 中 Humidity=High 的次数 + 1=3+22+1=53=0.6
P
(
High|No
)
=
No 中 Humidity=High 的次数 + 1
No 的样本数 + Humidity 取值数
=
2
+
1
3
+
2
=
0.6
P(\text{High|No}) = \frac{\text{No 中 Humidity=High 的次数 + 1}}{\text{No 的样本数 + Humidity 取值数}} = \frac{2 + 1}{3 + 2} = 0.6
P(High|No)=No 的样本数 + Humidity 取值数No 中 Humidity=High 的次数 + 1=3+22+1=0.6
计算后验概率
根据贝叶斯定理,计算
P
(
Yes|X
)
P(\text{Yes|X})
P(Yes|X)和
P
(
No|X
)
P(\text{No|X})
P(No|X):
P
(
Yes|X
)
∝
P
(
Yes
)
⋅
P
(
Sunny|Yes
)
⋅
P
(
High|Yes
)
⋅
P
(
High|Yes
)
P(\text{Yes|X}) \propto P(\text{Yes}) \cdot P(\text{Sunny|Yes}) \cdot P(\text{High|Yes}) \cdot P(\text{High|Yes})
P(Yes|X)∝P(Yes)⋅P(Sunny|Yes)⋅P(High|Yes)⋅P(High|Yes)
P
(
No|X
)
∝
P
(
No
)
⋅
P
(
Sunny|No
)
⋅
P
(
High|No
)
⋅
P
(
High|No
)
P(\text{No|X}) \propto P(\text{No}) \cdot P(\text{Sunny|No}) \cdot P(\text{High|No}) \cdot P(\text{High|No})
P(No|X)∝P(No)⋅P(Sunny|No)⋅P(High|No)⋅P(High|No)
代入数据:
P
(
Yes|X
)
=
0.5
⋅
1
6
⋅
0.333
⋅
0.6
≈
0.0167
P(\text{Yes|X}) = 0.5 \cdot \frac{1}{6} \cdot 0.333 \cdot 0.6 \approx 0.0167
P(Yes|X)=0.5⋅61⋅0.333⋅0.6≈0.0167
P
(
No|X
)
=
0.5
⋅
0.5
⋅
0.5
⋅
0.6
≈
0.075
P(\text{No|X}) = 0.5 \cdot 0.5 \cdot 0.5 \cdot 0.6 \approx 0.075
P(No|X)=0.5⋅0.5⋅0.5⋅0.6≈0.075
分类决策
比较后验概率:
P
(
No|X
)
>
P
(
Yes|X
)
P(\text{No|X}) > P(\text{Yes|X})
P(No|X)>P(Yes|X)
因此,预测结果为 “No”,即不适合打球。
4.4 代码实现
from sklearn.naive_bayes import MultinomialNB
from sklearn.preprocessing import LabelEncoder
import numpy as np
# 数据集定义
data = [
['Sunny', 'High', 'High', 'No'], # 样本 1
['Sunny', 'High', 'Normal', 'No'], # 样本 2
['Overcast', 'High', 'High', 'Yes'], # 样本 3
['Rainy', 'Mild', 'High', 'Yes'], # 样本 4
['Rainy', 'Low', 'Normal', 'Yes'], # 样本 5
['Rainy', 'Low', 'High', 'No'], # 样本 6
]
# 特征和标签提取
X = [row[:-1] for row in data] # 提取特征 ['Weather', 'Temperature', 'Humidity']
y = [row[-1] for row in data] # 提取标签 ['Play']
# 将类别数据编码为数值
encoders = []
X_encoded = []
for col in np.array(X).T:
le = LabelEncoder()
X_encoded.append(le.fit_transform(col))
encoders.append(le)
X_encoded = np.array(X_encoded).T
label_encoder = LabelEncoder()
y_encoded = label_encoder.fit_transform(y)
# 创建并训练朴素贝叶斯模型
model = MultinomialNB()
model.fit(X_encoded, y_encoded)
# 打印训练结果
print("Class Probabilities (P(y)):")
print(model.class_log_prior_) # 类别先验概率的对数
print("\nFeature Conditional Probabilities (P(X|y)):")
print(np.exp(model.feature_log_prob_)) # 特征条件概率的对数转换为普通概率
# 测试数据
test_data = [['Sunny', 'High', 'High']] # 新样本
# 测试数据编码
test_encoded = []
for i, col in enumerate(np.array(test_data).T):
test_encoded.append(encoders[i].transform(col))
test_encoded = np.array(test_encoded).T
# 预测结果
prediction = model.predict(test_encoded)
decoded_prediction = label_encoder.inverse_transform(prediction)
print("\nPrediction for Test Data:")
for i, test in enumerate(test_data):
print(f"Input: {test}, Prediction: {decoded_prediction[i]}")
5 关联规则
5.1 概述
关联规则是一种用于发现数据中隐藏关系的算法,常用于市场购物篮分析,比如找出“哪些商品经常一起购买”。它的核心是通过频繁模式寻找“如果 A 发生,那么 B 也很可能发生”的规则,帮助我们了解数据间的相关性。
关联规则的三个重要指标是:
• 支持度(Support):某事件在数据中出现的频率。
• 置信度(Confidence):在发生 A 的条件下,发生 B 的概率。
• 提升度(Lift):A 和 B 同时发生的可能性是否高于随机独立发生。
例如,在分析超市数据时,如果发现“购买面包的顾客有 70% 的概率还会买牛奶”,我们就可以利用这条规则优化商品摆放或促销策略。关联规则简单直观,但对大数据集的处理需要高效算法(如 Apriori)。
5.2具体例子
一个超市的交易数据集,用于分析商品的关联关系。数据如下:
交易编号(Transaction ID) | 商品列表 (Items Bought) |
---|---|
1 | 牛奶,面包,黄油 |
2 | 面包,黄油 |
3 | 牛奶, 面包, 饼干 |
4 | 牛奶, 面包, 黄油, 饼干 |
5 | 牛奶, 饼干 |
目标:使用关联规则算法找出购买某些商品时,其他商品也会被一起购买的模式。例如,发现“买了面包的顾客,是否也会买牛奶?”。
生成频繁项集
我们首先计算每个商品或商品组合的支持度(Support),即它们在交易中出现的频率。假设支持度阈值为 40%。
支持度计算公式:
Support
(
A
)
=
包含 A 的交易数
总交易数
\text{Support}(A) = \frac{\text{包含 A 的交易数}}{\text{总交易数}}
Support(A)=总交易数包含 A 的交易数
支持度计算结果:
项集 (Itemset) | 出现次数 | 支持度 (Support) |
---|---|---|
牛奶 (Milk) | 4 | 4/5 = 0.8 |
面包 (Bread) | 4 | 4/5 = 0.8 |
黄油 (Butter) | 3 | 3/5 = 0.6 |
饼干 (Cookies) | 3 | 3/5 = 0.6 |
牛奶, 面包 | 3 | 4/5 = 0.6 |
面包, 黄油 | 3 | 3/5 = 0.6 |
牛奶, 饼干 | 3 | 4/5 = 0.6 |
牛奶, 面包, 黄油 | 2 | 2/5 = 0.4 |
筛选支持度 ≥ 40% 的项集,保留以上结果。
计算置信度
对于每条关联规则
A
→
B
A \to B
A→B ,置信度的公式为:
Confidence
(
A
→
B
)
=
Support
(
A
∪
B
)
Support
(
A
)
\text{Confidence}(A \to B) = \frac{\text{Support}(A \cup B)}{\text{Support}(A)}
Confidence(A→B)=Support(A)Support(A∪B)
示例计算:规则 “面包
→
\to
→牛奶”
Confidence
(
Bread
→
Milk
)
=
Support
(
Bread, Milk
)
Support
(
Bread
)
=
0.6
0.8
=
0.75
\text{Confidence}(\text{Bread} \to \text{Milk}) = \frac{\text{Support}(\text{Bread, Milk})}{\text{Support}(\text{Bread})} = \frac{0.6}{0.8} = 0.75
Confidence(Bread→Milk)=Support(Bread)Support(Bread, Milk)=0.80.6=0.75
计算提升度
提升度衡量 A 和 B 同时发生的可能性是否高于它们独立发生的概率。公式如下:
Lift
(
A
→
B
)
=
Confidence
(
A
→
B
)
Support
(
B
)
\text{Lift}(A \to B) = \frac{\text{Confidence}(A \to B)}{\text{Support}(B)}
Lift(A→B)=Support(B)Confidence(A→B)
示例计算:规则 “面包
→
\to
→牛奶”
结果分析
根据支持度、置信度和提升度,选出有价值的规则:
规则 (Rule) | 支持度 (Support) | 置信度 (Confidence) | 提升度 (Lift) |
---|---|---|---|
面包 → \to →牛奶 | 0.6 | 0.75 | 0.9375 |
牛奶 → \to →面包 | 0.6 | 0.75 | 0.9375 |
面包 → \to →黄油 | 0.6 | 0.75 | 1.25 |
结果解读:
- 面包 → \to →牛奶:置信度为 75%,说明买了面包的人有 75% 的概率会买牛奶,提升度接近 1,说明面包和牛奶的关联性较弱。
- 面包
→
\to
→黄油:置信度 75%,提升度 1.25,说明这条规则比随机出现的概率更高,可以进一步利用。
这些规则可以用来优化商品摆放或设计联合促销活动。
5.3代码实现
from mlxtend.frequent_patterns import apriori, association_rules
from mlxtend.preprocessing import TransactionEncoder
import pandas as pd
# 数据集定义
data = [
['牛奶', '面包', '黄油'], # 交易 1
['面包', '黄油'], # 交易 2
['牛奶', '面包', '饼干'], # 交易 3
['牛奶', '面包', '黄油', '饼干'], # 交易 4
['牛奶', '饼干'] # 交易 5
]
# 使用 TransactionEncoder 将数据转换为布尔值矩阵
te = TransactionEncoder()
te_data = te.fit(data).transform(data)
df = pd.DataFrame(te_data, columns=te.columns_)
# 打印数据集布尔矩阵
print("Transaction Boolean Matrix:")
print(df)
# 使用 Apriori 算法生成频繁项集,支持度阈值设置为 0.4
frequent_itemsets = apriori(df, min_support=0.4, use_colnames=True)
# 打印频繁项集
print("\nFrequent Itemsets:")
print(frequent_itemsets)
# 基于频繁项集生成关联规则
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.6)
# 打印关联规则
print("\nAssociation Rules:")
print(rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])
6 聚类
6.1 概述
聚类是一种无监督学习算法,用来将数据根据相似性分组(称为“簇”)。它的目标是让同一簇内的数据点尽可能相似,不同簇之间的数据点差异尽可能大。
想象你在整理书籍:将小说、科普、教材分别放入不同的书架,这就是一种聚类的过程。聚类不需要提前知道数据的分类标签,而是通过分析数据本身的特征,将其自动分组。
6.2 数学基础
-
距离度量(Distance Metrics)
聚类算法的核心是衡量数据点之间的相似性,通常通过距离来表示。常见的距离计算方式包括:
(1) 欧几里得距离(Euclidean Distance)
衡量两点之间的直线距离,公式为:
d ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d(x, y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2} d(x,y)=i=1∑n(xi−yi)2
(2) 曼哈顿距离(Manhattan Distance)
沿着坐标轴的距离,公式为:
d ( x , y ) = ∑ i = 1 n ∣ x i − y i ∣ d(x, y) = \sum_{i=1}^n |x_i - y_i| d(x,y)=i=1∑n∣xi−yi∣
它适用于格子状数据,比如城市街道上的最短路径。
(3) 余弦相似度(Cosine Similarity)
衡量两个向量的方向相似性,适用于文本数据。公式为:
cos ( θ ) = ∑ i = 1 n x i y i ∑ i = 1 n x i 2 ⋅ ∑ i = 1 n y i 2 \text{cos}(\theta) = \frac{\sum_{i=1}^n x_i y_i}{\sqrt{\sum_{i=1}^n x_i^2} \cdot \sqrt{\sum_{i=1}^n y_i^2}} cos(θ)=∑i=1nxi2⋅∑i=1nyi2∑i=1nxiyi
值范围在 [-1, 1],值越接近 1,向量越相似。 -
簇内与簇间差异
聚类的目标是:• 簇内差异最小化:同一簇内的数据点要尽可能接近(相似)。
• 簇间差异最大化:不同簇之间的数据点要尽可能远离(差异大)。
簇内平方和(Within-Cluster Sum of Squares, WCSS) 是常用的衡量指标,公式为:
W C S S = ∑ k = 1 K ∑ x ∈ C k ∣ ∣ x − μ k ∣ ∣ 2 WCSS = \sum_{k=1}^K \sum_{x \in C_k} ||x - \mu_k||^2 WCSS=k=1∑Kx∈Ck∑∣∣x−μk∣∣2
其中:
•
K
K
K:簇的数量。
•
C
k
C_k
Ck:第
k
k
k个簇。
•
μ
k
\mu_k
μk:第
μ
\mu
μ个簇的中心。
6.3 具体例子
我们有一个包含二维数据点的小型数据集,目标是使用 K-Means 聚类算法将数据点分为  个簇。
数据集:
Points
=
{
(
2
,
3
)
,
(
3
,
3
)
,
(
6
,
6
)
,
(
8
,
8
)
,
(
7
,
7
)
}
\text{Points} = \{(2, 3), (3, 3), (6, 6), (8, 8), (7, 7)\}
Points={(2,3),(3,3),(6,6),(8,8),(7,7)}
初始化簇中心
假设随机初始化两个簇的质心为:
μ
1
=
(
2
,
3
)
,
μ
2
=
(
8
,
8
)
\mu_1 = (2, 3), \quad \mu_2 = (8, 8)
μ1=(2,3),μ2=(8,8)
分配数据点到最近的簇
计算每个点到两个质心的欧几里得距离,分配到最近的质心对应的簇。
距离公式:
d
(
x
,
μ
)
=
(
x
1
−
μ
1
)
2
+
(
x
2
−
μ
2
)
2
d(x, \mu) = \sqrt{(x_1 - \mu_1)^2 + (x_2 - \mu_2)^2}
d(x,μ)=(x1−μ1)2+(x2−μ2)2
计算结果如下:
点 (Point) | 到 μ 1 = ( 2 , 3 ) \mu_1=(2, 3) μ1=(2,3) 的距离 | 到 μ 2 = ( 8 , 8 ) \mu_2=(8, 8) μ2=(8,8) | 的距离 分配到的簇 |
---|---|---|---|
(2, 3) | ( 2 − 2 ) 2 + ( 3 − 3 ) 2 = 0 \sqrt{(2-2)^2 + (3-3)^2} = 0 (2−2)2+(3−3)2=0 | ( 2 − 8 ) 2 + ( 3 − 8 ) 2 ≈ 7.81 \sqrt{(2-8)^2 + (3-8)^2} \approx 7.81 (2−8)2+(3−8)2≈7.81 | 簇 1 |
(3, 3) | ( 3 − 2 ) 2 + ( 3 − 3 ) 2 = 1 \sqrt{(3-2)^2 + (3-3)^2} = 1 (3−2)2+(3−3)2=1 | ( 3 − 8 ) 2 + ( 3 − 8 ) 2 ≈ 7.07 \sqrt{(3-8)^2 + (3-8)^2} \approx 7.07 (3−8)2+(3−8)2≈7.07 | 簇 1 |
(6, 6) | ( 6 − 2 ) 2 + ( 6 − 3 ) 2 ≈ 5.0 \sqrt{(6-2)^2 + (6-3)^2} \approx 5.0 (6−2)2+(6−3)2≈5.0 | ( 6 − 8 ) 2 + ( 6 − 8 ) 2 ≈ 2.83 \sqrt{(6-8)^2 + (6-8)^2} \approx 2.83 (6−8)2+(6−8)2≈2.83 | 簇 2 |
(8, 8) | ( 8 − 2 ) 2 + ( 8 − 3 ) 2 ≈ 7.81 \sqrt{(8-2)^2 + (8-3)^2} \approx 7.81 (8−2)2+(8−3)2≈7.81 | ( 8 − 8 ) 2 + ( 8 − 8 ) 2 = 0 \sqrt{(8-8)^2 + (8-8)^2} = 0 (8−8)2+(8−8)2=0 | 簇 2 |
(7, 7) | $\sqrt{(7-2)^2 + (7-3)^2} \approx 6.40 | $ ( 7 − 8 ) 2 + ( 7 − 8 ) 2 ≈ 1.41 \sqrt{(7-8)^2 + (7-8)^2} \approx 1.41 (7−8)2+(7−8)2≈1.41 | 簇 2 |
第一轮分簇结果:
• 簇 1:
(
2
,
3
)
,
(
3
,
3
)
(2, 3), (3, 3)
(2,3),(3,3)
• 簇 2:
(
6
,
6
)
,
(
8
,
8
)
,
(
7
,
7
)
(6, 6), (8, 8), (7, 7)
(6,6),(8,8),(7,7)
更新簇中心
计算每个簇的质心(所有点的平均值)作为新的质心。
簇 1 的新质心:
μ
1
=
(
2
+
3
2
,
3
+
3
2
)
=
(
2.5
,
3.0
)
\mu_1 = \left( \frac{2+3}{2}, \frac{3+3}{2} \right) = (2.5, 3.0)
μ1=(22+3,23+3)=(2.5,3.0)
簇 2 的新质心:
μ
2
=
(
6
+
8
+
7
3
,
6
+
8
+
7
3
)
=
(
7.0
,
7.0
)
\mu_2 = \left( \frac{6+8+7}{3}, \frac{6+8+7}{3} \right) = (7.0, 7.0)
μ2=(36+8+7,36+8+7)=(7.0,7.0)
重复分配和更新
再次将数据点分配到最近的簇,然后更新质心,直到簇中心不再变化。
第二轮分簇结果:
• 簇 1:,质心保持为 
• 突2:,质心保持为 
质心未发生变化,算法收敛。
最终结果
• 簇 1:
(
2
,
3
)
,
(
3
,
3
)
(2, 3), (3, 3)
(2,3),(3,3),质心为
(
2.5
,
3.0
)
(2.5, 3.0)
(2.5,3.0)
• 簇 2:
(
6
,
6
)
,
(
8
,
8
)
,
(
7
,
7
)
,
(6, 6), (8, 8), (7, 7),
(6,6),(8,8),(7,7),质心为
(
7.0
,
7.0
)
(7.0, 7.0)
(7.0,7.0)
6.4 代码实现
from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt
# 数据集
data = np.array([
[2, 3],
[3, 3],
[6, 6],
[8, 8],
[7, 7]
])
# 创建并训练 K-Means 模型
kmeans = KMeans(n_clusters=2, random_state=42) # 2 个簇
kmeans.fit(data)
# 聚类结果
labels = kmeans.labels_ # 每个点的簇标签
centroids = kmeans.cluster_centers_ # 每个簇的质心
# 打印结果
print("Cluster Labels:", labels)
print("Centroids:", centroids)
# 可视化聚类结果
plt.scatter(data[:, 0], data[:, 1], c=labels, cmap='viridis', label='Data Points')
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', marker='X', s=200, label='Centroids')
plt.title("K-Means Clustering")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.legend()
plt.show()
OVER!