-
Notifications
You must be signed in to change notification settings - Fork 3
/
fisherclassifier.m
executable file
·104 lines (95 loc) · 3.22 KB
/
fisherclassifier.m
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
classdef fisherclassifier < classifier
% FISHERCLASSIFIER extend classifier superclass by providing The Fisher
% Method functionalities.
% Because of inheritance, 'fisherclassifier' will have the same
% properties and methods with superclass 'classifier'. So we only have to
% define unique add-on functionalities in 'fisherclassifier'.
properties
% cutoff for classifying into given categories
minimums;
end
methods
% Constructor Method
function self=fisherclassifier(getfeatures)
if nargin==0
self.getfeatures=@getwords;
else
self.getfeatures=getfeatures;
end
self.minimums={};
end
function p=cprob(self,f,cat)
% The frequency of this feature in this category
clf=self.fprob(f,cat);
if clf==0
p=0;
else
% The frequency of this feature in all the categoris
c=self.categories();
freqsum=0;
for i=1:size(c,1)
freqsum=freqsum+self.fprob(f,c{i});
end
% The probability is the frequency in this category divided
% by the overall frequency
p=clf/(freqsum);
end
end
function fprob=fisherprob(self,item,cat)
%Multiply all the probabilities together
p=1;
features=self.getfeatures(item);
for i=1:size(features,1)
p=p*self.weightedprob(features{i},cat,@self.cprob);
end
% Take the natural log and multiply by -2
fscore=-2*log(p);
% Use the Chi-square inverse function to get a probability
fprob=self.invchi2(fscore,size(features,1)*2);
end
function x=invchi2(self,chi,df)
m=chi/2.0;
sum=exp(-m);
term=sum;
for i=1:floor(df/2)-1
term=term*m/i;
sum=sum+term;
end
x=min(sum,1.0);
end
function setminimum(self,cat,min)
if isempty(strmatch(cat,char(self.minimums{:,1}), 'exact'))
self.minimums{end+1,1}=cat;
self.minimums{end,2}=min;
else
idx=strmatch(cat,char(self.minimums{:,1}), 'exact');
self.minimums{idx,2}=min;
end
end
function m=getminimum(self,cat)
if isempty(strmatch(cat,char(self.minimums{:,1}), 'exact'))
m=0;
else
idx=strmatch(cat,char(self.minimums{:,1}), 'exact');
m=self.minimums{idx,2};
end
end
function best=classify(self,item,default)
if nargin <3
default='';
end
% Loop through looking for the best result
best=default;
max=0.0;
c=self.categories();
for i=1:size(c,1)
p=self.fisherprob(item,c{i});
% Make sure it exceeds its minimum
if (p>self.getminimum(c{i}))&&(p>max)
best=c{i};
max=p;
end
end
end
end
end