作者: Terence Parr, Prince Grover
翻译:王雨桐
校对:詹好
本文长度约为9500字 ,建议阅读10+ 分钟
本文分析了决策树可视化中的关键因素,比较了现有的可视化工具。并通过大量的示例介绍了一个决策树可视化工具的设计和实现过程。
目录
决策树概述
决策树可视化的关键因素
效果展示
与现有可视化的比较
我们的决策树可视化
可视化特征-目标空间
细节部分
用可视化树来解释单次观测
横向决策树
简化结构
回归树可视化----以波士顿房价为例
分类树可视化---以红酒为例
Scikit决策树的影子树
工具箱
SVG生成的矢量图
在适用于结构化数据的机器学习模型中,梯度提升和随机森林可以称得上是明星级模型,而决策树则是这两者的基石。 决策树的可视化工作对于了解这些模型的工作原理有极大的帮助。然而目前的可视化软件工具很基础,对新手并不友好。例如,我们无法利用现有的库展示每个节点是如何划分变量的。此外,当把一个新样本放到决策树中进行预测时,我们只能生成一张可供展示的结果图片,而很难运用现有工具将整个过程可视化。
因此我们创建了一个通用包来在scikit-learn上可视化决策树模型以及解释模型。并且我们将在马上出版的机器学习书籍《The Mechanics of Machine Learning》(由JeremyHoward编写)中大量使用该包。以下是一个简单的决策树可视化示例:
附书链接:
https://mlbook.explained.ai/
本文演示了这项工作的成果,详细介绍了我们为此所做的尝试,并概述了该工具的在使用过程中的基本框架和技术细节。 该可视化软件是dtreeviz的一部分,它是一个新兴的Python机器学习库。本文不会过多阐述决策树的基本原理,但为了方便您熟悉相关的术语使用,我们会对此做一个简短的概述。
决策树概述
决策树是一种基于二叉树(最多有左右两个子树)的机器学习模型。决策树遍历训练数据并将信息浓缩为二叉树的内部节点和叶节点,从而学习训练集中的观测值之间的关系,这些观测值表示为特征向量x和目标值y。(注:向量为粗体,标量为斜体。)
决策树中的每个叶子都表示特定的预测结果。回归树中输出的预测是一个(连续的)值,例如价格;而分类树中输出的预测是(离散的)目标类别(在scikit中表示为整数),例如是否患有癌症。决策树将观测分为具有相似目标值的组,每个叶子代表其中一个分组。对于回归而言,叶节点中观测的相似性意味着目标值之间的差异很小;而对于分类而言,则意味着大多数或所有观测属于同一类别。
任何一个从树根到叶节点的路径都要经过一系列(内部)决策节点。在训练过程中选出特定的分割点后,每个决策节点将x中的单个要素的值(xi)与分割点值进行比较。例如,在预测房租的模型中,决策节点会比较特征,如卧室数量和浴室数量等。(请参阅第3章,新样本预测的可视化效果。)即使在具有目标值离散的分类模型中,决策节点仍会比较数值特征值,这是因为在scitkit中,假定决策树模型的所有特征都是数值类型,因此分类变量必须要经过独热编码、合并、标签编码等处理。
为了得到决策节点,模型将遍历训练集的子集(或根节点的完整训练集)。在训练过程中,根据相似性最大化的原则,决策树将根据选择节点的特征和该特征空间内的分割点,将观察结果放入左右两个桶中(子集)。 (该选择过程通常要对特征和特征值进行详尽的比较)左子集中样本的xi特征值均小于分割点,而右子集中样本的xi均大于分割点。通过为左分支和右分支创建决策节点,递归地进行树的构造。当达到某个停止标准(例如,节点中包含的观测数少于5)时,决策树终止生长。
决策树可视化的关键因素
决策树可视化应该突出以下重要元素,我们将在下文中具体阐述。
决策节点的特征vs目标值分布(在本文中称为特征-目标空间)。 我们想知道能否基于特征和分割点将观测进行分类。
决策节点的特征和特征分割点。 我们需要知道每个决策节点所选择的待考察的特征变量,以及将观测分类的标准。
叶节点纯度,这会影响我们的预测置信度。 较高的纯度也就意味着那些在回归问题中较低方差的叶节点,以及分类问题中包含绝大多数目标的叶节点,它们都意味着更可靠的预测效果。
叶节点预测值。 基于训练集的目标值,该叶节点具体的预测结果。
决策节点中的样本数。 我们需要了解决策节点上大部分样本的归属。
叶节点中的样本数。 我们的目标是让决策树的叶节点更少,数目更大和纯度更高。如果样本的节点下的样本数太少,则可能由过拟合现象。
新样本如何从根节点开始被分到特定的叶节点。 这有助于解释为什么新样本得到了相应的预测。例如,在预测公寓租金价格的回归树中,由于决策节点检查了卧室的数量,而新样本的卧室数量大于3,因此预测价格偏高。
效果展示
在深入研究现有的可视化工具之前,想先介绍一下我们生成的效果图。本节重点介绍一些可视化的案例,这些是我们利用一些数据集构造的scikit回归和分类决策树。你还可以利用完整的库和代码复现所有案例。
附代码链接:
https://github.com/parrt/dtreeviz/blob/master/testing/gen_samples.py
与现有可视化工具的比较
如果搜索“可视化决策树”,很快便能找到由scikit提供的基于Python语言的解决方案:sklearn.tree.export_graphviz。此外还可以找到R甚至SAS和IBM的可视化工具。在本节中,我们收集了现有的各种决策树可视化效果,并将它们与我们使用dtreeviz库制作的决策树进行了比较。在下一部分中,我们将对可视化进行更详细的讨论。
让我们使用默认设置下的scitkit可视化工具,在大家都很熟悉的的Iris数据集上绘制一个可视化的决策树。
scikit树很好地表现了树的结构,但我们仍然发现了一些问题。首先颜色的运用不够直观,比如在为什么有些节点是彩色的而有些不是这一问题上:如果颜色代表该分类器的预测类别,那么我们可能会认为只有叶子才是彩色的,因为只有叶子才有预测。事实证明,没有颜色的节点预测能力较弱。
除此之外,基尼系数(确定性得分)会占用图中的空间,并且不利于解释。在每个节点中体现各目标类别的样本数很有用,但直方图可以提供更多信息。 此外,利用有颜色的目标类别图例会很好。最后,将true和false用作边缘标签并不够清晰,³和<看起来更清晰。最显著的区别是我们的决策节点利用堆叠直方图展示特征分布,每个目标类别都会用不同的颜色显示。同样,我们的叶子大小与该叶子中的样本数成正比。
再来考察一个回归的案例。下图是在波士顿数据集的上使用scikit的可视化效果,我们将它与dtreeviz的版本进行比较。
同样,在scikit树中,我们不能直观地理解颜色的用途,但是在进一步研究后,我们发现颜色较深的图像表示较高的预测目标值。 如前文所述,在我们的解决方案中,决策节点下能够显示特征空间分布,比如该案例就使用了特征-目标值散点图,在叶节点总使用带状图显示目标值分布,其中点更密集的叶节点意味着该叶节点下有更多的样本。
同样,我们来考察以下R语言下的可视化决策树的软件包,该软件包的结果与scikit类似,但边缘标签的效果更好:
SAS和IBM同样提供(均不支持Python语言)决策树可视化。我们发现SAS的决策节点包括与该节点的样本目标值和其他详细信息有关的条形图:
在这一案例中有一个很好的idea,就是通过边缘宽度来体现子树中的样本量。但是由于缺少水平轴,这些条形图的解释性并不如意。测试类别变量的决策节点(上图)每个类别仅具有一个条形,因此它们只能表示简单的类别计数,而不是特征分布。对于数字特征(下图),SAS决策节点显示目标值或特征值的直方图(我们无法从图像中分辨出)。SAS节点条形图/直方图似乎只是在说明目标值,这并没有告诉我们有关特征分割的信息。
下侧的SAS树似乎突出显示了新样本的预测过程,但我们无法从其他工具和库中找到任何其他示例,这样的功能似乎并不常见。
再来考察IBM软件的情况。它在泰坦尼克数据集中表现出了非常不错的可视化效果,甚至结合IBM的Watson分析以条形图的形式显示了决策节点类别的计数:
再来看看IBM较早的SPSS产品中对决策树可视化效果:
可见,在SPSS中,这些决策节点提供了与样本目标类别计数相同的SAS条形图。
以上所提及的所有可视化都提供了不错的结果,但是给予我们启发性最大的是来自《机器学习的可视化简介》中的案例。它给我们展示了一个以动画形式展示的决策树可视化案例,如下所示:
附链接:
r2d3.us/visual-intro-to-machine-learning-part-1/(译者注:很经典的可视化,建议看原网站动态图)
除了动画的要素之外,该可视化还具有此前提到的三个独特特征:
尽管该案例是出于教学目的而开发的基于hardcoded技术的可视化动图,但它给我们指明了正确的方向。
我们的决策树可视化
除了《机器学习的可视化简介》中的动画外,我们找不到另一个能够更好说明如何在决策节点(特征目标空间)处分割特征值的案例了。而这一点恰恰是在决策树模型训练期间进行操作的关键点,也是新手应该关注的点,因此我们借鉴这一方案,从检查分类树和回归树的决策节点开始我们的可视化工作。
同行,我们通过训练数据学习到决策节点选择特征xi并在xi的值域(特征空间)进行分割,将具有相似目标值的样本分到两个子树中的一个中。准确地说,训练过程中需要检查特征和目标值之间的关系。因此,除非我们的可视化工作在决策节点上显示了特征-目标空间,否则读者很难根据可视化图像来直观理解得到预测结果的整个过程和原因。为了突出现实决策节点是如何分割特征空间的,我们以单特征(AGE)的回归树和分类树作为展示。这个案例使用波士顿房价数据中的单个特征(age)来训练回归决策树。为了便于讨论,在下图中加入了节点id:
附生成效果图的代码:
https://github.com/parrt/dtreeviz/blob/master/testing/paper_examples.py
水平虚线表示决策节点中左子树和右子树的目标均值;垂直虚线表示特征空间中的分割点。下方的黑色三角形突出显示分割点并标出了确切的分割值。叶节点用虚线指示目标预测(这里使用的是平均值)。
如图所示,为了便于决策节点的比较,AGE特征轴都控制在了一个相同的值域上,而并没有将数值集中的区域进行方法。因此,决策节附近的样本的AGE值被限制在了一个狭窄的区域中。
例如,将节点0中的特征空间进一步被划分为了为节点1和8的特征空间;节点1的特征空间又进一步划分为节点2和5中所示的特征空间。当然,可以看到,这一决策树模型的预测效果并不是很好,这是因为出于展示的方便,我们仅仅单一的变量来训练模型,但是这个简单的案例给我们演示了如何可视化决策树划分特征空间的过程。
尽管分类决策树和回归决策树的在实现方式大致上相同,但对它们进行解释方式却大不相同,因此这两种情况的可视化效果是不同的。对于回归模型,最好使用特征与目标的散点图来显示特征-目标空间。但是,对于分类模型,目标是离散的类别而不是连续的数字,因此我们选择使用直方图来可视化特征目标空间。下图是在USER KNOWLEDGE数据上训练的分类树,同样我们只使用了单个特征(PEG)来进行训练,并且同样标记了节点id:
在这一案例中,直方图显示了PEG特征空间分布,而颜色则体现了特征与目标类别之间的关系。例如,在节点0中,我们可以看到具有very_low目标类别的样本聚集在PEG特征空间的左端,而具有high目标类别的样本聚集在右端。与回归树一样,左子树的特征空间和父节点上直方图分割点左侧的特征空间相同;右子树也同理。
例如,将节点9和12的直方图组合起来,可以得出节点8的直方图。我们将PEG决策节点的水平轴限制在相同范围,因此位于下方的直方图中的范围更窄,这也意味着分类更纯净。
为了更清楚地显示不同类别的特征空间,我们使用了堆叠直方图。值得注意的是,堆叠直方图在Y轴上的高度是所有类别的样本总数。多个类别的计数相互叠加。
当类别多于四或五个时,堆积直方图可读性很低,因此我们建议在这种情况下将直方图类型参数设置为不堆积的直方图。 在基数较高的目标类别下,重叠的分布更难以可视化,并且出现问题,因此我们设置了10个目标类别的限制。使用10类Digits数据集(使用非堆叠直方图)所构成的一个比较浅的决策树的示例如下:
在前面的论述中,我们省略了一些最值得关注的可视化细节,在这里我们来对其中的一些关键要素展开分析。
在对于分类树可视化中,我们使用了节点大小来指示每个节点包含的样本数量。随着节点中样本数量的减少和叶节点直径的变小,直方图将按比例变短。
对于给定的特征,特征空间(水平轴)始终具有相同的宽度和相同的范围,这更有利于比较不同节点的特征目标空间。所有直方图的条具有相同的宽度(以像素为单位)。为了避免混乱,我们仅在水平和垂直轴上标示了最小值和最大值。
尽管在决策树的可视化过程中一般不适用饼状图来进行呈现,但我们还是选择了使用它来体现叶节点的分类。我们通过观察图中是否有明显占主导的颜色,就可以评判分类结果的纯度。饼图最大的缺陷是无法体现元素间具体的关系。我们仅仅能从其中主导的颜色决定该节点的预测结果。
对于回归树而言,为了便于比较节点,我们将所有决策节点的目标(垂直)轴限制在相同的高度和相同的范围。对于给定的特征,回归要素空间(水平轴)始终是相同的宽度和范围。将所有散点图的透明度设置为较低水平,因此较高的目标值密度对应较深的颜色。
回归叶节点在垂直方向上显示相同范围的目标空间。 相比于箱状图,我们选择了带状图,因为带状图能更好地表示分布,并隐含地以点数表示样本数。(我们还用文字标示了叶子节点的样本数。)关于叶节点的预测值,我们选择了带状图的质量(均值)分布中心,同时,我们使用了虚线来将其突出显示。
除此之外,还有许多其他细节可以提高可视化图表的效果:
包含分类类别的图例。
所有颜色均从一个对于色盲而言相对友好的调色板中进行挑选,每个2至10个目标类别绑定一个调色板。
我们在文本上使用灰色而不是黑色,这更有利于人眼审视。
图中的线采用细线。
我们在带状图和饼状图中突出了其轮廓。
通过了解拆分决策节点的特征空间的过程,我们能直观地看到决策树是如何得到具体的预测结果的。现在让我们看一下如何将预测新样本的过程可视化。此处的关键是可视化从根到叶节点的路上所做出的决策。
节点内的决策很简单:如果测试向量x中的特征xi小于分割点,则归类到左子树,否则归为右子树 。为了突出决策过程,我们必须重点强调比较操作。对于沿叶子预测变量节点路径的决策节点,我们在水平特征空间中的位置xi处显示了橙色三角形。
如果橙色三角形位于黑色三角形的左侧,则沿左路径,否则沿右路径。预测过程中涉及的决策节点被带有虚线框的框包围,边缘较粗且呈橙色。以下为两个测试向量的示例树:
带有特征名称和值的测试向量x出现在叶子预测变量节点的下方(或横向决策树的右端)。测试向量突出显示了一个或多个决策节点中使用的特征。 当特征数量达到阈值20(左右方向为10)时,测试向量不会显示未使用的特征,以避免不必要的测试向量。
相比于纵向决策树,一些用户偏爱横向图像,有时树的性质从左到右体现得更好。在预测过程中,样本特征向量也可以从左向右延伸。以下是一些示例:
从更宏观的角度评估决策树,我们可以看到对分类过程的概述。这意味着比较树的形状和大小之类等,但更重要的是查看叶节点。我们想知道每个叶节点有多少个样本,分类的纯度如何,以及大多数样本落在哪里。
当可视化文件太大时,很难获得概述,因此我们提供了一个“non-fancy”选项。该选项可以生成较小的可视化文件,同时保留关键的叶子信息。以下案例是分别为non-fancy模式的回归树和分类树:
前车之鉴
从设计的角度对这些树可视化感兴趣的人可能会发现阅读我们尝试过并拒绝的内容很有意思。在设计分类树时,相比于块状的直方图,我们预计核密度估计会给出更准确的图像。 我们完成了如下的案例:
问题在于只有一个或两个样本的决策节点中,所得到的这种分布极具误导性:
我们还尝试使用气泡图代替直方图作为分类器决策节点:
这些可视化图形看起来确实很酷,但比较下来,还是直方图更易于阅读。
关于回归树,我们考虑使用箱形图显示预测值的分布,还考虑使用简单的条形图显示样本数量:
与现在使用的条形图相比,每片叶子的双图都不令人满意。箱形图无法像条形图那样显示目标值的分布。 在带状图之前,我们只是使用样本索引值作为水平轴来体现目标值:
这是一种误导,因为水平轴通常是特征空间。我们将其压缩为带状图。
代码示例
本节提供了波士顿回归数据集和红酒分类数据集的可视化示例。您还可以查看示例可视化的完整库以及生成示例的代码。
以下是一个代码示例,用于加载Boston数据并训练最大深度为3的回归树:
boston= load_boston()
X_train= boston.data
y_train= boston.target
testX= X_train[5,:]
regr= tree.DecisionTreeRegressor(max_depth=3)
regr= regr.fit(X_train, y_train)
可视化树的代码包括树模型,训练数据,特征和目标名以及新样本(如果必要的话):
viz = dtreeviz(regr, X_train, y_train,target_name='price',
feature_names=boston.feature_names,
X =testX)
viz.save("boston.svg") # suffix determines thegenerated image format
viz.view() # pop up window to display image
这是一个代码案例,用于加载Wine数据并训练最大深度为3的分类树:
clf= tree.DecisionTreeClassifier(max_depth=3)
wine= load_wine()
clf.fit(wine.data,wine.target)
分类模型可视化与回归模型相同,但需要目标类名称:
viz= dtreeviz(clf, wine.data, wine.target, target_name='wine',
feature_names=wine.feature_names,
class_names=list(wine.target_names))
viz.view()
在Jupyter notebooks中,从dtreeviz()返回的对象具有_repr_svg_()函数,Jupyter使用该函数自动显示该对象。请参阅示例笔记本。
附链接:
https://github.com/parrt/dtreeviz/blob/master/notebooks/examples.ipynb
截至2018年9月,Jupyter notebooks无法正常显示此库生成的SVG,字体等会变得混乱:
好消息是github和JupyterLab可以正确地显示图像。
在Juypter notebooks中使用Image(viz.topng())的视觉效果较差;如果直接调用viz.view(),会弹出一个窗口,其中会恰当地显示结果。
实践经验
我们在这个项目中遇到了很多问题,编程错误、参数设置、解决bug和各种库的错误/限制以及如何更好地融合现有工具。唯一有趣的部分是可视化设计的无数次尝试。期待这个可视化会对机器学习社区有很大的帮助,这也是我们坚持不懈完成项目的动力。结合stackoverflow,文档和繁琐的图形编程,我们大概花了两个月的时间完成了这个项目。
最终我们使用matplotlib生成决策和叶节点的图像,并使用传统的graphviz将它们组合成树。我们还在graphviz树的描述中广泛使用了HTML标签,以用于布局和字体规范。但我们遇到的最大麻烦是将所有组件组合成高质量的矢量图形。
我们先创建了一个影子树,它包括了scikit创建的决策树,让我们开始吧。
scikit-learn的分类树和回归决策树是为提高效率而构建的,树的延伸或提取节点信息并不是重点。我们创建了dtreeviz.shadow.ShadowDecTree和dtreeviz.shadow.ShadowDecTreeNode类,以便于使用所有树信息(传统的二叉树)。以下是通过scikit分类树或回归树模型创建影子树的方法:
shadow_tree = ShadowDecTree(tree_model,X_train, y_train, feature_names, class_names)
影子树/节点类具有许多方法,这些方法还可以用于需要遍历scikit决策树的其他库。例如,predict()不仅可以运用树来预测新样本,而且还返回被访问节点的路径。可以通过node_samples()获得与任意特定节点关联的样本。
工具箱
如果能掌握所有技巧,Graphviz和dot语言有助于设计合理的树型布局,例如当子树重叠时,如何隐藏图象重叠的边缘。如果要在同一水平上显示两个叶节点leaf4和leaf5,我们可以用到graphviz如下:
LSTAT3-> leaf4 [penwidth=0.3 color="#444443" label=<>]
LSTAT3-> leaf5 [penwidth=0.3 color="#444443" label=<>]
{
rank=same;
leaf4-> leaf5 [style=invis]
}
我们通常在graphviz节点上使用HTML标签,而不仅仅是文本标签,因为它们能更好地控制文本显示,并将表格数据显示为实际表格。例如,当显示沿着树的测试向量时,使用HTML表显示测试向量:
为了从graphviz文件生成图像,我们使用graphvizpython软件包,该软件包最终是用程序例程之一(run())执行dot二进制可执行文件。有时,我们在dot命令上使用了略有不同的参数,因此我们可以更像这样更灵活地直接调用run():
cmd= ["dot", "-Tpng", "-o", filename, dotfilename]
stdout,stderr = run(cmd, capture_output=True, check=True, quiet=False)
我们还将使用run()函数来执行pdf2svg(PDF转SVG)工具,如下一节所述。
我们使用matplotlib生成决策和叶子节点,随后生成graphviz /dot图像和HTMLgraphviz标签,最终通过img标签引用生成的图像,如下所示:
94806数字是进程ID,它有利于独立运行同一台计算机的多个dtreeviz实例。否则,多个进程可能会覆盖相同的临时文件。
因为需要可缩放的矢量图形,我们先尝试着导入SVG图像,但无法通过graphviz插入这些文件(两者都不是pdf)。随后我们花了四个小时才发现生成和导入SVG是两件事,需要在OS X上使用--with-librsvg进行如下操作:
$brew install graphviz --with-librsvg --with-app --with-pango
最初,当我们想从matplotlib生成PNG文件时,我们将每英寸的点数(dpi)设置为450,这样它们在iMac这样高分辨率屏幕上能有不错的效果。不幸的是,这意味着我们必须使用
标签的width和height参数和graphviz中的HTML表来设定整个树的大小。这会带来很多问题,因为我们必须了解matplotlib得到的宽高比。使用SVG文件后,我们不必再了解SVG 文件在HTML中的具体大小;在撰写此文档时,我们意识到没有必要了解SVG文件的具体尺寸。
然而graphviz的SVG结果仅引用了我们导入的节点文件,而没有将节点图像嵌入到整个树形图像中。这是一种很不方便的形式,因为当发送可视化树时,我们要发送文件的zip而不是单个文件。我们花了一些时间解析SVG XML,并将所有引用的图像嵌入到单个大型meta-SVG文件中。有最终,得到了很好的效果。
然后我们注意到在生成SVG时,graphviz不能正确处理HTML标签中的文本。例如,分类树图例的文本会被切除并重叠。
为了获得独立SVG文件的工作,我们首先从graphviz生成PDF文件,然后使用pdf2svg将PDF转换为SVG(pdf2cairo也似乎起作用)。
我们注意到Jupyter notebook存在一个问题,它无法正确显示这些SVG文件(请参见上文)。Jupyterlab确实可以像github一样正确处理SVG。我们添加了一个topng()方法,这样Jupyter Notebook的用户就能使用Image(viz.topng())来获取嵌入式图像。还有一个跟好的方法,调用viz.view()将弹出一个窗口,也可以正确显示图像。
经验总结
有时解决编程问题与算法无关,而与编程语言的限制和功能有关,例如构建一个工具和库。决策树可视化软件也是这种类似的情况。编程并不难,我们是通过搭配适当的图形工具和库来得到最终的结果。
设计实际的可视化效果还需要进行无数次的实验和调整。生成高质量的矢量图还需要不断试错,对结果进行完善。
我们算不上可视化的狂热者,但是对于这个特定的问题,我们一直坚持了下来,才收获了理想的效果。在爱德华·塔夫特(Edward Tufte)的研讨会上,我了解到,只要不是随意的瞎搭配,我们就可以在人眼可以处理的限度下使用丰富的图表呈现大量的信息。
在这个项目中,我们使用了设计面板中的许多元素:颜色,线条粗细,线条样式,各种图,大小(区域,长度,图形高度,...),颜色透明度(alpha),文本样式(颜色,字体,粗体,斜体,大小),图形注释和视觉流程。所有视觉元素都发挥了相应的作用。例如,我们不能仅因为某一个颜色漂亮就使用它,而是要考虑到如何使用这个颜色来突出显示重要的维度(目标类别),因为人类能轻松且快速地发现颜色差异。节点大小的差异也应该很容易被人眼捕捉到,所以我们用节点的大小来表示叶子节点数据量的大小。
未来工作
本文档中描述的可视化内容是dtreeviz机器学习库的一部分,该库还处于起步阶段。我很快会将rfpimp库移至dtreeviz。到目前为止,我们只在OS X上测试过该工具。我们期待其他平台上的程序员提供更多执导,以便包括更丰富的安装步骤。
我们还在考虑几个细节的调整,例如使直方图和分类树底部对齐,会更利于比较节点。另外,某些三角形标签与轴标签重叠。最后,如果边缘宽度和子树中的样本量成比例就更好了(如SAS)。
原文标题:
How to visualize decision trees
原文链接:
https://explained.ai/decision-tree-viz/index.html
编辑:黄继彦
校对:林亦霖
译者简介
王雨桐 ,UIUC统计学在读硕士,本科统计专业,目前专注于Coding技能的提升。理论到应用的转换中,敬畏数据,持续进化。
翻译组招募信息
工作内容: 需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。
你能得到: 定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。
其他福利: 来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。
点击文末“阅读原文 ”加入数据派团队~
点击“阅读原文” 拥抱组织
你可能感兴趣的:(独家 | 全面!手把手教你决策树可视化(附链接&代码))
【人工智能】Python实战:构建高效的多任务学习模型
蒙娜丽宁
Python杂谈 AI 人工智能 python 学习
《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界多任务学习(Multi-taskLearning,MTL)作为机器学习领域中的一种重要方法,通过在单一模型中同时学习多个相关任务,不仅能够提高模型的泛化能力,还能有效利用任务间的共享信息。本文深入探讨了多任务学习的基本概念、优势及其在实际应用中的重要性。
2024年全国信息素养大赛图形化挑战赛国赛(决赛)真题——绘制20个多边形
嗨信奥
scratch 青少年编程
绘制20个多边形编程任务从三角形开始,递增边数,一次画出20个多边形。参数说明:1.画笔初始位置(-25,180),粗细为2;2.每个多边形的边长都是50;3.每画一个多边形,画笔要改变颜色。完整题目可点击下方链接:绘制20个多边形_scratch_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/scratch/show-3937.html程序演示及获取源码可
Python读取通达信日线数据(.day文件)
逝去的紫枫
Python python
Python读取通达信日线数据(.day文件)1.day文件位置2.day文件内容的构成3.Python代码识别day文件4.将识别结果输出为csv文件5.最终结果展示在金融数据分析中,通达信软件提供的数据文件(如日线数据文件.day)是非常宝贵的资源。本文将详细介绍如何使用Python读取和解析这些文件,并将解析结果输出为CSV文件,以便进行进一步的数据分析和处理。1.day文件位置通达信日线数
Android 内核开发之—— repo 使用教程
ByteSaid
Android 开发 android git
前言repo是一个用于管理多个Git仓库的工具,特别适用于管理大型项目如Android的源码。它是由Google开发的,用于解决多个Git仓库的同步、管理和代码审查等问题。因此,做Android内核开发,首先要了解repo是什么,它是如何使用的?1repo的概念repo是一种代码版本管理工具,它是由一系列的Python脚本组成,封装了一系列的Git命令,用来统一管理多个Git仓库。2repo的作用
Android AIDL 使用教程
ByteSaid
Android 开发 android ipc aidl
AIDL(AndroidInterfaceDefinitionLanguage)是一种IDL语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。通过AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法,从而满足进程间通信的需求。通常,暴露方法给其他应用进行调用的应用称为服务端,调用其他应用的方法的应用称为客户端,客户端通过绑定服务端的Service来
Mac安装JDK
FINAL_NO
Java基础 Mac JDK
1.JDK地址下载https://adoptopenjdk.net/?variant=openjdk8&jvmVariant=hotspot2.解决链接https://apple.stackexchange.com/questions/334384/how-can-i-install-java-openjdk-8-on-high-sierra3.方法安装最新版JDKbrewcaskinstalla
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
watermelo37
前端 # 数据结构 javascript vue.js 前端 算法 数据分析 数据挖掘
目录JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)一、什么时候该使用Array.map(),与forEach()的区别是什么?1、什么时候该用Array.map()2、Array.map()与Array.forEach()的区别二、Array.map()的使用与
分布式 IO 模块与伺服电机:拉丝机高效生产的 “黄金搭档”
明达技术
分布式
在工业生产领域,拉丝机的高效运作对于金属加工等众多行业至关重要。随着技术的不断进步,明达技术MR30分布式IO模块与伺服电机的协同应用,正为拉丝机带来前所未有的生产效率提升。高效协作,提升产能MR30分布式IO模块的分布式特性,使得它可以灵活地控制拉丝机的各个关键节点上,实现对设备的全面监控和控制。它与伺服电机紧密协作,能够快速响应生产过程中的各种变化。比如,当拉丝速度需要根据生产需求进行调整时,
手把手教你学simulink(83.2)--分布式能源场景实例:使用Simulink构建一个典型的光伏发电分布式能源系统模型
小蘑菇二号
simulink matlab
目录基于Simulink的分布式能源系统(DistributedEnergySystem,DES)项目实例背景介绍系统架构仿真实现步骤1.创建新的Simulink模型2.添加光伏发电模块模拟太阳能光伏板的输出功率在Simulink中实现光伏发电模块3.添加储能电池模块模拟储能电池的充放电过程在Simulink中实现储能电池模块4.添加负载模块模拟不同类型负载的需求5.添加电网连接模块模拟与主电网的
C++的STL库介绍及使用(初学者请食用)
陌晽叶吖
c++ 开发语言
C++STL(标准模板库)是C++中提供的一个强大而广泛的库,包含了多种常用的模板类和算法。对于初学者来说,掌握STL的基础是非常重要的,它能大大提高代码的效率和简洁性。下面是适用于C++STL库初学者的使用方法,涵盖了常用的容器、算法和迭代器等基本内容。1.STL容器STL容器是存储数据的类模板,常见的容器包括:Vector(向量)List(链表)Deque(双端队列)Map(映射)Set(集合
比亚迪进军具身智能:未来实验室的战略布局与挑战
前端
比亚迪,这家以新能源汽车闻名全球的企业,正在悄然布局一个全新的领域——具身智能及机器人技术。近日,比亚迪成立未来实验室的消息引发广泛关注,其战略意义和未来发展前景值得我们深入探讨。在人工智能技术飞速发展的今天,选择合适的AI写代码工具对于项目的成功至关重要。比亚迪未来实验室的战略意义:汽车基因与智能融合比亚迪进军机器人领域并非偶然之举。其深厚的汽车制造经验和规模化生产能力,为其在机器人研发方面奠定
苹果携手腾讯字节跳动:AI代码生成器赋能iPhone,开启移动智能新时代?
前端
近年来,人工智能技术飞速发展,其在移动设备上的应用也日益普及。近日,路透社爆料称苹果公司正在与腾讯和字节跳动商谈,计划将它们的AI模型整合到在中国销售的iPhone中,这一消息迅速引发了业界广泛关注。这不仅预示着苹果在AI领域的战略布局进一步深化,也标志着AI技术在移动设备应用领域迈入了一个新的里程碑。这篇文章将深入探讨苹果此举的意义、挑战以及对整个AI产业的影响。整合AI模型:机遇与挑战并存苹果
淘宝商品评价 API 的获取与应用
前端后端运维数据挖掘api
在电商领域,商品评价是消费者购买决策的重要依据,也是商家了解产品优缺点、优化服务的关键信息来源。对于开发者和电商从业者来说,能够获取淘宝商品评价数据,进行深入分析,具有极大的价值。淘宝商品评价API就提供了这样一个途径,通过该API可以获取到淘宝平台上各类商品的评价信息,从而为市场分析、竞品研究、店铺运营优化等提供有力支持。本文将详细介绍淘宝商品评价API的获取方法及实际应用,并附上代码示例,帮助
测试驱动开发的智能进化:AI代码生成的质量保证之路
前端
测试驱动开发(TDD)作为一种敏捷开发方法,强调在编写代码之前先编写测试用例,以确保代码的质量和可维护性。然而,在面对日益复杂的项目和快速迭代的需求时,传统的TDD方法也面临着诸多挑战,例如开发效率低下和代码质量保证难度大等问题。幸运的是,AI代码生成工具的出现为解决这些问题提供了新的思路和可能性,为TDD带来了智能化的进化。TDD的局限性:效率与质量的博弈传统TDD方法的核心流程是:先编写测试用
云鲸智能大裁员:AI代码生成器时代,企业如何应对寒冬?
前端
近日,云鲸智能大裁员的消息引发了行业震动,涉及研发、测试等多个部门,部分团队甚至裁员比例高达65%。这一事件不仅凸显了智能家电行业面临的挑战,也引发了人们对企业发展与员工权益的深思。本文将深入分析云鲸智能裁员事件,探讨其背后的原因、行业影响以及未来展望,并思考在AI代码生成器等新技术浪潮下,企业如何更好地应对挑战。事件分析:寒冬下的无奈之举?云鲸智能此次裁员规模巨大,受影响员工涵盖老员工、应届生和
设计模式概述 - 设计模式的重要性
w(゚Д゚)w吓洗宝宝了
C++从 0 到 1 设计模式 c++
引言设计模式是软件工程中用于解决常见设计问题的经典解决方案。它们提供了一种标准化的方式来组织和设计代码,使得代码更易于理解、维护和扩展。在C++编程中,设计模式尤为重要,因为它们可以帮助开发者应对复杂的系统设计,提高代码的可重用性和灵活性。本文将探讨设计模式的基本概念、分类以及它们在C++中的重要性。1.什么是设计模式?设计模式是经过验证的、可重用的解决方案,用于解决在软件设计中反复出现的问题。它
零售业的AI赋能与前端开发效率革命:ScriptEcho 的助力
前端
零售业正经历着前所未有的数字化转型,但同时也面临着巨大的挑战。库存管理混乱、个性化客户体验不足等问题,严重制约着零售企业的盈利能力。而人工智能(AI)的兴起,为解决这些问题提供了新的思路。通过AI驱动的实时库存管理和客户行为分析,零售企业可以显著提升运营效率和客户满意度。然而,构建这些AI赋能的零售应用,需要强大的前端开发能力,这正是AI代码生成器ScriptEcho能够发挥关键作用的地方。AI赋
自学记录:用鸿蒙API 13 开发一个专业的进度条与二维码组件
harmonyos-next
这篇文章,我会结合自己的学习故事,讲解如何使用API13的全新能力,打造一个进度条和二维码展示组件,并以实际开发项目作为成果展示。我的学习路线:从文档到实践如果正在看的同学如果你不了解鸿蒙,那么我简单说一下,鸿蒙目前需要使用ArkUI配合ArkTS进行开发。它们不仅支持声明式开发,还通过DSL(领域专用语言)的设计,使代码更高效、模块化。于是,我们从以下几点展开学习:了解进度条与二维码组件的能力\
JAVA:Spring Boot 实现责任链模式处理订单流程的技术指南
拾荒的小海螺
JAVA java spring boot 责任链模式
1、简述在复杂的业务系统中,订单流程往往需要一系列的操作,比如验证订单、检查库存、处理支付、更新订单状态等。责任链模式(ChainofResponsibility)可以帮助我们将这些处理步骤分开,并且以链式方式处理每一个操作,从而让代码更加清晰、可扩展和模块化。本文将介绍如何在SpringBoot3.3中使用责任链模式实现订单流程管理。2、场景设计责任链模式是一种行为设计模式,它通过将请求沿着处理
Python读取通达信一分钟K线数据(.lc1文件)
逝去的紫枫
Python python
Python读取通达信一分钟K线数据(.lc1文件)1.lc1文件位置2.lc1文件内容的构成3.Python代码识别lc1文件4.将识别结果输出为csv文件5.最终结果展示在金融数据分析中,通达信软件提供的数据文件(如1分钟K线数据文件.lc1)是非常宝贵的资源。本文将详细介绍如何使用Python读取和解析这些文件,并将解析结果输出为CSV文件,以便进行进一步的数据分析和处理。1.lc1文件位置
python graphviz 中文乱码
晓梦OvO
python 决策树
问题:在调用graphviz库进行决策树绘图的时候,即使我们设置了fontname='SimHei',encoding='utf-8',我们同样会发现出现了中文乱码的情况fromgraphvizimportDigraphdot=Digraph('决策树',encoding='utf-8')dot.attr(fontname='SimHei',encoding='utf-8')#改为系统中的中文字体
摆脱“鱼钩”:误点网络钓鱼链接后的10步自救法
网络安全
拼写错误、奇怪的语法、紧急或威胁的语言、缺乏上下文——所有这些都是网络钓鱼攻击的常见特征。然而,一些精心布局的网络钓鱼威胁通常很难被发现,因为它们往往涉及攻击者的大量时间投入以及详尽细致的计划,他们甚至会仔细检查目标过去的通信,以增加攻击成功的可能性。在大规模欺诈活动中,骗子常用的一种策略是利用当前的热门事件。例如,一封看似来自英国国家卫生服务机构提供免费COVID-19检测的电子邮件,实际上是一
科技早报|OpenAI的人工智能模型销售收入超过微软类似业务;荣耀中国区CMO辟谣将采用麒麟芯片 | 最新快讯
最新科技快讯
科技 人工智能 microsoft
科大讯飞新模型在测试集结果中超越GPT-4Turbo6月27日,科大讯飞发布讯飞星火大模型V4.0。与此前的版本相比,新模型在文本生成、语言理解、知识问答、逻辑推理、数学能力、代码能力、多模态能力等七大能力上都有提升。例如,讯飞星火可以根据用户的语言描述,结合空间和常识推断描述对象所在的位置。而在图文识别上,讯飞星火大模型V4.0能力也进一步升级,在科研、金融、医疗、司法、办公等场景的应用效果已领
玩转至轻云大数据平台-docker部署篇
fanciNate454
大数据 docker
产品介绍至轻云是一款超轻量级、企业级大数据计算平台,基于Spark生态打造。一键部署,开箱即用。快速实现大数据离线ETL、Spark计算、实时计算、可视化调度、自定义接口、数据大屏以及自定义表单等多种功能,为企业提供高效便捷的大数据解决方案。至轻云有什么特点呢?又能怎么玩呢?产品特点开源轻量化云原生架构:兼容云原生架构,支持Docker、Rancher平台的快速部署。国内镜像下载:可直接从阿里云镜
YOLOv10全网最新创新点改进系列:YOLOv10融合SwinTransformer模块,分辨率每层变成一半,而通道数变成两倍,有效提升小目标检测效果!
AI棒棒牛
YOLO 目标检测 人工智能 模型改进 yolov10 创新 sci写作
YOLOv10全网最新创新点改进系列:YOLOv10融合SwinTransformer模块,分辨率每层变成一半,而通道数变成两倍,有效提升小目标检测效果!所有改进代码均经过实验测试跑通!截止发稿时YOLOv10已改进40+!自己排列组合2-4种后,考虑位置不同后可排列组合上千万种!改进不重样!!专注AI学术,关注B站up主:Ai学术叫叫兽er!购买相关资料后畅享一对一答疑!YOLOv10全网最新创
DeepSeek:极致的中国技术理想
X_taiyang18
AI与机器学习 人工智能
揭秘DeepSeek:一个更极致的中国技术理想主义故事划重点中国的大模型创业公司DeepSeek因其创新的MLA架构和DeepSeekMoESparse结构,使推理成本降低至每百万token仅1块钱,引发中国大模型价格战。与其他大公司烧钱补贴不同,DeepSeek是有利润的,背后是DeepSeek对模型架构的全面创新。DeepSeek创始人梁文锋认为,中国的大模型创业者除应用创新外,也可以加入到全
AI编程,不会使用提示词,那怎么能行!! 小南独家提示词书写技巧, 让你效率提高2倍!!! - 提示词第一课!!!!
小南AI学院
AI JAVA 前端 AI编程
0.前言这是提示词第一课程,未来还有cursor、Copilot、通义千问、MarsCode的实战。关注、收藏不迷路。麻烦点个赞吧。小南持续为大家1.如何写提示词编写有效提示词是高效使用AI编程软件的关键。下面介绍一些方法和技巧,帮助你更精准地引导模型生成所需内容。1.1明确角色将AI编程软件设定为特定领域的专家角色,有助于生成更专业、更贴合实际需求的内容。示例:“你是一位经验丰富的Java后端开
第4篇:使用ChatterBot构建基本聊天机器人
Python测试之道
聊天机器人 机器人 人工智能
在这一篇文章中,我们将实际构建一个简单的聊天机器人,展示如何使用ChatterBot库进行基本的对话交互。我们将集中讨论代码实现,并介绍一些有用的功能扩展。4.1创建聊天机器人4.1.1编写聊天机器人代码首先,创建一个新的Python文件,例如chatbot.py,并输入以下代码:fromchatterbotimportChatBotfromchatterbot.trainersimportLis
百度AI战略与2025年AI应用井喷:AI代码生成器ScriptEcho如何助力前端开发
前端
2025年,百度创始人李彦宏在百度25周年全员信中预言:AI应用将在2025年井喷式增长。这预示着AI技术将迎来一个新的发展高峰,同时也为前端开发者带来了前所未有的机遇和挑战。面对AI应用的快速发展,如何提升前端开发效率,降低开发成本,成为摆在开发者面前的难题。本文将探讨百度AI战略下前端开发面临的挑战,并重点介绍AI代码生成器ScriptEcho如何助力开发者迎接2025年AI应用井喷的浪潮。百
AI赋能软件国际化:ScriptEcho如何提升开发效率
前端
在全球化的今天,软件国际化(i18n)已不再是锦上添花,而是软件能否成功走向国际市场的关键因素。一个成功的软件产品需要能够适应不同的语言、文化和地区,为全球用户提供一致且本地化的体验。然而,实现i18n并非易事,它面临着诸多挑战,例如多语言支持的巨大工作量、对不同地区文化习俗的适配,以及由此带来的开发效率低下等问题。为了解决这些问题,越来越多的开发者开始寻求AIAI代码生成器的帮助。AI赋能软件国
Spring的注解积累
yijiesuifeng
spring 注解
用注解来向Spring容器注册Bean。
需要在applicationContext.xml中注册:
<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。
如:在base-package指明一个包
<context:component-sc
传感器
百合不是茶
android 传感器
android传感器的作用主要就是来获取数据,根据得到的数据来触发某种事件
下面就以重力传感器为例;
1,在onCreate中获得传感器服务
private SensorManager sm;// 获得系统的服务
private Sensor sensor;// 创建传感器实例
@Override
protected void
[光磁与探测]金吕玉衣的意义
comsci
这是一个古代人的秘密:现在告诉大家
信不信由你们:
穿上金律玉衣的人,如果处于灵魂出窍的状态,可以飞到宇宙中去看星星
这就是为什么古代
精简的反序打印某个数
沐刃青蛟
打印
以前看到一些让求反序打印某个数的程序。
比如:输入123,输出321。
记得以前是告诉你是几位数的,当时就抓耳挠腮,完全没有思路。
似乎最后是用到%和/方法解决的。
而今突然想到一个简短的方法,就可以实现任意位数的反序打印(但是如果是首位数或者尾位数为0时就没有打印出来了)
代码如下:
long num, num1=0;
PHP:6种方法获取文件的扩展名
IT独行者
PHP 扩展名
PHP:6种方法获取文件的扩展名
1、字符串查找和截取的方法
1
$extension
=
substr
(
strrchr
(
$file
,
'.'
), 1);
2、字符串查找和截取的方法二
1
$extension
=
substr
面试111
文强chu
面试
1事务隔离级别有那些 ,事务特性是什么(问到一次)
2 spring aop 如何管理事务的,如何实现的。动态代理如何实现,jdk怎么实现动态代理的,ioc是怎么实现的,spring是单例还是多例,有那些初始化bean的方式,各有什么区别(经常问)
3 struts默认提供了那些拦截器 (一次)
4 过滤器和拦截器的区别 (频率也挺高)
5 final,finally final
XML的四种解析方式
小桔子
dom jdom dom4j sax
在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 预 备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server
wordpress中常见的操作
aichenglong
中文注册 wordpress 移除菜单
1 wordpress中使用中文名注册解决办法
1)使用插件
2)修改wp源代码
进入到wp-include/formatting.php文件中找到
function sanitize_user( $username, $strict = false
小飞飞学管理-1
alafqq
管理
项目管理的下午题,其实就在提出问题(挑刺),分析问题,解决问题。
今天我随意看下10年上半年的第一题。主要就是项目经理的提拨和培养。
结合我自己经历写下心得
对于公司选拔和培养项目经理的制度有什么毛病呢?
1,公司考察,选拔项目经理,只关注技术能力,而很少或没有关注管理方面的经验,能力。
2,公司对项目经理缺乏必要的项目管理知识和技能方面的培训。
3,公司对项目经理的工作缺乏进行指
IO输入输出部分探讨
百合不是茶
IO
//文件处理 在处理文件输入输出时要引入java.IO这个包;
/*
1,运用File类对文件目录和属性进行操作
2,理解流,理解输入输出流的概念
3,使用字节/符流对文件进行读/写操作
4,了解标准的I/O
5,了解对象序列化
*/
//1,运用File类对文件目录和属性进行操作
//在工程中线创建一个text.txt
getElementById的用法
bijian1013
element
getElementById是通过Id来设置/返回HTML标签的属性及调用其事件与方法。用这个方法基本上可以控制页面所有标签,条件很简单,就是给每个标签分配一个ID号。
返回具有指定ID属性值的第一个对象的一个引用。
语法:
&n
励志经典语录
bijian1013
励志 人生
经典语录1:
哈佛有一个著名的理论:人的差别在于业余时间,而一个人的命运决定于晚上8点到10点之间。每晚抽出2个小时的时间用来阅读、进修、思考或参加有意的演讲、讨论,你会发现,你的人生正在发生改变,坚持数年之后,成功会向你招手。不要每天抱着QQ/MSN/游戏/电影/肥皂剧……奋斗到12点都舍不得休息,看就看一些励志的影视或者文章,不要当作消遣;学会思考人生,学会感悟人生
[MongoDB学习笔记三]MongoDB分片
bit1129
mongodb
MongoDB的副本集(Replica Set)一方面解决了数据的备份和数据的可靠性问题,另一方面也提升了数据的读写性能。MongoDB分片(Sharding)则解决了数据的扩容问题,MongoDB作为云计算时代的分布式数据库,大容量数据存储,高效并发的数据存取,自动容错等是MongoDB的关键指标。
本篇介绍MongoDB的切片(Sharding)
1.何时需要分片
&nbs
【Spark八十三】BlockManager在Spark中的使用场景
bit1129
manager
1. Broadcast变量的存储,在HttpBroadcast类中可以知道
2. RDD通过CacheManager存储RDD中的数据,CacheManager也是通过BlockManager进行存储的
3. ShuffleMapTask得到的结果数据,是通过FileShuffleBlockManager进行管理的,而FileShuffleBlockManager最终也是使用BlockMan
yum方式部署zabbix
ronin47
yum方式部署zabbix
安装网络yum库#rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch.rpm 通过yum装mysql和zabbix调用的插件还有agent代理#yum install zabbix-server-mysql zabbix-web-mysql mysql-
Hibernate4和MySQL5.5自动创建表失败问题解决方法
byalias
J2EE Hibernate4
今天初学Hibernate4,了解了使用Hibernate的过程。大体分为4个步骤:
①创建hibernate.cfg.xml文件
②创建持久化对象
③创建*.hbm.xml映射文件
④编写hibernate相应代码
在第四步中,进行了单元测试,测试预期结果是hibernate自动帮助在数据库中创建数据表,结果JUnit单元测试没有问题,在控制台打印了创建数据表的SQL语句,但在数据库中
Netty源码学习-FrameDecoder
bylijinnan
java netty
Netty 3.x的user guide里FrameDecoder的例子,有几个疑问:
1.文档说:FrameDecoder calls decode method with an internally maintained cumulative buffer whenever new data is received.
为什么每次有新数据到达时,都会调用decode方法?
2.Dec
SQL行列转换方法
chicony
行列转换
create table tb(终端名称 varchar(10) , CEI分值 varchar(10) , 终端数量 int)
insert into tb values('三星' , '0-5' , 74)
insert into tb values('三星' , '10-15' , 83)
insert into tb values('苹果' , '0-5' , 93)
中文编码测试
ctrain
编码
循环打印转换编码
String[] codes = {
"iso-8859-1",
"utf-8",
"gbk",
"unicode"
};
for (int i = 0; i < codes.length; i++) {
for (int j
hive 客户端查询报堆内存溢出解决方法
daizj
hive 堆内存溢出
hive> select * from t_test where ds=20150323 limit 2;
OK
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
问题原因: hive堆内存默认为256M
这个问题的解决方法为:
修改/us
人有多大懒,才有多大闲 (评论『卓有成效的程序员』)
dcj3sjt126com
程序员
卓有成效的程序员给我的震撼很大,程序员作为特殊的群体,有的人可以这么懒, 懒到事情都交给机器去做 ,而有的人又可以那么勤奋,每天都孜孜不倦得做着重复单调的工作。
在看这本书之前,我属于勤奋的人,而看完这本书以后,我要努力变成懒惰的人。
不要在去庞大的开始菜单里面一项一项搜索自己的应用程序,也不要在自己的桌面上放置眼花缭乱的快捷图标
Eclipse简单有用的配置
dcj3sjt126com
eclipse
1、显示行号 Window -- Prefences -- General -- Editors -- Text Editors -- show line numbers
2、代码提示字符 Window ->Perferences,并依次展开 Java -> Editor -> Content Assist,最下面一栏 auto-Activation
在tomcat上面安装solr4.8.0全过程
eksliang
Solr solr4.0后的版本安装 solr4.8.0安装
转载请出自出处:
http://eksliang.iteye.com/blog/2096478
首先solr是一个基于java的web的应用,所以安装solr之前必须先安装JDK和tomcat,我这里就先省略安装tomcat和jdk了
第一步:当然是下载去官网上下载最新的solr版本,下载地址
Android APP通用型拒绝服务、漏洞分析报告
gg163
漏洞 android APP 分析
点评:记得曾经有段时间很多SRC平台被刷了大量APP本地拒绝服务漏洞,移动安全团队爱内测(ineice.com)发现了一个安卓客户端的通用型拒绝服务漏洞,来看看他们的详细分析吧。
0xr0ot和Xbalien交流所有可能导致应用拒绝服务的异常类型时,发现了一处通用的本地拒绝服务漏洞。该通用型本地拒绝服务可以造成大面积的app拒绝服务。
针对序列化对象而出现的拒绝服务主要
HoverTree项目已经实现分层
hvt
编程 .net Web C# ASP.ENT
HoverTree项目已经初步实现分层,源代码已经上传到 http://hovertree.codeplex.com请到SOURCE CODE查看。在本地用SQL Server 2008 数据库测试成功。数据库和表请参考:http://keleyi.com/a/bjae/ue6stb42.htmHoverTree是一个ASP.NET 开源项目,希望对你学习ASP.NET或者C#语言有帮助,如果你对
Google Maps API v3: Remove Markers 移除标记
天梯梦
google maps api
Simply do the following:
I. Declare a global variable:
var markersArray = [];
II. Define a function:
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++ )
jQuery选择器总结
lq38366
jquery 选择器
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 31 32 33 34 35 36 37 38 39 40
基础数据结构和算法六:Quick sort
sunwinner
Algorithm Quicksort
Quick sort is probably used more widely than any other. It is popular because it is not difficult to implement, works well for a variety of different kinds of input data, and is substantially faster t
如何让Flash不遮挡HTML div元素的技巧_HTML/Xhtml_网页制作
刘星宇
html Web
今天在写一个flash广告代码的时候,因为flash自带的链接,容易被当成弹出广告,所以做了一个div层放到flash上面,这样链接都是a触发的不会被拦截,但发现flash一直处于div层上面,原来flash需要加个参数才可以。
让flash置于DIV层之下的方法,让flash不挡住飘浮层或下拉菜单,让Flash不档住浮动对象或层的关键参数:wmode=opaque。
方法如下:
Mybatis实用Mapper SQL汇总示例
wdmcygah
sql mysql mybatis 实用
Mybatis作为一个非常好用的持久层框架,相关资料真的是少得可怜,所幸的是官方文档还算详细。本博文主要列举一些个人感觉比较常用的场景及相应的Mapper SQL写法,希望能够对大家有所帮助。
不少持久层框架对动态SQL的支持不足,在SQL需要动态拼接时非常苦恼,而Mybatis很好地解决了这个问题,算是框架的一大亮点。对于常见的场景,例如:批量插入/更新/删除,模糊查询,多条件查询,联表查询,