How can we measure the similarity distance between categorical data ? - distance

How can we measure the similarity distance between categorical data ?
Example:
Gender: Male, Female
Numerical values: [0 - 100], [200 - 300]
Strings: Professionals, beginners, etc,...
Thanks in advance.

There are different ways to do this. One of the simplest would be as follows.
1) Assign numeric value to each property so the order matches the meaning behind the property if possible. It is important to order property values from lower to higher if property can be measured. If it is not possible and property is categorical (like gender, profession, etc), just assign number to each possible value.
P1 - Gender
-------------------
0 - Male
1 - Female
P2 - Experience
-----------
0 - Beginner
5 - Average
10 - Professional
P3 - Age
-----------
[0 - 100]
P4 - Body height, cm
-----------
[50 - 250]
2) For each concept find scale factor and offset so all property values fall in the same chosen range, say [0-100]
Sx = 100 / (Px max - Px min)
Ox = -Px min
In sample provided you would get:
S1 = 100
O1 = 0
S2 = 10
O2 = 0
S3 = 1
O3 = 0
S4 = 0.5
O4 = -50
3) Now you can create a vector containing all the property values.
V = (S1 * P1 + O1, S2 * P2 + O2, S3 * P3 + O3, S4 * P4 + O4)
In sample provided it would be:
V = (100 * P1, 10 * P2, P3, 0.5 * P4 - 50)
4) Now you can compare two vectors V1 and V2 by subtracting one from other. The length of resulting vector will tell how different they are.
delta = |V1 - V2|
Vectors are subtracted by subtracting each dimension. Vector length can be calculated as square root of sum of squared vector dimensions.
Imagine we have 3 persons:
John
P1 = 0 (male)
P2 = 0 (beginner)
P3 = 20 (20 years old)
P4 = 190 (body height is 190 cm)
Kevin
P1 = 0 (male)
P2 = 10 (professional)
P3 = 25 (25 years old)
P4 = 186 (body height is 186 cm)
Lea
P1 = 1 (female)
P2 = 10 (professional)
P3 = 40 (40 years old)
P4 = 178 (body height is 178 cm)
Vectors would be:
J = (100 * 0, 10 * 0, 20, 0.5 * 190 - 50) = (0, 0, 20, 45)
K = (100 * 0, 10 * 10, 25, 0.5 * 186 - 50) = (0, 100, 25, 43)
L = (100 * 1, 10 * 10, 40, 0.5 * 178 - 50) = (100, 100, 40, 39)
To determine we need to subtract vectors:
delta JK = |J - K| =
= |(0 - 0, 0 - 100, 20 - 25, 45 - 43)| =
= |(0, -100, -5, 2)| =
= SQRT(0 ^ 2 + (-100) ^ 2 + (-5) ^ 2 + 2 ^ 2) =
= SQRT(10000 + 25 + 4) =
= 100,14
delta KL = |K - L| =
= |(0 - 100, 100 - 100, 25 - 40, 43 - 39)| =
= |(-100, 0, -15, 4)| =
= SQRT((-100) ^ 2 + 0 ^ 2 + (-15) ^ 2 + 4 ^ 2) =
= SQRT(10000 + 225 + 16) =
= 101,20
delta LJ = |L - J| =
= |(100 - 0, 100 - 0, 40 - 20, 39 - 45)| =
= |(100, 100, 20, -6)| =
= SQRT(100 ^ 2 + 100 ^ 2 + (20) ^ 2 + (-6) ^ 2) =
= SQRT(10000 + 10000 + 400 + 36) =
= 142,95
From this you can see that John and Kevin are more similar than any other as delta is smaller.

There are a number of measures for finding similarity between categorical data. The following paper discuses briefly about these measures.
https://conservancy.umn.edu/bitstream/handle/11299/215736/07-022.pdf?sequence=1&isAllowed=y
If you're trying to do this in R, there's a package named 'nomclust', which has all these similarity measures readily available.
Hope this helps!

If you are using python, there is a latest library which helps in finding the proximity matrix based on similarity measures such as Eskin, overlap, IOF, OF, Lin, Lin1, etc.
After obtaining the proximity matrix we can go on clustering using Hierarchical Cluster Analysis.
Check this link to the library named "Categorical_similarity_measures":
https://pypi.org/project/Categorical-similarity-measures/0.4/

