source: orange/orange/Orange/distance/__init__.py @ 9719:782cfec5fe88

Revision 9719:782cfec5fe88, 9.6 KB checked in by markotoplak, 2 years ago (diff)

Orange.distance renames.

Line 
1import Orange
2
3#ExampleDistance -> Distance
4#ExampleDistanceConstructor -> DistanceConstructor
5#Hamming -> HammingDistance
6#DTW -> DTWDistance
7#Euclidean -> EuclideanDistance
8#Manhattan -> ...
9#Maximal -> ...
10#Relief -> ..
11#DTWConstructor
12#EuclideanConstructor
13#HammingConstructor
14#ManhattanConstructor
15#MaximalConstructor
16#ReliefConstructor
17#PearsonRConstructor -> PearsonR
18#PearsonR -> PearsonRDistance
19#SpearmanRConstructor -> SpearmanR
20#SpearmanR -> SpearmanRDistance
21#MahalanobisConstructor ->  Mahalanobis
22#Mahalanobis -> MahalanobisDistance
23#ExamplesDistance_Normalized -> Distance_Normalized
24
25from Orange.core import \
26     AlignmentList, \
27     DistanceMap, \
28     DistanceMapConstructor, \
29     ExampleDistConstructor, \
30     ExampleDistBySorting, \
31     ExampleDistVector, \
32     ExamplesDistance as Distance, \
33     ExamplesDistance_Normalized as DistanceNormalized, \
34     ExamplesDistanceConstructor as DistanceConstructor
35
36from Orange.core import ExamplesDistance_Hamming as HammingDistance
37from Orange.core import ExamplesDistance_DTW as DTWDistance
38from Orange.core import ExamplesDistance_Euclidean as EuclideanDistance
39from Orange.core import ExamplesDistance_Manhattan as ManhattanDistance
40from Orange.core import ExamplesDistance_Maximal as MaximalDistance
41from Orange.core import ExamplesDistance_Relief as ReliefDistance
42
43from Orange.core import ExamplesDistanceConstructor_DTW as DTW
44from Orange.core import ExamplesDistanceConstructor_Euclidean as Euclidean
45from Orange.core import ExamplesDistanceConstructor_Hamming as Hamming
46from Orange.core import ExamplesDistanceConstructor_Manhattan as Manhattan
47from Orange.core import ExamplesDistanceConstructor_Maximal as Maximal
48from Orange.core import ExamplesDistanceConstructor_Relief as Relief
49
50import statc
51import numpy
52from numpy import linalg
53
54class PearsonR(DistanceConstructor):
55    """Constructs an instance of :obj:`PearsonRDistance`. Not all the data needs to be given."""
56   
57    def __new__(cls, data=None, **argkw):
58        self = ExamplesDistanceConstructor.__new__(cls, **argkw)
59        self.__dict__.update(argkw)
60        if data:
61            return self.__call__(data)
62        else:
63            return self
64
65    def __call__(self, table):
66        indxs = [i for i, a in enumerate(table.domain.attributes) \
67                 if a.varType==Orange.data.Type.Continuous]
68        return PearsonRDistance(domain=table.domain, indxs=indxs)
69
70class PearsonRDistance(Distance):
71    """
72    `Pearson correlation coefficient
73    <http://en.wikipedia.org/wiki/Pearson_product-moment\
74    _correlation_coefficient>`_
75    """
76
77    def __init__(self, **argkw):
78        self.__dict__.update(argkw)
79       
80    def __call__(self, e1, e2):
81        """
82        :param e1: data instances.
83        :param e2: data instances.
84       
85        Returns Pearson's disimilarity between e1 and e2,
86        i.e. (1-r)/2 where r is Sprearman's rank coefficient.
87        """
88        X1 = []
89        X2 = []
90        for i in self.indxs:
91            if not(e1[i].isSpecial() or e2[i].isSpecial()):
92                X1.append(float(e1[i]))
93                X2.append(float(e2[i]))
94        if not X1:
95            return 1.0
96        try:
97            return (1.0 - statc.pearsonr(X1, X2)[0]) / 2.
98        except:
99            return 1.0
100
101class SpearmanR(DistanceConstructor):
102    """Constructs an instance of SpearmanR. Not all the data needs to be given."""
103   
104    def __new__(cls, data=None, **argkw):
105        self = DistanceConstructor.__new__(cls, **argkw)
106        self.__dict__.update(argkw)
107        if data:
108            return self.__call__(data)
109        else:
110            return self
111
112    def __call__(self, table):
113        indxs = [i for i, a in enumerate(table.domain.attributes) \
114                 if a.varType==Orange.data.Type.Continuous]
115        return SpearmanRDistance(domain=table.domain, indxs=indxs)
116
117class SpearmanRDistance(Distance): 
118
119    """`Spearman's rank correlation coefficient
120    <http://en.wikipedia.org/wiki/Spearman%27s_rank_\
121    correlation_coefficient>`_"""
122
123    def __init__(self, **argkw):
124        self.__dict__.update(argkw)
125       
126    def __call__(self, e1, e2):
127        """
128        :param e1: data instances.
129        :param e2: data instances.
130       
131        Returns Sprearman's disimilarity between e1 and e2,
132        i.e. (1-r)/2 where r is Sprearman's rank coefficient.
133        """
134        X1 = []; X2 = []
135        for i in self.indxs:
136            if not(e1[i].isSpecial() or e2[i].isSpecial()):
137                X1.append(float(e1[i]))
138                X2.append(float(e2[i]))
139        if not X1:
140            return 1.0
141        try:
142            return (1.0 - statc.spearmanr(X1, X2)[0]) / 2.
143        except:
144            return 1.0
145
146class Mahalanobis(DistanceConstructor):
147    """ Construct instance of Mahalanobis. """
148   
149    def __new__(cls, data=None, **argkw):
150        self = ExamplesDistanceConstructor.__new__(cls, **argkw)
151        self.__dict__.update(argkw)
152        if data:
153            return self.__call__(data)
154        else:
155            return self
156   
157    # Check attributtes a, b, c
158    def __call__(self, table, a=None, b=None, c=None, **argkw):
159        # Process data
160        dc = Orange.core.DomainContinuizer()
161        dc.classTreatment = Orange.core.DomainContinuizer.Ignore
162        dc.continuousTreatment = Orange.core.DomainContinuizer.NormalizeBySpan
163        dc.multinomialTreatment = Orange.core.DomainContinuizer.NValues
164       
165        newdomain = dc(table)
166        newtable = table.translate(newdomain)
167       
168        data, cls, _ = newtable.to_numpy()
169       
170        covariance_matrix = numpy.cov(data, rowvar=0, bias=1)
171        inverse_covariance_matrix = linalg.pinv(covariance_matrix, rcond=1e-10)
172       
173        return MahalanobisDistance(domain=newdomain, icm=inverse_covariance_matrix)
174
175class MahalanobisDistance(Distance):
176    """`Mahalanobis distance
177    <http://en.wikipedia.org/wiki/Mahalanobis_distance>`_"""
178
179    def __init__(self, domain, icm, **argkw):
180        self.domain = domain
181        self.icm = icm
182        self.__dict__.update(argkw)
183       
184    def __call__(self, e1, e2):
185        """
186        :param e1: data instances.
187        :param e2: data instances.
188       
189        Returns Mahalanobis distance between e1 and e2.
190        """
191        e1 = Orange.data.Instance(self.domain, e1)
192        e2 = Orange.data.Instance(self.domain, e2)
193       
194        diff = []
195        for i in range(len(self.domain.attributes)):
196            diff.append(e1[i].value - e2[i].value) if not(e1[i].isSpecial() or e2[i].isSpecial()) else 0.0
197        diff = numpy.asmatrix(diff)
198        res = diff * self.icm * diff.transpose()
199        return res[0,0]**0.5
200   
201   
202class PearsonRAbsolute(PearsonRConstructor):
203    """ Construct an instance of PearsonRAbsolute example distance estimator.
204    """
205    def __call__(self, data):
206        indxs = [i for i, a in enumerate(data.domain.attributes) \
207                 if a.varType==Orange.data.Type.Continuous]
208        return PearsonRAbsoluteDistance(domain=data.domain, indxs=indxs)
209   
210   
211class PearsonRAbsoluteDistance(PearsonR):
212    """ An example distance estimator using absolute value of Pearson
213    correlation coefficient.
214    """
215    def __call__(self, e1, e2):
216        """
217        Return absolute Pearson's dissimilarity between e1 and e2,
218        i.e.
219       
220        .. math:: (1 - abs(r))/2
221       
222        where r is Pearson's correlation coefficient.
223        """
224        X1 = []; X2 = []
225        for i in self.indxs:
226            if not(e1[i].isSpecial() or e2[i].isSpecial()):
227                X1.append(float(e1[i]))
228                X2.append(float(e2[i]))
229        if not X1:
230            return 1.0
231        try:
232            return (1.0 - abs(statc.pearsonr(X1, X2)[0]))
233        except:
234            return 1.0
235       
236       
237class SpearmanRAbsolute(SpearmanRConstructor):
238    """ Construct an instance of SpearmanRAbsolute example distance estimator.
239    """
240    def __call__(self, data):
241        indxs = [i for i, a in enumerate(data.domain.attributes) \
242                 if a.varType==Orange.data.Type.Continuous]
243        return SpearmanRAbsoluteDistance(domain=data.domain, indxs=indxs)
244   
245   
246class SpearmanRAbsoluteDistance(SpearmanR):
247    def __call__(self, e1, e2):
248        """
249        Return absolute Spearman's dissimilarity between e1 and e2,
250        i.e.
251         
252        .. math:: (1 - abs(r))/2
253       
254        where r is Spearman's correlation coefficient.
255        """
256        X1 = []; X2 = []
257        for i in self.indxs:
258            if not(e1[i].isSpecial() or e2[i].isSpecial()):
259                X1.append(float(e1[i]))
260                X2.append(float(e2[i]))
261        if not X1:
262            return 1.0
263        try:
264            return (1.0 - abs(statc.spearmanr(X1, X2)[0]))
265        except:
266            return 1.0
267   
268   
269def distance_matrix(data, distance_constructor, progress_callback=None):
270    """ A helper function that computes an obj:`Orange.core.SymMatrix` of all
271    pairwise distances between instances in `data`.
272   
273    :param data: A data table
274    :type data: :obj:`Orange.data.Table`
275   
276    :param distance_constructor: An ExamplesDistance_Constructor instance.
277    :type distance_constructor: :obj:`Orange.distances.ExampleDistConstructor`
278   
279    """
280    from Orange.misc import progressBarMilestones as progress_milestones
281    matrix = Orange.core.SymMatrix(len(data))
282    dist = distance_constructor(data)
283   
284    msize = len(data)*(len(data) - 1)/2
285    milestones = progress_milestones(msize, 100)
286    count = 0
287    for i in range(len(data)):
288        for j in range(i + 1, len(data)):
289            matrix[i, j] = dist(data[i], data[j])
290           
291            if progress_callback and count in milestones:
292                progress_callback(100.0 * count / msize)
293            count += 1
294           
295    return matrix
Note: See TracBrowser for help on using the repository browser.