source: orange/Orange/OrangeWidgets/Regression/OWSVMRegression.py @ 9671:a7b056375472

Revision 9671:a7b056375472, 10.1 KB checked in by anze <anze.staric@…>, 2 years ago (diff)

Moved orange to Orange (part 2)

Line 
1# coding=utf-8
2"""
3<name>SVM Regression</name>
4<description>Support Vector Machine Regression.</description>
5<icon>icons/BasicSVM.png</icon>
6<contact>Ales Erjavec (ales.erjavec(@at@)fri.uni-lj.si)</contact>
7<priority>100</priority>
8<keywords>Support, Vector, Machine, Regression</keywords>
9
10"""
11
12import orngSVM
13
14from OWSVM import *
15
16import Orange
17from Orange.classification import svm
18
19class OWSVMRegression(OWSVM):
20    def __init__(self, parent=None, signalManager=None, title="SVM Regression"):
21        OWWidget.__init__(self, parent, signalManager, title, wantMainArea=False)
22       
23        self.inputs=[("Data", Orange.data.Table, self.setData), 
24                     ("Preprocess", PreprocessedLearner, self.setPreprocessor)]
25       
26        self.outputs=[("Learner", orange.Learner, Default),
27                      ("Predictor", orange.Classifier, Default),
28                      ("Support Vectors", Orange.data.Table)]
29
30        ##########
31        # Settings
32        ##########
33        self.kernel_type = 2
34        self.gamma = 0.0
35        self.coef0 = 0.0
36        self.degree = 3
37        self.C = 1.0
38        self.p = 0.1
39        self.eps = 1e-3
40        self.nu = 0.5
41        self.shrinking = 1
42        self.probability=1
43        self.useNu=0
44        self.nomogram=0
45        self.normalization=1
46        self.data = None
47        self.selFlag=False
48        self.preprocessor = None
49        self.name = "SVM Regression"
50       
51        self.loadSettings()
52
53       
54        OWGUI.lineEdit(self.controlArea, self, 'name', box='Learner/predictor Name',
55                       tooltip='Name to be used by other widgets to identify your learner/predictor.')
56        OWGUI.separator(self.controlArea)
57
58        b = OWGUI.radioButtonsInBox(self.controlArea, self, "useNu", [], 
59                                    box="SVM Type", 
60                                    orientation = QGridLayout(), 
61                                    addSpace=True)
62       
63        # Epsilon SVR
64        b.layout().addWidget(OWGUI.appendRadioButton(b, self, 
65                                                "useNu", u"ε-SVR",
66                                                tooltip="Epsilon SVR",
67                                                addToLayout=False),
68                             0, 0, Qt.AlignLeft)
69       
70        b.layout().addWidget(QLabel("Cost (C)", b), 0, 1, Qt.AlignRight)
71        b.layout().addWidget(OWGUI.doubleSpin(b, self, "C", 0.5, 512.0, 0.5, 
72                          addToLayout=False, 
73                          callback=lambda *x: self.setType(0), 
74                          alignment=Qt.AlignRight,
75                          tooltip="Cost for out of epsilon training points."),
76                          0, 2)
77       
78        b.layout().addWidget(QLabel(u"Loss Epsilon (ε)", b), 1, 1, Qt.AlignRight)
79        b.layout().addWidget(OWGUI.doubleSpin(b, self, "p", 0.05, 1.0, 0.05,
80                                      addToLayout=False,
81                                      callback=lambda *x: self.setType(0),
82                                      alignment=Qt.AlignRight,
83                                      tooltip="Epsilon bound (all points inside this interval are not penalized)."
84                                      ),
85                             1, 2)
86       
87        # Nu SVR
88        b.layout().addWidget(OWGUI.appendRadioButton(b, self, 
89                                                "useNu", u"ν-SVR",
90                                                tooltip="Nu SVR",
91                                                addToLayout=False),
92                             2, 0, Qt.AlignLeft)
93       
94        b.layout().addWidget(QLabel("Cost (C)", b), 
95                             2, 1, Qt.AlignRight)
96        b.layout().addWidget(OWGUI.doubleSpin(b, self, "C", 0.5, 512.0, 0.5, 
97                        addToLayout=False, 
98                        callback=lambda *x: self.setType(0), 
99                        alignment=Qt.AlignRight,
100                        tooltip="Cost for out of epsilon training points."),
101                        2, 2)
102       
103        b.layout().addWidget(QLabel(u"Complexity bound (\u03bd)", b),
104                             3, 1, Qt.AlignRight)
105        b.layout().addWidget(OWGUI.doubleSpin(b, self, "nu", 0.1, 1.0, 0.1,
106                        tooltip="Lower bound on the ratio of support vectors",
107                        addToLayout=False, 
108                        callback=lambda *x: self.setType(1), 
109                        alignment=Qt.AlignRight),
110                        3, 2)
111       
112        # Kernel
113        self.kernelBox=b = OWGUI.widgetBox(self.controlArea, "Kernel")
114        self.kernelradio = OWGUI.radioButtonsInBox(b, self, "kernel_type", 
115                                btnLabels=[u"Linear,   x∙y", 
116                                           u"Polynomial,   (g x∙y + c)^d",
117                                           u"RBF,   exp(-g|x-y|²)", 
118                                           u"Sigmoid,   tanh(g x∙y + c)"],
119                                callback=self.changeKernel)
120
121        OWGUI.separator(b)
122        self.gcd = OWGUI.widgetBox(b, orientation="horizontal")
123        self.leg = OWGUI.doubleSpin(self.gcd, self, "gamma", 0.0, 10.0, 0.0001,
124                                    label="  g: ", orientation="horizontal",
125                                    callback=self.changeKernel, 
126                                    alignment=Qt.AlignRight)
127       
128        self.led = OWGUI.doubleSpin(self.gcd, self, "coef0", 0.0, 10.0, 0.0001,
129                                    label="  c: ", orientation="horizontal", 
130                                    callback=self.changeKernel, 
131                                    alignment=Qt.AlignRight)
132       
133        self.lec = OWGUI.doubleSpin(self.gcd, self, "degree", 0.0,10.0,0.5, 
134                                    label="  d: ", orientation="horizontal", 
135                                    callback=self.changeKernel, 
136                                    alignment=Qt.AlignRight)
137
138        OWGUI.separator(self.controlArea)
139       
140        self.optionsBox=b=OWGUI.widgetBox(self.controlArea, "Options", addSpace=True)
141       
142        OWGUI.doubleSpin(b,self, "eps", 0.0005, 1.0, 0.0005, 
143                         label=u"Numerical tolerance", 
144                         labelWidth = 180, 
145                         orientation="horizontal",
146                         tooltip="Numerical tolerance of termination criterion.", 
147                         alignment=Qt.AlignRight)
148
149        OWGUI.checkBox(b, self, "normalization", 
150                       label="Normalize data", 
151                       tooltip="Use data normalization")
152
153        self.paramButton = OWGUI.button(self.controlArea, self,
154                                         "Automatic parameter search", 
155                                         callback=self.parameterSearch,
156                                         tooltip="Automatically searches for parameters that optimize classifier accuracy", 
157                                         debuggingEnabled=0)
158       
159        self.paramButton.setDisabled(True)
160
161        OWGUI.button(self.controlArea, self,"&Apply", 
162                     callback=self.applySettings, 
163                     default=True)
164       
165        OWGUI.rubber(self.controlArea)
166       
167       
168        self.changeKernel()
169        self.searching=False
170        self.applySettings()
171
172    def setData(self, data=None):
173        self.data = self.isDataWithClass(data, 
174                    wantedVarType=Orange.core.VarTypes.Continuous,
175                    checkMissing=True) and data or None
176        self.paramButton.setDisabled(not self.data)
177       
178    def applySettings(self):
179        learner = svm.SVMLearner(svm_type=svm.SVMLearner.Nu_SVR
180                                          if self.useNu else
181                                          svm.SVMLearner.Epsilon_SVR,
182                                 C=self.C,
183                                 p=self.p,
184                                 nu=self.nu,
185                                 kernel_type=self.kernel_type,
186                                 gamma=self.gamma,
187                                 degree=self.degree,
188                                 coef0=self.coef0,
189                                 eps=self.eps,
190                                 probability=self.probability,
191                                 normalization=self.normalization,
192                                 name=self.name)
193        predictor = None
194        support_vectors = None
195        if self.preprocessor:
196            learner = self.preprocessor.wrapLearner(learner)
197       
198        if self.data is not None:
199            predictor = learner(self.data)
200            support_vectors = predictor.support_vectors
201            predictor.name = self.name
202           
203        self.send("Learner", learner)
204        self.send("Predictor", predictor)
205        self.send("Support Vectors", support_vectors)
206       
207    def sendReport(self):
208        if self.useNu:
209            settings = [("Type", "Nu SVM regression"),
210                        ("Cost (C)", "%.3f" % self.C),
211                        ("Complexity bound (nu)", "%.2f" % self.nu)]
212        else:
213            settings = [("Type", "Epsilon SVM regression"),
214                        ("Cost (C)", "%.3f" % self.C),
215                        ("Loss epsilon", "%.3f" % self.p)]
216           
217        if self.kernel_type == 0:
218            kernel = "Linear, x.y"
219        elif self.kernel_type == 1:
220            kernel = "Polynomial, (%.4f*x.y+%.4f)<sup>%.4f</sup>" % (self.gamma, self.coef0, self.degree)
221        elif self.kernel_type == 2:
222            kernel = "RBF, e<sup>-%.4f*(x-y).(x-y)</sup>" % self.gamma
223        else:
224            kernel = "Sigmoid, tanh(%.4f*x.y+%.4f)" % (self.gamma, self.coef0)
225           
226        settings.extend([("Kernel", kernel),
227                         ("Tolerance", self.eps),
228                         ("Normalize data", OWGUI.YesNo[self.normalization])])
229       
230           
231        self.reportSettings("Settings", settings)
232        self.reportData(self.data)
233           
234       
235if __name__ == "__main__":
236    app = QApplication([])
237    w = OWSVMRegression()
238    w.show()
239    data = Orange.data.Table("housing")
240    w.setData(data)
241    app.exec_()
Note: See TracBrowser for help on using the repository browser.