Just a thought, We can also apply euclidean distance between two variables to find a drift value. If it is 0, then there is no drift or else call as similar. But the vector should be sorted and same length before calculation.

Related

Beginner PyTorch - RuntimeError: shape '[16, 400]' is invalid for input of size 9600

I'm trying to build a CNN but I get this error:
---> 52 x = x.view(x.size(0), 5 * 5 * 16)
RuntimeError: shape '[16, 400]' is invalid for input of size 9600
It's not clear for me what the inputs of the 'x.view' line should be. Also, I don't really understand how many times I should have this 'x.view' function in my code. Is it only once, after the 3 convolutional layers and 2 linear layers? Or is it 5 times, one after every layer?
Here's my code:
CNN
import torch.nn.functional as F
# Convolutional neural network
class ConvNet(nn.Module):
def __init__(self, num_classes=10):
super(ConvNet, self).__init__()
self.conv1 = nn.Conv2d(
in_channels=3,
out_channels=16,
kernel_size=3)
self.conv2 = nn.Conv2d(
in_channels=16,
out_channels=24,
kernel_size=4)
self.conv3 = nn.Conv2d(
in_channels=24,
out_channels=32,
kernel_size=4)
self.dropout = nn.Dropout2d(p=0.3)
self.pool = nn.MaxPool2d(2)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(512, 10)
self.final = nn.Softmax(dim=1)
def forward(self, x):
print('shape 0 ' + str(x.shape))
x = F.max_pool2d(F.relu(self.conv1(x)), 2)
x = self.dropout(x)
print('shape 1 ' + str(x.shape))
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = self.dropout(x)
print('shape 2 ' + str(x.shape))
# x = F.max_pool2d(F.relu(self.conv3(x)), 2)
# x = self.dropout(x)
x = F.interpolate(x, size=(5, 5))
x = x.view(x.size(0), 5 * 5 * 16)
x = self.fc1(x)
return x
net = ConvNet()
Can someone help me understand the problem?
The output of 'x.shape' is:
shape 0 torch.Size([16, 3, 256, 256])
shape 1 torch.Size([16, 16, 127, 127])
shape 2 torch.Size([16, 24, 62, 62])
Thanks
This means that instead the product of the channel and spatial dimensions is not 5*5*16. To flatten the tensor, replace x = x.view(x.size(0), 5 * 5 * 16) with:
x = x.view(x.size(0), -1)
And self.fc1 = nn.Linear(600, 120) with:
self.fc1 = nn.Linear(600, 120)

fmincon: objective function for this?

