什么是“判定问题”?(3)

什么是“判定问题”?(3)- NP-hard与NP

已有 1586 次阅读 2015-12-1 12:19 |个人分类:不确定性问题和算法讨论|系统分类:科研笔记|关键词:NP-hard NP

我们已经从NP的二个定义等价的流行观点切入,通过解读NDTM、算法复杂度、停机问题,揭示了NP流行定义将NP与P混淆,导致NP的“不确定性”消失,是有“P versus NP”世纪难题的困惑。

这里,我们再来解读另一个重要概念NP-hard,进一步揭示NP流行定义带给人们观念认知的混淆和混乱:

一,流行观念:NP-hard

于流行观念,NP-hard与“优化问题”有关,而NP与“判定问题”有关:

1,优化问题与判定问题(https://en.wikipedia.org/wiki/Optimization_problem)

In mathematics and computer science, an optimization problem is the problem of finding the best solution from all feasible solutions. Optimization problems can be divided into two categories depending on whether the variables are continuous or discrete. An optimization problem with discrete variables is known as a combinatorial optimization problem. In a combinatorial optimization problem, we are looking for an object such as an integer, permutation or graph from a finite (or possibly countable infinite) set.

For each combinatorial optimization problem, there is a corresponding decision problem that asks whether there is a feasible solution for some particular measure. For example, if there is a graph G which contains vertices u and v, an optimization problem might be "find a path from u to v that uses the fewest edges". This problem might have an answer of, say, 4. A corresponding decision problem would be "is there a path from u to v that uses 10 or fewer edges?" This problem can be answered with a simple 'yes' or 'no'.

2,NP与NP-hard(https://en.wikipedia.org/wiki/NP-hardness)

NP : Class of computational problems for which a given solution can be verified as a solution in polynomial time by a deterministic Turing machine.

NP-hard :Class of problems which are at least as hard as the hardest problems in NP. Problems that are NP-hard do not have to be elements of NP; indeed, they may not even be decidable.

Consequences:

-If P ≠ NP, then NP-hard problems cannot be solved in polynomial time;

-If an optimization problem H has an NP-complete decision version L, then H is NP-hard.

二,解读流行观念:NP-hard

首先,从逻辑的角度,NP-hard的流行定义:Class of problems which are at least as hard as the hardest problems in NP,虽说没错;但从认识问题的角度,此定义却几乎是什么也没说。这也正是为什么人们学完NP完备理论就很快将之忘得干干净净的根本原因。

其次,追本溯源,人们当初遭遇到一类找不到多项式时间算法求解的问题时,这些问题正是以“优化问题”的面貌出现的,优化问题有两类,离散性的优化问题被转换为“判定问题”。“物有本末,事有终始”,也就是说,NP概念的源头在“优化问题”上。然而,由于“优化问题”的解具有不可验证性,人们不是面对现实、直探其“不确定性”的本质,而是采取回避的态度,给出一个“特定的界值(some particular measure)”,将“优化问题”转换成所谓的“判定问题”,让转换后的“判断问题”的“解”变得“可验证(确定性)”,然后用这个“可验证性”去定义NP,其结果却是让原初“优化问题”的“不确定性”消失了,导致人们对NP的误读至今!

再次,正如我们的分析,由于流行的“NP问题”的定义中,不确定性消失了,所以当初提出问题的意义也就消失了,但“问题”仍然存在,这就是原有的理论体系中不得不给这个无法驱除的不死的冤魂留下NP-hard 这个名称的原因。

三,从我们的“不确定性问题(NP)”的角度解读NP-hard

于我们的NP理论,NP被还原成“不确定性问题(Nondeterministic Problem)”,故“优化问题”与其对应的“判定问题”都是NP,由于“优化问题”的“最优解”具有不可验证性,而“解的可验证性”是计算求解问题的一个必要条件,故通常将“优化问题”转化为“判定问题”来解决。  

 



转载本文请联系原作者获取授权,同时请注明本文来自柳渝科学网博客。
链接地址:http://blog.sciencenet.cn/blog-2322490-940181.html 

<think>判定树(Decision Tree)是一种用于分类和回归的机器学习模型。它通过树状结构表示决策过程,每个内部节点表示一个特征上的测试,每个分支代表一个测试结果,而每个叶节点代表一个类别(分类树)或一个值(回归树)。判定树易于理解和解释,可以处理数值型和类别型数据。###判定树的基本概念1. **节点类型**:-**根节点**:没有入边,但有零条或多条出边。- **内部节点**:恰有一条入边,且有多条出边。-**叶节点**:恰有一条入边,没有出边,存放类别标签或回归值。2.**分裂准则**:- **分类树**:常用基尼不纯度(Giniimpurity)或信息增益(Information gain)作为分裂标准。- **回归树**:常用均方误差(MSE)或平均绝对误差(MAE)作为分裂标准。3.**停止条件**:-节点中的样本属于同一类别(或回归值足够接近)。-树的深度达到预设值。-节点中的样本数少于预设阈值。-分裂带来的性能提升小于预设阈值。 ###判定树的构建算法(ID3算法为例) ID3算法使用信息增益来选择特征进行分裂。信息增益表示特征A对训练数据集D的信息增益,定义为D的经验熵与特征A给定条件下D的经验条件熵之差:\[ \text{Gain}(D,A)= H(D)- H(D|A)\]其中,\( H(D)\)是数据集D的经验熵,\( H(D|A)\)是特征A给定条件下D的经验条件熵。###代码示例:使用Python的scikit-learn库构建判定树以下是一个使用scikit-learn库中的`DecisionTreeClassifier`构建分类树的示例: ```pythonfrom sklearn.datasetsimport load_irisfromsklearn.model_selectionimport train_test_splitfromsklearn.tree importDecisionTreeClassifier,plot_treeimportmatplotlib.pyplotas plt#加载鸢尾花数据集iris= load_iris() X= iris.datay =iris.target#划分训练集和测试集X_train, X_test,y_train, y_test =train_test_split(X, y, test_size=0.3,random_state=42) #创建决策树分类器clf= DecisionTreeClassifier(criterion=&#39;entropy&#39;,max_depth=3, random_state=42)clf.fit(X_train,y_train) #评估模型accuracy =clf.score(X_test,y_test) print(f"模型准确率:{accuracy:.2f}") #可视化决策树plt.figure(figsize=(12,8))plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names,filled=True) plt.show()``` ###代码解释1.**数据准备**:-使用鸢尾花数据集,包含150个样本,4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度),3个类别(山鸢尾、变色鸢尾、维吉尼亚鸢尾)。 2. **模型训练**:-使用`DecisionTreeClassifier`初始化一个决策树分类器。-参数`criterion=&#39;entropy&#39;`表示使用信息增益作为分裂标准。-参数`max_depth=3`限制树的最大深度为3,防止过拟合。-调用`fit`方法在训练集上训练模型。 3. **模型评估**:-使用测试集计算模型准确率。 4. **树的可视化**:-使用`plot_tree`函数绘制决策树,并传入特征名和类别名以增强可读性。-参数`filled=True`表示按类别填充颜色。 ###判定树的优缺点**优点**: -易于理解和解释,可视化直观。 -不需要数据预处理(如标准化、归一化)。-能够处理数值型和类别型数据。-可以处理多输出问题。**缺点**:-容易过拟合,需要剪枝或设置停止条件。-不稳定,数据的小变化可能导致完全不同的树。-学习最优决策树是NP完全问题,通常使用启发式方法(如贪心算法)。###剪枝(Pruning) 剪枝是判定树算法中防止过拟合的主要技术,分为预剪枝(Pre-pruning)和后剪枝(Post-pruning): -**预剪枝**:在树生长过程中提前停止生长,如设置最大深度、最小样本数等。- **后剪枝**:先构建完整的树,然后自底向上替换子树为叶节点,根据验证集性能决定是否剪枝。###回归树回归树用于预测连续值,其构建过程与分类树类似,但分裂标准通常为均方误差(MSE):\[ \text{MSE}= \frac{1}{n}\sum_{i=1}^{n} (y_i- \hat{y}_i)^2\]其中,\( \hat{y}_i\)是节点中样本的平均值。###相关算法-**ID3**:使用信息增益,只能处理类别型特征。 -**C4.5**:ID3的改进,使用信息增益率,可处理连续型特征和缺失值。- **CART**(分类与回归树):使用基尼指数(分类)或均方误差(回归),可处理连续型和类别型特征。---### §§相关问题§§:1.什么是基尼指数?在判定树中如何使用? 2.如何防止判定树过拟合?请列举几种剪枝方法。3.随机森林与判定树的关系是什么?随机森林如何提升性能? 4.在判定树中如何处理连续型特征?</think>### 判定树(Decision Tree)详解 判定树是一种用于表示决策过程的树形结构,广泛应用于算法设计、数据结构、人工智能和决策分析等领域。它通过树状图表示各种可能的决策路径及其结果,帮助系统化地解决决策问题。 #### 核心概念 1. **定义**: - 判定树是一种特殊的树结构,其中: - 内部节点表示决策条件(属性测试) - 分支表示决策结果(属性取值) - 叶节点表示最终决策结果(类别标签或操作) 2. **关键特征**: - 分层决策过程:从根节点到叶节点的路径代表完整的决策流程 - 互斥且完备:所有可能的决策情况都被覆盖且不重叠 - 高效决策:通过树形结构减少决策步骤 #### 应用场景 1. **算法设计**: - 比较排序算法的决策过程(如堆排序、归并排序) - 搜索算法的决策路径(如二叉搜索树) 2. **人工智能**: - 机器学习中的决策树分类器 - 游戏AI的决策系统(如棋类游戏走法决策) 3. **系统设计**: - 诊断系统(如医疗诊断、故障排查) - 规则引擎(如业务规则决策) #### 经典示例:排序算法的判定树 以下是一个三元素排序的判定树示例: ``` [a,b,c] / | \ / | \ a<b? a<c? b<c? / | \ Y N Y / / \ \ [b,a,c] [c,a,b] [a,c,b] | / \ | b<c? a<b? a<c? a<b? / / \ / \ Y N Y N Y / | | | | [a,b,c] [c,b,a] [b,c,a] [c,a,b] [a,c,b] ``` #### 判定树实现(Python示例) ```python class DecisionNode: def __init__(self, question=None, result=None): self.question = question # 决策条件(如 "a < b?") self.branches = {} # 分支:{条件结果: 子节点} self.result = result # 叶节点的最终结果 def add_branch(self, answer, node): self.branches[answer] = node def decide(self, input_data): if self.result is not None: return self.result # 到达叶节点,返回结果 # 获取决策结果(实际应用中需自定义评估函数) ans = evaluate_condition(self.question, input_data) if ans in self.branches: return self.branches[ans].decide(input_data) else: raise ValueError(f"Undefined branch for answer: {ans}") # 示例:构建三元素排序判定树 def build_sorting_tree(): # 叶节点(最终排序结果) abc = DecisionNode(result=[&#39;a&#39;,&#39;b&#39;,&#39;c&#39;]) acb = DecisionNode(result=[&#39;a&#39;,&#39;c&#39;,&#39;b&#39;]) bac = DecisionNode(result=[&#39;b&#39;,&#39;a&#39;,&#39;c&#39;]) bca = DecisionNode(result=[&#39;b&#39;,&#39;c&#39;,&#39;a&#39;]) cab = DecisionNode(result=[&#39;c&#39;,&#39;a&#39;,&#39;b&#39;]) cba = DecisionNode(result=[&#39;c&#39;,&#39;b&#39;,&#39;a&#39;]) # 第三层决策 node_bc = DecisionNode("b < c?") node_bc.add_branch(True, bac) node_bc.add_branch(False, bca) node_ab2 = DecisionNode("a < b?") node_ab2.add_branch(True, acb) node_ab2.add_branch(False, cab) node_ac2 = DecisionNode("a < c?") node_ac2.add_branch(True, abc) node_ac2.add_branch(False, cba) # 第二层决策 node_ab = DecisionNode("a < b?") node_ab.add_branch(True, node_bc) node_ab.add_branch(False, node_ab2) node_ac = DecisionNode("a < c?") node_ac.add_branch(True, node_ac2) node_ac.add_branch(False, node_ab2) # 根节点 root = DecisionNode("b < c?") root.add_branch(True, node_ab) root.add_branch(False, node_ac) return root # 条件评估函数(简化版) def evaluate_condition(question, data): # 实际应用中需根据具体问题实现 if question == "a < b?": return data[0] < data[1] elif question == "a < c?": return data[0] < data[2] elif question == "b < c?": return data[1] < data[2] else: raise ValueError(f"Unknown question: {question}") # 使用判定树进行排序决策 if __name__ == "__main__": sorting_tree = build_sorting_tree() # 测试不同输入 test_cases = [ [3, 1, 2], # a=3,b=1,c=2 [2, 3, 1], # a=2,b=3,c=1 [1, 2, 3] # a=1,b=2,c=3 ] for data in test_cases: result = sorting_tree.decide(data) print(f"Input: {data} -> Sorted: {result}") ``` #### 代码解释 1. **决策节点类(DecisionNode)**: - `question`:当前节点的决策条件 - `branches`:分支字典,键为条件结果,值为子节点 - `result`:叶节点的最终结果 - `decide()`:递归决策方法 2. **树构建(build_sorting_tree)**: - 创建叶节点表示所有可能的排序结果 - 分层构建决策节点,逐步缩小可能性范围 - 最终返回根节点 3. **决策过程**: - 从根节点开始评估条件 - 根据条件结果选择分支 - 递归直到到达叶节点 - 返回最终决策结果 #### 判定树的重要性质 1. **时间复杂度**: - 决策路径长度 = 树的高度 - 最优情况:平衡树(O(log n)) - 最差情况:退化树(O(n)) 2. **空间复杂度**: - 存储所有可能路径:O(n!)(排序决策树) - 实际应用中通常优化存储 3. **信息论基础**: - 信息增益:选择能最大程度减少不确定性的属性 - 熵:衡量决策的不确定性 #### 机器学习中的决策树 在机器学习中,决策树用于分类和回归: ```python from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier, plot_tree import matplotlib.pyplot as plt # 加载数据 iris = load_iris() X, y = iris.data, iris.target # 创建决策树 clf = DecisionTreeClassifier(max_depth=2) clf.fit(X, y) # 可视化 plt.figure(figsize=(12,8)) plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names, filled=True) plt.show() ``` #### 判定树 vs. 判定表 | 特性 | 判定树 | 判定表 | |--------------|---------------------------|---------------------| | **表示形式** | 树形结构 | 表格形式 | | **可读性** | 直观,易理解决策流程 | 紧凑,适合复杂规则 | | **扩展性** | 易于添加新分支 | 添加规则需重构表格 | | **执行效率** | 路径长度决定执行时间 | 固定时间检查所有条件| --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值