-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SYSTEMDS-3549] Hidden Markov model builtin #1838
base: main
Are you sure you want to change the base?
Conversation
Hi @cluelesprogrammer , Yes the files are located correctly. Next steps are to (as we texted about before):
Once the above is done start making the HMM implementation. I suggest you just do the work on top of this PR. |
scripts/builtin/hmm.dml
Outdated
# P Probability of the set of outputs | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
hmm = function(Matrix[Double] X) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you are allowed to define more than one function in these files, we require you to mark the main function with: m_ , aka here it become m_hmm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good so far you just have to write the test matrix to disk and verify that the test executes correctly with the correct output.
writeInputMatrixWithMTD("X", X, true); | ||
""" | ||
|
||
runTest(true, false, null, -1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this only runs your code. it does not verify something happened.
you can alternatively call it like
String stdout = runTest(null).toString()
then you get the output from the experiment if you also call before setOutputBuffering(true);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To Finish the submission i expect at least:
- A test that verify behavior not just that your method is running.
- If it is impossible to implement the HMM itself, then at least test the HMM predict in accordance to what you think it should do, and make clear indications where in the code elements are missing for a full implementation. Otherwise a full simple version of HMM would be required, it does not have to be efficient.
Best regards
Sebastian
iteration, break. | ||
*/ | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new lines in end of files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand this. Could you please clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I add or remove a newline?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went through the code again.
It looks okay, so i would say it is a passed AMLS project.
But i did leave some coding comments, that we need to look into before we merge it.
Thanks for the PR and help (but do not feel forced to do it.)
|
||
#X should have the size of 1 * ncols | ||
#should be transposed for the unique function | ||
unique_X = matrix(X, rows=ncol(X), cols=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to transpose call t(X)
|
||
search = TRUE | ||
nr_states = 2 | ||
seed = 42 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make seed an argument initially
#X should have the size of 1 * ncols | ||
#should be transposed for the unique function | ||
unique_X = matrix(X, rows=ncol(X), cols=1) | ||
nr_outputs = unique_vals(unique_X) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a builtin function to calculate the number of unique values:
countDistinct()
you can give it an direction if you want to know the number of distinct in columns, rows or entirety.
seed = seed+1 | ||
B = col_normalize(matrix(1/nr_outputs,rows=nr_states, cols=nr_outputs) + rand(rows=nr_states, cols=nr_outputs, seed=seed)) | ||
seed = seed+1 | ||
ip = matrix(1/nr_states, rows=nr_states, cols=1) + rand(rows=nr_states, cols=1, seed=seed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, each call to random have to have a unique seed. A suggestion for this is to make each rand call with seed += 1. (+= is not supported so you have to assign back the seed with seed = seed + 1, between the lines.)
#initialize state transition and emmission matrices uniformly | ||
A = col_normalize(matrix(1/nr_states, rows=nr_states, cols=nr_states) + rand(rows=nr_states, cols=nr_states, seed=seed)) | ||
seed = seed+1 | ||
B = col_normalize(matrix(1/nr_outputs,rows=nr_states, cols=nr_outputs) + rand(rows=nr_states, cols=nr_outputs, seed=seed)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Values contained in the matrix is equivalent in each cell for both calls.
perhaps the value to put into the matrix can be calculated once and then assigned into a matrix?
And even better if this is something we can assign into the arguments of the rand call, then we would reduce the current calls from 3 matrices materialized to only 1 per line of (98, 100, and 102)
[i, j] = index(trans_id, nr_states) | ||
for (t in 1:(T-1)) { | ||
#indices for alpha and beta | ||
ot1 = output_t(X, t+1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the method output_t and call the extraction here. It should automatically know it is a scalar.
Do you cast to int because you want to round? if so then call round()
nr_states = nrow(alpha) | ||
T = ncol(alpha) | ||
|
||
gamma = rand(rows=nr_states, cols=T) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rand call seems to be done just to materialize a matrix?
If so we could consider changing it to a matrix(rows...) call.
But it might not be the best solution.
den_it = sum(alpha[,t] * beta[,t]) | ||
gamma[i, t] = num_it / den_it | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these parfors can be rewritten as:
num_it_M = alpha * beta
den_it_M = rowsum(num_it_M)
gamma = num_it_M / den_it_M
This is because we support direct matrix and vector operations.
And i think this nicely maps to it. (But i might have an error here.)
for (t in 2:T) { | ||
ot = output_t(X, t) | ||
for (i in 1:nr_states) { | ||
alpha[i, t] = B[i, ot] * sum(alpha[,t-1]* A[ ,i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move alpha[,t-1] to outer loop
for (t in (T-1):1) { | ||
ot = output_t(X, t) | ||
for (i in 1:nr_states) { | ||
beta[i, t] = sum(beta[, t+1] * t(A[i, ]) * B[ , ot]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move beta[,t+1] to outer loop if possible
Hi @cluelesprogrammer , thanks a lot for contributing to SystemDS. Do you need some help with addressing the review comments. Your PR looks good as is. Let me know if you would like to address the comments. Kindly let us know, if there is any assistance we could provide. Regards, |
No description provided.