I'm writing a program to optimize a packing problem using Robert Lang's algorithm from his webpage: https://langorigami.com/wp-content/uploads/2015/09/ODS1e_Algorithms.pdf
This is used to design origami models and it's a problem from circle packing with constraints and different radius.
I have created an example with 5 nodes, where 4 of them are terminal.
Looking at these definitions included in the previous algorithm, I want to work with the Scale Optimization (A.3).
According to the notation, in my example I have:
E = {e1, e2, e3, e4,} ---> Edges
U = {u1, u2. u3, u4, u5} ---> Vertices (Each one with x and y coordinates)
Ut = {u2, u3, u4, u5} ---> Terminal Vertices
P = {[u1, u2], [u1, u3], [u1, u4], [u1, u5],
[u2, u3], [u2, u4], [u2, u5],
[u3, u4], [u4, u5]} ---> All paths between vertices from U
Pt = {[u2, u3], [u2, u4], [u2, u5],
[u3, u4], [u3, u5],
[u4, u5]} ---> All paths between terminal vertices Ut
And if I assume that σ is equal to 0:
L = {100, 50, 100, 100,
150, 200, 200,
150, 150,
200} --> Length of the paths P
Note that the length of each path is in the same position of P.
So now, with all this defined, I have to optimize the scale.
For that, I should:
Minimize (-m) over {m,ui ∈ Ut} s.t.: (A-2)
1.- 0 ≤ ui,x ≤ w for all ui ∈Ut (A-3)
2.- 0 ≤ ui,y ≤ h for all ui ∈Ut (A-4)
3.- (A-5) from webpage I provided.
So, in the example, merging (A-3) and (A-4) we can set the Lb and Ub for the fmincon function such as:
Lb = zeros(1,8)
Ub = [ones(1,4)*w, ones(1,4)*h]
The input x for the fmincon function, due to refusing matrix, I'm using it like:
X = [x1 x2 x3 x4 y1 y2 y3 y4], that's why Lb and Ub has that form.
About the (A-5), we get this set of inequalities:
m*150 - sqrt((x(2)-x(3))^2 + (y(2)-y(3))^2) <= 0
m*200 - sqrt((x(2)-x(4))^2 + (y(2)-y(4))^2) <= 0
m*200 - sqrt((x(2)-x(5))^2 + (y(2)-y(5))^2) <= 0
m*150 - sqrt((x(3)-x(4))^2 + (y(3)-y(4))^2) <= 0
m*150 - sqrt((x(3)-x(5))^2 + (y(3)-y(5))^2) <= 0
m*200 - sqrt((x(4)-x(5))^2 + (y(4)-y(5))^2) <= 0
My main program is testFmincon.m:
[x,fval,exitflag] = Solver(zeros(1,10),zeros(1,10),ones(1,10)*700);
%% w = h = 700
I implemented the optimizer in the file Solver.m:
function [x,fval,exitflag,output,lambda,grad,hessian] = Solver(x0, lb, ub)
%% This is an auto generated MATLAB file from Optimization Tool.
%% Start with the default options
options = optimoptions('fmincon');
%% Modify options setting
options = optimoptions(options,'Display', 'off');
options = optimoptions(options,'Algorithm', 'sqp');
[x,fval,exitflag,output,lambda,grad,hessian] = ...
fmincon(#Objs,x0,[],[],[],[],lb,ub,#Objs2,options);
Where Objs2.m is:
function [c, ceq] = Objs2(xy)
length = size(xy);
length = length(2);
x = xy(1,1:length/2);
y = xy(1,(length/2)+1:length);
c(1) = sqrt((x(2) - x(3))^2 + (y(2)-y(3))^2) - m*150;
c(2) = sqrt((x(2) - x(4))^2 + (y(2)-y(4))^2) - m*200;
c(3) = sqrt((x(2) - x(5))^2 + (y(2)-y(5))^2) - m*200;
c(4) = sqrt((x(3) - x(4))^2 + (y(3)-y(4))^2) - m*150;
c(5) = sqrt((x(3) - x(5))^2 + (y(3)-y(5))^2) - m*150;
c(6) = sqrt((x(4) - x(5))^2 + (y(4)-y(5))^2) - m*200;
ceq=[x(1) y(1)]; %% x1 and y1 are 0.
end
And Objs.m file is:
function c = Objs(xy)
length = size(xy);
length = length(2);
x = xy(1,1:length/2);
y = xy(1,(length/2)+1:length);
c(1) = sqrt((x(2) - x(3))^2 + (y(2)-y(3))^2) - m*150;
c(2) = sqrt((x(2) - x(4))^2 + (y(2)-y(4))^2) - m*200;
c(3) = sqrt((x(2) - x(5))^2 + (y(2)-y(5))^2) - m*200;
c(4) = sqrt((x(3) - x(4))^2 + (y(3)-y(4))^2) - m*150;
c(5) = sqrt((x(3) - x(5))^2 + (y(3)-y(5))^2) - m*150;
c(6) = sqrt((x(4) - x(5))^2 + (y(4)-y(5))^2) - m*200;
c = m*sum(c);
end
But I doesn't work correctly, I think I'm using wrong the fmincon function.
I don't know neither how to optimize (-m) ... should I use syms m or something like that?
edit: The output like this is always [0 0 0 0 0 0 0 0 0 0] when it shouldn't. See the output here.
Thank you so much in advice.
Some more observations.
We can simplify things a little bit by getting rid of the square root. So the constraints look like:
set c = {x,y}
maximize m2
m2 * sqrpathlen(ut,vt) <= sum(c, sqr(pos(ut,c)-pos(vt,c))) for all paths ut->vt
where m2 is the square of m.
This is indeed non-convex. With a global solver I get as solution:
---- 83 VARIABLE m2.L = 12.900 m^2, with m=scale
PARAMETER m = 3.592
---- 83 VARIABLE pos.L positions
x y
u3 700.000 700.000
u4 700.000 161.251
u5 161.251 700.000
(pos(u2,x) and pos(u2,y) are zero).
With a local solver using 0 as starting point, we see we don't move at all:
---- 83 VARIABLE m2.L = 0.000 m^2, with m=scale
PARAMETER m = 0.000
---- 83 VARIABLE pos.L positions
( ALL 0.000 )

How to convert dbm to watts on Matlab

Good day
I want to convert PT=47dbm to watts,how can i do that conversion on matlab?
On my code I have it as PT=50,12watts, but i want to do the proper conversion from dbm to watts using Matlab.
The watt to dBm conversion follows the following rule:
dBW = 10 * log10(P[w])
dBm = 10 * log10(1000 * P[w])
= 10 * log10(P[w]) + 10 * log10(1000)
= 10 * log10(P[w]) + 10 * 3
= 10 * log10(P[w]) + 30
= dBW + 30
Hence, the inverse path will be:
P[w] = 10 ^ ((P[dBm] - 30) / 10);
Thus, in Matlab:
P_w = 47;
P_dBm = 10 ^ ((P_w - 30) / 10); % 50.12

Using Kharitonov method to design the Robust controller for uncertain model

The tr. functions describing the system.
G11= 1 / (29s^3 + 40s^2 + 30s +20), G12= 1 / (50s^3 + 10s^2 + 70s +2),
G21= 1 / (80s^3 + 10s^2 + 90s +5), G22= 1 / (11s^3 + 4s^2 + 66s +7),
then,
Can I consider it as an uncertain plants given by Gij= 1/ (a s^3 + bs^2 + c s + d ) where,
a min = 11, a max = 80; b min =4 , b max = 40,
c min = 30, c max = 90, d min = 2, d max = 20.
How can we apply Kharitonov theorem to design a PID controller for an uncertain system described transfer functions and plot the interval stable region?

Not sure what this 'histogram code' is doing in MATLAB

I have following code that was given to me, but I am not sure at all as to what the logic here is. The idea, I believe, is that this will histogram/quantize my data. Here is the code:
The input:
x = 180.*rand(1,1000); %1000 points from 0 to 180 degrees.
binWidth = 20; %I want the binWidth to be 20 degrees.
The main function:
% -------------------------------------------------------------------------
% Compute the closest bin center x1 that is less than or equal to x
% -------------------------------------------------------------------------
function [x1, b1] = computeLowerHistBin(x, binWidth)
% Bin index
bin = floor(x./binWidth - 0.5);
% Bin center x1
x1 = binWidth * (bin + 0.5);
% add 2 to get to 1-based indexing
b1 = bin + 2;
end
Finally, the final 'quantized' data:
w = 1 - (x - x1)./binWidth
Here is what I do not get: I do not understand - at all - just why exactly x1 is computed the way it is, and also why/how w is computed the way it is. In fact, of all the things, w confuses me the most. I literally cannot understand the logic here, or what is really intended. Would appreciate a detailed elucidation of this logic. Thanks.
He is binning with lb <= x < up and splitting the interval [0,180] in [-10,10), [10, 30), [30,40) ..., [150,170), [170,190).
Suppose x = 180, then:
bin = floor(180/20-0.5) = floor(9-0.5) = floor(8.5) = 8;
while if x = 0:
bin = floor(`0/20-0.5) = floor(-0.5) = floor(-1) = -1;
which respectively translate into x1 = 20 * (8+0.5) = 170 and x1 = -10 which seems like what the function suggests lowerHistBin().
In the end, w simply measures how far the point x is from the corresponding lower bin x1. Notice that w is in (0,1], with w being 1 when x = x1 and approaching 0 when x -> x1+binWidth. So, if x say approaches 170, then w will approach 1 - (170-150)/20 = 0.