Orange-Data-Mining数据挖掘工具widgets组件开发(一)

官网网站:

https://github.com/biolab/orange3

https://orangedatamining.com/

orange是一款开源的数据挖掘工具,采用Python+QT技术栈,可实现非监督学习、监督学习、频谱分析等应用场景。

我想开发一个组件widget,加入自定义的数据挖掘算法与可视化分析功能。

一、环境配置

环境配置方面,我不准备独立安装conda,因为经过我观察,orange安装后的目录下,自带了conda环境,所以个人计划直接使用。

PS:也可以自己安装环境,文档见README-dev.md,依赖方面安装源代码中的requirements.txt。

1.1 下载并安装orange

下载链接:https://orangedatamining.com/download/#windows

下载安装exe后,直接双击正常安装即可。

安装后,桌面图标如下:

打开Orange默认安装目录:C:\Users\xxxx\AppData\Local\Programs\Orange

可以看到内部有完整的python运行环境。

1.2 orange启动分析

查看orange启动命令,可以 看到orange实际启动命令为:

C:\Users\xxx\AppData\Local\Programs\Orange\pythonw.exe -s -m Orange.canvas

pythonw.exe -m 直接启动了Orange.canvas包。

查看Lib\site-packages\Orange 即可看到,安装的orange实际上就是一个标准python环境+Orange+AnyQt+其它包。

1.3 源代码下载

https://github.com/biolab/orange3

github下载最新源代码后,采用VS Code打开。

1.4 文档编译

可以看到doc代码说明文档与orange源代码文件。

下载安装Sphinx后,可以直接make html编译出data-mining-library、development、visual-programming 用户文档。

编译后的doc目录如下,index.html帮助文档,可以直接用浏览器打开。

浏览器浏览文档如下:

1.5 demo组件测试

参考文档:/doc/development/build/html/tutorial.html#a-demo-package

参考以上文档,在VS Code建立插件项目,目录如下:

1.5.2 demo widget组件安装

过程见下:

  1. 关闭orange;
  2. 进入插件开发目录;
  3. 执行安装包命令:
C:\Users\think\AppData\Local\Programs\Orange\python.exe -m pip install -e .

1.5.3 测试组件

打开orange,后查看组件:

1.5.4 单元测试

每个调试组件,都需要安装到orange内,太恼火了。orange官网文档中有教程,教我们独立运行的方案。

代码中添加测试代码:

VS Code Python库目录 ,选择orange安装 目录:

直接单独文件直接运行:

分步单步调试运行:

完整的demo组件代码。(其他代码都是通用代码,直接看官网文档即可)

import sys
import numpy

import Orange.data
from Orange.widgets import widget, gui
from Orange.widgets.utils.signals import Input, Output


class OWDataSamplerA(widget.OWWidget):
    name = "Data Sampler3"
    description = "Randomly selects a subset of instances from the data set"
    icon = "icons/DataSamplerA.svg"
    priority = 10

    class Inputs:
        data = Input("Data", Orange.data.Table)

    class Outputs:
        sample = Output("Sampled Data", Orange.data.Table)

    want_main_area = False

    def __init__(self):
        super().__init__()

        # GUI
        box = gui.widgetBox(self.controlArea, "Info")
        self.infoa = gui.widgetLabel(
            box, "No data on input yet, waiting to get something.")
        self.infob = gui.widgetLabel(box, '')
    @Inputs.data
    def set_data(self, dataset):
        if dataset is not None:
            self.infoa.setText("%d instances in input data set" % len(dataset))
            indices = numpy.random.permutation(len(dataset))
            indices = indices[:int(numpy.ceil(len(dataset) * 0.1))]
            sample = dataset[indices]
            self.infob.setText("%d sampled instances" % len(sample))
            self.Outputs.sample.send(sample)
        else:
            self.infoa.setText(
                "No data on input yet, waiting to get something.")
            self.infob.setText('')
            self.Outputs.sample.send(None)

def main(argv=sys.argv):
    from AnyQt.QtWidgets import QApplication
    app = QApplication(list(argv))
    args = app.arguments()
    if len(args) > 1:
        filename = args[1]
    else:
        filename = "iris"

    ow = OWDataSamplerA()
    ow.show()
    ow.raise_()

    dataset = Orange.data.Table(filename)
    ow.set_data(dataset)
    ow.handleNewSignals()
    app.exec_()
    ow.set_data(None)
    ow.handleNewSignals()
    return 0


if __name__ == "__main__":
    sys.exit(main())