【问题标题】:FileNotFoundError rendering decision tree with CHAIDFileNotFoundError 使用 CHAID 渲染决策树
【发布时间】:2020-04-24 23:56:59
【问题描述】:

我用下面的代码得到了CHAID的决策树

independent_variable_columns = ['gender', 'grade', 'no_renewals', 'complaint_count']
dep_variable = 'switch'
tree = Tree.from_pandas_df(
    df,
    dict(zip(independent_variable_columns, ['nominal'] * 38)),
    dep_variable,
    max_depth=2
)
tree.to_tree()
tree.render()

但我收到以下错误

  File "C:\Users\data\AppData\Local\Continuum\anaconda3\lib\site-packages\CHAID\graph.py", line 93, in <listcomp>
    [os.remove(file) for file in self.files]
FileNotFoundError: [WinError 3] The system cannot find the path specified: '/tmp/157840175993116164207458496094.png'

【问题讨论】:

标签: python decision-tree


【解决方案1】:

在生成文件名和处理临时文件时,该特定库没有实施最佳实践。这使得他们的代码在 Windows 上以多种方式中断。

我已在 similar issue with the same root cause 上发表评论,提出修改以解决这些问题。

您可以通过运行以下代码在本地解决此问题:

import os
from datetime import datetime
from tempfile import TemporaryDirectory

import plotly.io as pio
import colorlover as cl
from graphviz import Digraph

from CHAID import graph

def Graph_render(self, path, view):
    if path is None:
        path = os.path.join("trees", f"{datetime.now():%Y-%m-%d %H:%M:%S}.gv")
    with TemporaryDirectory() as self.tempdir:
        g = Digraph(
            format="png",
            graph_attr={"splines": "ortho"},
            node_attr={"shape": "plaintext", "labelloc": "b"},
        )
        for node in self.tree:
            image = self.bar_chart(node)
            g.node(str(node.node_id), image=image)
            if node.parent is not None:
                edge_label = f"     ({', '.join(map(str, node.choices))})     \n ")
                g.edge(str(node.parent), str(node.node_id), xlabel=edge_label)

        g.render(path, view=view)

def Graph_bar_chart(self, node):
    fig = {
        "data": [
            {
                "values": list(node.members.values()),
                "labels": list(node.members),
                "showlegend": node.node_id == 0,
                "domain": {"x": [0, 1], "y": [0.4, 1.0]},
                "hole": 0.4,
                "type": "pie",
                "marker_colors": cl.scales["5"]["qual"]["Set1"],
            },
        ],
        "layout": {
            "margin_t": 50,
            "annotations": [{"font_size": 18, "x": 0.5, "y": 0.5}, {"y": [0, 0.2]}],
        },
    }

    if not node.is_terminal:
        p = None if node.p is None else format(node.p, ".5f")
        score = None if node.score is None else format(node.score, ".2f")
        self.append_table(fig, [p, score, node.split.column])

    filename = os.path.join(self.tempdir, f"node-{node.node_id}.png")
    pio.write_image(fig, file=filename, format="png")
    return filename

graph.Graph.render = Graph_render
graph.Graph.bar_chart = Graph_bar_chart

以上是该库中Graph 类的两个方法的重构,切换到使用tempdir.TemporaryDirectory() 处理临时文件,并清理文件名的生成方式。我还冒昧地清理了代码中的一些小问题。

我已经把它变成了pull request to update the project itself

【讨论】:

  • 感谢您的回复。我收到以下错误。PermissionError: [WinError 32] 该进程无法访问该文件,因为它正在被另一个进程使用:'C:\\Users\\RANJIT~1.PS\\AppData\\Local\\Temp \\tmpmbv62ah1\\tmp4ld852us.png'
  • 我删除了临时文件并重新启动,但还是一样。请帮我解决这个问题。
  • @ran_search:我已将我的答案与更新的拉取请求同步;对图像文件使用 mkstemp() 太过分了,会导致 Windows 出现问题。
  • 如何传递源自 CHAID 决策树的点文件以创建具有以下格式的树形图
  • @ran_search 这是一个完全不同的问题,可能需要另一个帖子。 CHAID 输出一个Graphviz dot file,带有每个节点的图像以可视化值的分布(包括饼图和表格)。图像本身在将它们合并到图形的 PNG 渲染后再次被删除,因此输出文本文件本身相当无用。如果要创建不同的图形,最好使用树本身的数据。我从来没有这样做过,现在也没有时间弄清楚。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2016-12-14
  • 2018-09-06
  • 2018-07-24
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多