16 过拟合与欠拟合

16 过拟合与欠拟合

在数据挖掘和机器学习中,过拟合欠拟合是影响模型性能的两个重要概念。理解这两个概念有助于我们更好地选择合适的模型及其参数,提升预测精度。

过拟合

定义

过拟合发生在模型学习到了训练数据中的噪声和细节,而不仅仅是数据的主要趋势。当一个模型过于复杂,比如包含过多的特征或用复杂的算法来拟合训练集时,反而可能导致模型在新数据上的表现变差。

特征

  • 高训练集精度
  • 低测试集精度
  • 模型复杂度高

案例

假设我们有一组数据点,表示某产品的价格(y)与其广告支出(x)的关系。我们用多项式回归来拟合这组数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

# 生成数据
np.random.seed(0)
x = np.random.rand(10, 1) * 10
y = 2 * (x ** 2) + np.random.randn(10, 1) * 5 # 加入噪声

# 过拟合模型
poly_features = PolynomialFeatures(degree=10)
x_poly = poly_features.fit_transform(x)
model = LinearRegression()
model.fit(x_poly, y)

# 预测
x_new = np.linspace(0, 10, 100).reshape(-1, 1)
x_new_poly = poly_features.transform(x_new)
y_new = model.predict(x_new_poly)

# 绘图
plt.scatter(x, y, color='blue', label='训练数据')
plt.plot(x_new, y_new, color='red', label='过拟合模型')
plt.legend()
plt.xlabel('广告支出')
plt.ylabel('产品价格')
plt.title('过拟合示例')
plt.show()

在上面的例子中,当我们使用十次多项式来拟合数据时,模型完全适应了训练数据的每一个点,导致曲线非常复杂,这就是过拟合的体现。虽然模型在训练集上表现很好,但它在未知数据(测试集)上可能会表现不佳。

欠拟合

定义

欠拟合发生在模型未能捕捉到训练数据中的趋势。模型过于简单,无法有效地解释数据。

特征

  • 训练集精度低
  • 测试集精度低
  • 模型复杂度低

案例

延续上面的例子,如果我们使用一条直线(线性回归)来拟合这些数据,可能会出现欠拟合的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sklearn.linear_model import LinearRegression

# 欠拟合模型
linear_model = LinearRegression()
linear_model.fit(x, y)

# 预测
y_pred = linear_model.predict(x_new)

# 绘图
plt.scatter(x, y, color='blue', label='训练数据')
plt.plot(x_new, y_pred, color='green', label='欠拟合模型')
plt.legend()
plt.xlabel('广告支出')
plt.ylabel('产品价格')
plt.title('欠拟合示例')
plt.show()

在这个示例中,模型仅使用线性方程来拟合数据。由于数据的真正关系是一个二次方程,线性模型显然无法捕捉到这种复杂性,导致它在训练集和测试集上的表现都不佳,这就是欠拟合的结果。

总结

  • 过拟合欠拟合是模型性能不佳的两个极端。
  • 过拟合意味着模型太复杂,学习到了训练数据的噪声,而不是潜在的模式。
  • 欠拟合则意味着模型过于简单,无法捕捉数据中的重要特征。
  • 理想的情况是找到一个合适的模型复杂度,使得模型在训练集和测试集上均有良好的表现。为此,我们可以使用交叉验证、正则化等技术来帮助选择合适的模型和参数。
17 交叉验证简介

17 交叉验证简介

在数据挖掘中,评估模型的性能至关重要。交叉验证是一种常用的验证方法,可以帮助我们更好地评估模型的泛化能力。

什么是交叉验证?

交叉验证是一种统计学方法,用于评估和比较学习算法,以防止过拟合的问题。它将数据集划分为多个子集,模型在这些子集上进行训练和测试,以获得更可靠的性能评估。

交叉验证的类型

K折交叉验证

K折交叉验证是最常用的交叉验证方法。其步骤如下:

  1. 将数据集随机划分为 K 个子集。
  2. 在每次迭代中,选择一个子集作为 测试集,其余 K-1 个子集作为 训练集
  3. 重复上述步骤 K 次,每次选择不同的子集作为测试集。
  4. 最后,将所有迭代的性能结果进行平均,作为最终评估指标。

示例代码(使用 Python 和 scikit-learn):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from sklearn.model_selection import KFold
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 初始化K折交叉验证
kf = KFold(n_splits=5)
model = RandomForestClassifier()

