11
$\begingroup$

Suppose, the following are the first few lines from a dataset for solving a regression problem:

H   7.042 5.781 5.399  -9.118   5.488  7.470     0 0 0 1 0 1 1 3 0 0 0 1 0 0 0 0 0 0 0 0    2.144    
H   5.781 5.399 5.373   5.488   5.166  6.452     0 1 1 3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0    2.268
H   5.399 5.373 5.423   5.166   4.852  6.069     0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2.101 
H   5.373 5.423 5.247   4.852   5.164  6.197     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2.222 
H   5.423 5.247 5.485   5.164   4.943  6.434     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2.416
C   5.247 5.485 6.675   4.943   8.103  8.264     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    3.028
C   5.485 6.675 6.372   8.103  -9.152  9.047     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    -1.235
C   6.675 6.372 5.669  -9.152  -8.536 11.954     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    -0.953 
H   6.372 5.669 5.304  -8.536   5.433  6.703     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2.233 
H   5.669 5.304 5.461   5.433   4.924  6.407     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0    2.313

The left-most column is the class data. The right-most column is Y data. The rest of the features are all angular data.

.

My initial setup for the model was as follows:

def create_model(n_hidden_1, n_hidden_2, num_features):
    # create the model
    model = Sequential()
    model.add(tf.keras.layers.InputLayer(input_shape=(num_features,)))
    model.add(tf.keras.layers.Dense(n_hidden_1, activation='relu'))
    model.add(tf.keras.layers.Dense(n_hidden_2, activation='relu'))
    model.add(tf.keras.layers.Dense(1))

    # instantiate the optimizer
    opt = keras.optimizers.Adam(learning_rate=LEARNING_RATE)

    # compile the model
    model.compile(
         loss="mean_squared_error",
         optimizer=opt,
         metrics=["mean_squared_error"]
    )

    # return model
    return model

This model didn't produce the correct outcome. The expected output should be around $0.20$. However, the current setup is producing around $0.80$. These are radian values.

Someone told me that MSE doesn't work in the case of angular data. So, I need to use a custom output layer and a custom error function.

Why doesn't mean square error work in the case of angular data?

How can I solve this issue?

$\endgroup$
9
  • 1
    $\begingroup$ what do you mean by "correct outcome" ? $\endgroup$
    – J. Delaney
    Feb 19, 2022 at 19:18
  • $\begingroup$ @J.Delaney, The expected output should be around $0.20$. However, the current setup is producing around $0.80$. These are radian values. $\endgroup$
    – user366312
    Feb 19, 2022 at 19:25
  • 5
    $\begingroup$ You mean the output for some single line? Is the Y data also in radians? Why are some of the angular features greater than 2$\pi$? Try to explain your problem more clearly $\endgroup$
    – J. Delaney
    Feb 19, 2022 at 19:47
  • 2
    $\begingroup$ if Y is in radians (?) then MSE can obviously be problematic because for example $-\pi$ and $+\pi$ are the same angle and that is not reflected in your loss function. $\endgroup$
    – J. Delaney
    Feb 19, 2022 at 20:18
  • 3
    $\begingroup$ The natural thing would be to change the loss function for example to be square of the angular difference (see e.g. [stackoverflow.com/questions/1878907/…). I don't know if something like that already exists or you will have to write your own custom function. $\endgroup$
    – J. Delaney
    Feb 19, 2022 at 20:37

1 Answer 1

36
$\begingroup$

The problem with using MSE directly on angle values is that values can be very close together on the circle, but will have a large square error. For example, 359 degrees and 1 degrees are very close together on a circle, but very far apart in terms of squared difference.

To rectify this, you should use a distance metric that reflects the fact that you're working with angles.

The Euclidean distance between two points on a circle is the length of the chord between the two points. So a simple and direct example of a distance considers the angle $\alpha$ as a point on the unit circle $(\cos \alpha, \sin \alpha)$, then computes the Euclidean distance in the ordinary way.

Elementary trigonometric identities simplify the expression.

$$\begin{align} d_E^2 (\theta, \phi) &= (\cos \theta - \cos \phi)^2 + (\sin \theta - \sin \phi)^2 \\ &= \cos^2 \theta - 2 \cos \theta \cos \phi + \cos^2 \phi + \sin^2 \theta - 2 \sin \theta \sin \phi + \sin^2 \phi \\ d_E (\theta, \phi) &= \sqrt{2 - 2 \cos (\theta - \phi) } \end{align}$$

By inspection, we can see that angles that are very close together have $\cos (\theta - \phi)$ close to 1, so the distance is close to 0. On the other hand, angles that are very far apart have $\cos (\theta - \phi)$ close to 0, so the distance is close to 1. This satisfies our intuitive notions of distance.

Of course, this is not the only option. This distance and some alternatives are discussed in these related threads:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.