拉普拉斯修正——机器学习中常用的数据平滑处理方法

拉普拉斯修正平滑方法

在朴素贝叶斯分类器中,计算条件概率 P ( x ∣ y ) P(x|y) P(xy)时,如果在某个类别下没有观测到某个特征值,那么P(x|y)的值就会变成0,这会导致朴素贝叶斯分类器失去分类能力。例如,在周志华老师的西瓜书的第7.3章提到,在西瓜数据集3.0中对于一个“敲声=清脆”的测试用例,有 P ( 敲声 = 清脆 ∣ 好瓜 = 是 ) P(敲声=清脆|好瓜=是) P(敲声=清脆好瓜=)=0,因此基于朴素贝叶斯公式,无论该样本的其它属性是什么,它的分类结果都会是“好瓜=否”。为了解决这个问题,我们需要对条件概率进行平滑,使得即使在没有观测到某个特征值的情况下,对应的概率值也不会为0。

**拉普拉斯修正的本质是给每个计数加上一个较小的数,该值通常为1,既保证了每个属性概率非零又保证了概率和为1。**假设用N表示训练集中总共的分类数;属性 a i a_i ai可能的取值数用

### 关于《机器学习》西瓜书的相关习题解答与实验代码 以下是关于《机器学习》西瓜书中涉及的习题解答以及部分实验代码的总结: #### 一、第六章相关内容 在第六章中,主要讨论的是支持向量机(SVM)。如果需要完成该章节中的课后习题,可以参考如下思路: - **理论推导**:针对公式推导类题目,建议仔细阅读课本中的定义并结合线性代数的知识进行求解[^1]。 - **实践操作**:可以通过 Python 的 `sklearn` 库来实现 SVM 模型。例如,构建一个简单的二分类模型: ```python from sklearn import svm import numpy as np X = np.array([[0, 0], [1, 1]]) y = np.array([0, 1]) clf = svm.SVC(kernel='linear') clf.fit(X, y) print(clf.predict([[2., 2.]])) ``` --- #### 二、第七章相关内容 第七章重点介绍了朴素贝叶斯算法及其改进方法——拉普拉斯平滑修正。以下是一个基于拉普拉斯修正的朴素贝叶斯分类器实现,并以西瓜数据集为例对样本进行判别[^2]。 ##### 数据处理 假设我们已经加载了西瓜数据集 3.0 并将其划分为训练集和测试集,则可按照以下方式实现分类器: ```python def naive_bayes_laplace(train_data, test_sample): from collections import defaultdict class_counts = defaultdict(int) feature_probs = {} # 统计类别数量 for sample in train_data: label = sample[-1] class_counts[label] += 1 total_samples = sum(class_counts.values()) # 计算先验概率 P(Ck) prior_probabilities = {label: count / total_samples for label, count in class_counts.items()} # 初始化条件概率表 for label in class_counts.keys(): feature_probs[label] = defaultdict(lambda: 1) # 使用 Laplace 平滑初始化为 1 # 更新条件概率表 for sample in train_data: features = sample[:-1] label = sample[-1] for i, value in enumerate(features): key = f"{i}_{value}" feature_probs[label][key] += 1 # 归一化条件概率 for label, counts in feature_probs.items(): normalization_factor = sum(counts.values()) + len(set(feature.split('_')[1] for feature in counts)) * 1 for key in counts: counts[key] /= normalization_factor # 测试阶段 max_posterior = None predicted_label = None for label in class_counts.keys(): posterior = prior_probabilities[label] for i, value in enumerate(test_sample): key = f"{i}_{value}" posterior *= feature_probs[label].get(key, 1e-8) # 防止零概率 if not max_posterior or posterior > max_posterior: max_posterior = posterior predicted_label = label return predicted_label ``` 调用上述函数即可完成预测任务。 --- #### 三、第四章相关内容 第四章探讨了决策树的学习过程及相关性质。其中提到的一个重要结论是:对于不含冲突的数据集,总能通过某种划分策略找到一棵满足训练误差为零的决策树[^5]。 为了验证这一结论,我们可以利用 ID3 或 C4.5 算法手动构造一颗决策树。下面提供了一个简化版的决策树生成逻辑: ```python def create_decision_tree(data_set, labels): class_list = [example[-1] for example in data_set] # 如果所有实例属于同一类 if class_list.count(class_list[0]) == len(class_list): return class_list[0] # 如果特征耗尽 if len(data_set[0]) == 1: return majority_vote(class_list) best_feature_index = choose_best_splitting_feature(data_set) best_feature_label = labels[best_feature_index] tree = {best_feature_label: {}} del(labels[best_feature_index]) unique_values = set(example[best_feature_index] for example in data_set) for value in unique_values: sub_labels = labels[:] tree[best_feature_label][value] = create_decision_tree(split_data_set(data_set, best_feature_index, value), sub_labels) return tree # 辅助函数 def split_data_set(data_set, axis, value): ret_data_set = [] for feat_vec in data_set: if feat_vec[axis] == value: reduced_feat_vec = feat_vec[:axis] reduced_feat_vec.extend(feat_vec[axis+1:]) ret_data_set.append(reduced_feat_vec) return ret_data_set def majority_vote(class_list): vote_dict = {} for cls in class_list: vote_dict[cls] = vote_dict.get(cls, 0) + 1 sorted_votes = sorted(vote_dict.items(), key=lambda item:item[1], reverse=True) return sorted_votes[0][0] def choose_best_splitting_feature(data_set): num_features = len(data_set[0]) - 1 base_entropy = calculate_shannon_entropy(data_set) best_info_gain = 0.0 best_feature = -1 for i in range(num_features): info_gain = base_entropy - conditional_entropy(data_set, i) if info_gain > best_info_gain: best_info_gain = info_gain best_feature = i return best_feature def calculate_shannon_entropy(data_set): num_entries = len(data_set) label_count = {} for feat_vec in data_set: current_label = feat_vec[-1] label_count[current_label] = label_count.get(current_label, 0) + 1 shannon_ent = 0.0 for key in label_count: prob = float(label_count[key]) / num_entries shannon_ent -= prob * math.log(prob, 2) return shannon_ent def conditional_entropy(data_set, feature_idx): entropy_sum = 0.0 values = set(example[feature_idx] for example in data_set) for value in values: subset = split_data_set(data_set, feature_idx, value) probability = len(subset) / float(len(data_set)) entropy_sum += probability * calculate_shannon_entropy(subset) return entropy_sum ``` 此代码片段实现了基本的决策树生成流程,并可通过调整参数适应不同的应用场景[^4]。 --- #### 四、其他补充资源 除了以上具体章节外,《机器学习》西瓜书中还涵盖了大量经典算法及其变体。读者可以根据实际需求深入研究每种技术背后的原理及其实现细节。例如,在第八章中会介绍聚类分析;第九章则聚焦强化学习等内容[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易霭珞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值