accuracies = []

for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]

# 训练模型
model.fit(X_train, y_train)
# 预测
predictions = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, predictions)
accuracies.append(accuracy)

# 输出平均准确率
print("平均准确率:", sum(accuracies) / len(accuracies))

留出法

留出法是一种更简单的验证方式。常见做法是将数据集以一定比例分为训练集和测试集(例如 80% 训练集,20% 测试集)。这种方法简单,但可能导致结果不稳定。

其他变种

还有一些其他的交叉验证变种,如 分层K折交叉验证(Stratified K-Folds),适用于类别不平衡的数据集,确保每个折中的类别分布与整体数据集保持一致。

交叉验证的优缺点

优点

  • 提升模型性能评估的可靠性。
  • 有助于选择最佳模型参数,减少过拟合风险。

缺点

  • 计算开销较大,尤其是数据集和模型复杂度较高时。
  • 可能导致训练时间大幅增加。

结论

交叉验证是数据挖掘过程中不可或缺的一部分,通过合理地评估模型性能,你可以更好地选择和优化你的模型,从而在实际应用中获得更好的结果。务必在模型评估中使用交叉验证,以确保结果的稳健性。

18 市场篮子分析案例

18 市场篮子分析案例

市场篮子分析是一种经典的数据挖掘技术,通常用于发现商品之间的购买关联。通过分析顾客在购物时的行为,我们可以获得有价值的商业洞察,例如哪些商品经常一起被购买,从而帮助商家制定促销策略和优化商品布局。

案例背景

假设我们有一份超市的交易数据,记录了顾客购买的不同商品。我们的目标是分析这些交易数据,找出哪些商品经常一起购买,以便进行交叉销售和提升销售额。

数据准备

我们将使用一个简单的超市交易数据集,其中包含一些顾客的购物记录。数据可能会格式如下:

1
2
3
4
5
6
TransactionID, Items
1, Milk, Bread, Eggs
2, Bread, Diaper, Beer, Eggs
3, Milk, Diaper, Beer, Cola
4, Bread, Milk, Diaper, Beer
5, Bread, Milk

在这个数据集中,每一行代表一次交易,Items 列中列出了顾客所购买的商品。

数据处理

在进行市场篮子分析之前,我们需要将数据转换成合适的格式,以便应用关联规则挖掘算法。我们可以使用 pandas 库来处理数据,并将商品转换为稀疏矩阵格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder

# 创建交易数据列表
dataset = [
['Milk', 'Bread', 'Eggs'],
['Bread', 'Diaper', 'Beer', 'Eggs'],
['Milk', 'Diaper', 'Beer', 'Cola'],
['Bread', 'Milk', 'Diaper', 'Beer'],
['Bread', 'Milk']
]

# 使用TransactionEncoder转换数据
encoder = TransactionEncoder()
onehot = encoder.fit(dataset).transform(dataset)
df = pd.DataFrame(onehot, columns=encoder.columns_)

应用关联规则挖掘

接下来,我们将使用 mlxtend 库中的 apriori 算法来挖掘频繁项集,并使用 association_rules 函数来提取关联规则。

1
2
3
4
5
6
7
8
9
10
from mlxtend.frequent_patterns import apriori, association_rules

# 计算频繁项集
frequent_itemsets = apriori(df, min_support=0.4, use_colnames=True)

# 计算关联规则
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.6)

# 输出结果
print(rules)

分析结果

运行上面的代码,我们会获得一组关联规则,其中包括以下几个重要的指标:

  • 支持度(support):表示某个商品组合在所有交易中出现的频率。
  • 置信度(confidence):表示在购买了某个商品的情况下,顾客购买另外一个商品的概率。
  • 提升度(lift):表示某个商品组合之间的相互影响程度。

我们可以根据这些指标分析商品之间的关系。比如,如果我们发现 {Milk, Bread} 的提升度很高,说明购买 Milk 的顾客很可能也会购买 Bread。商家可以利用这一信息进行交叉销售,例如在结账时推荐 Bread

总结

通过市场篮子分析,我们可以识别出顾客的购买模式,从而优化商品的布局、制定促销策略、提升用户体验。市场篮子分析 的实际应用场景非常广泛,包括零售、电子商务、餐饮等行业。

希望这个简单的案例能够帮助你理解数据挖掘中的市场篮子分析!