-
Notifications
You must be signed in to change notification settings - Fork 12
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
Finally compare dataset characteristics against each other #28
Conversation
shankari
commented
Jul 23, 2021
- Implement and evaluate a simple trip clustering algorithm (only start and end) based on DBSCAN clustering of the start and end locations
- Load data from multiple datasets and save into JSON to make it easier for others to work with it
- Load data from JSON and compare dataset characteristics against each other
- Since we concatenate multiple dataframes, the indices are all over the map. Let's reset the index before saving so we have a unified view. - We have JSON objects in our dataframe (`start_loc`, `end_loc`) so serializing as a csv doesn't really work. We read the objects back as strings, and the JSON library can't parse them because it is not using the correct quotes. - We save it directly as a JSON, using the default BSON handler to correctly serialize the object.
We are already using DBSCAN for the start and end location clustering, we can pretty easily find trips by matching on the start and end locations. Here, we explore two alternatives for the trip matching - add the distance matrices and recluster, or group by the (start, end) cluster label pairs and group. We find that the second method is correct. We also spot check both methods and find that the location clustering can also have some minor issues sometimes, but 2/3 spot checks worked well.
We are able to compare multiple datasets against each other by loading the labeled trips, clustering them and comparing the number of trips and how they are clustered against each other. The NREL dataset has the most compact clusters, the mini-pilot has the least, and the staging dataset has the most variability that spans both highly compat and very uncompact clusters.
Primarily to understand why it is worse than the DBSCAN trip clustering code. As you may recall, the results for DBSCAN were pretty respectable. Most trips were in a cluster, and the median cluster : trip-in-cluster ratio was below 40% for all datasets. e-mission#28 (comment) Why is similarity so much worse than the DBSCAN-based clustering? Should we switch to DBSCAN instead (horrifying proposition given the tight deadline)? See the notebook conclusion to find out! @corinne-hcr, this is more on the lines of what I expected you to do back when you were evaluating the first round/common trips, and definitely when we were getting poor results with the clustering. + change the original DBSCAN notebook to have the modified viz code
Initial results with DBSCAN based trip clustering (c7e8205) Most labeled trips fit into at least one clusterThe cluster:trip-in-cluster ratio (a rough estimate of the tightness of the cluster) is < 50% for most users.So we can guess that most users should be prompted ~ < 50% of the time Median ratio is consistently below 40%Definitely, the minipilot data was harder to work with, but its median is also below 40%. As expected NREL is best, but staging is also respectable. I don't see any reason why we should have been able to build only models for only three users on staging. |
Comparison between DBSCAN and similarity for one user is complete: Next step is to incorporate this back into the generalization across datasets and see if the results are generally relevant. |
The database code has currently been optimized for a 1:1 mapping between the server and the database, where the server needs to make multiple intensive queries to the database, for example, to read trajectory information from the database for multiple users at a time, for the post-processing. This has led to design decisions in which we cache the database connection and re-use it, to avoid overloading the server with multiple queries. We are now getting some requests for federated data. A concrete example is e-mission/e-mission-eval-private-data@952c476 where we wanted to compare the characteristics of multiple datasets (e-mission/e-mission-eval-private-data#28) An upcoming example would be to "roll up" multiple dashboard deployments (e.g. from individual cities) into a program level dashboard. We anticipate that these will be low, volume, intermittent accesses to generate analyses and metrics. The long-term fix is probably to create a FederatedTimeseries (similar to the AggregateTimeseries that merges data across users). But for now, we just implement a hack to reset the connection and reconnect it to a different URL. This means that we cannot access all databases in parallel, we will need to access them serially. But for the current use case, that is sufficient since we can concatenate all the data and work with it later.
@corinne-hcr with corinne-hcr/e-mission-server@7a75990, corinne-hcr/e-mission-server@58a14a8 and all the notebooks in this repo are runnable. |
We need to make sure to call `filter_trips` to reproduce the original results now that corinne-hcr/e-mission-server@b46a370 is committed
@corinne-hcr Tradeoffs for various combinations of similarity parameters and radii for the mini-pilot are done: Scatter plot of tradeoffsBox plot of tradeoffsIMHO, this shows the differences more clearly than the scatter plot. Top: request_pct, Bottom: homogeneity score I'm going to integrate this into the dataset comparison before poking around with this some more. Other analyses I would like to do are:
|
@corinne-hcr more examples of what the initial analysis might have looked like. Build similarity models for: - 100, 300m, 500m - all combinations of filtering (yes/no) and cutoffs (yes/no) Generate labels for all labeled trips Determine ground truth by looking at: unique tuples and unique values for each of the user inputs Use these models to compute the metrics (homogeneity score and request %) for all combinations, along with a few other metrics like the number of unique tuples, cluster_trip_pct, etc. At this point, we are focusing on ground truth from tuples since the homogeneity score is already fairly high. What we really need to do is to bring down the request %, or determine *why* the user % is so high so that we can fix it (e.g. polygon). Some results in: e-mission#28 (comment)
So we can easily change the result creation interactively without rebuilding the models, which takes a lot of time.
Generalization results: Scatter plot (left: DBSCAN, right: our sim)Box plots for the componets (left: DBSCAN, right: our sim), top: request %, bottom: homogeneity scoreHowever, the cluster_trip_pct that I had defined earlier still shows a significant difference w. Need to understand it better and figure out why it is different and why it doesn't capture the true metric. I will briefly attempt to figure that out tomorrow morning, but based on these results, we can stick to a single level of "clustering", use a 500m radius, and don't filter or delete bins. I will attempt to make the changes to the server code tomorrow, but if @corinne-hcr has finished her work, maybe that is the next task for her to tackle. |
Some more multi-dataset results, including an exploration on the number of trips required to be meaningful, and an explanation of the cluster trip ratio v/s request pct discrepancy. Results from: 31733c1 Visualize various counts: top to bottom, minipilot, nrel-lh, stageh-score v/s request pct scatter plot (l: DBSCAN, r: oursim, same as yesterday)log plot of number of trips v/s request pctBox plots that illustrate the result |
Major changes were to integrate the functions from the "unrolled" exploration code into this notebook so that we could generalize the "oursim" results across multiple datasets as well. It also appeared that we were building all the models **twice** for reasons that I don't understand; unified it to build the models once. Also pulled out the summary statistics code into a separate cell, so we can experiment with it without having to re-run the models, which take significant time. Added several visualizations to visualize the findings, which are: - oursim and DBSCAN have similar request pct - oursim has higher homogeniety score than DBSCAN - we have lower noise and tighter models if we have 100+ labeled trips Visualizations at: e-mission#28 (comment) @corinne-hcr, at this point, I'm going to move on to actually implementing this in the pipeline so we can get some results before the next meeting on Tuesday.
I was surprised that the homogeneity score of DBSCAN was so low, and then I realized that I was computing it incorrectly. Basically, I was just passing in the labels from DBSCAN as the predicted labels, but all the noisy trips have the same label (-1), instead separate labels, one for each noisy trip. This is likely the reason why the scores are lower. For example, consider the case in which we have two clusters of length 2 each, and 4 single trip clusters. If all the single trip clusters are labeled with
because it looks like the
I am almost certainly not going to use DBSCAN in the integrated pipeline, and that is my current priority, so I do not plan to fix this now. But if @corinne-hcr wants to write a paper, maybe she can fix it here? |
@corinne-hcr to understand this PR, and to compare it with your prior work, I would use the following order:
You will not be able to absorb the results just by looking at the code. You need to check out this branch and actually run the notebooks in the commits above. The notebooks have inline explanations (they are "notebooks" after all) of what I'm trying to understand and what the graphs mean. Most of them are "unrolled" so that I first try one option and then another, so that you can see the evolution of the analysis. For the last, multi-dataset notebook, you will need the combined dataset JSON file. I have shared that with you through OneDrive. Please let me know if you have any high-level questions. |
For the box plots which titled |
you should be able to see this from the code - e.g. https://github.com/e-mission/e-mission-eval-private-data/pull/28/files#diff-5b27f01eda7481b2844df59e55fffa030ca22df0c58f9796b8d1bb7ad13b1089R679 Again, You need to check out this branch and actually run the notebooks in the commits above. The notebooks have inline explanations (they are "notebooks" after all) of what I'm trying to understand and what the graphs mean. There are additional plots in the notebooks. The plots are not designed to be published without modification - they were primarily designed for me to understand what was going on so I could figure out how to modify the evaluation pipeline. If you choose to use any of them, you will need to ensure that all the labels are in place and the font sizes are appropriate. |
The nrel-lh dataset is from 4 NREL employees who voluntarily collected and labeled their data. |
@corinne-hcr from looking at your code ( But you compute the request percentage taking the full, non-cutoff list into account; you have a request for each of Can you discuss the reason for that mismatch further? We should standardize on a really clear definition of the metric calculations because otherwise we don't know what the metrics mean! |
I actually raised that question at the first term. But at this point, I don't remember your explanation clearly. Let's see if there is some records. |
So I actually implemented both alternate metrics (below cutoff as single trip clusters, and drop trips below cutoff) e457545 The first result is pretty much identical to no_cutoff, the second is pretty much identical to the old metric Old implementationTreat below cutoff as single label clustersDrop below cutoff |
Our current implementation of the h-score was incorrect because all the noisy trips were in the same `-1` bucket. e-mission#28 (comment) Experiment with two alternate handling methods, need to figure out which one to use e-mission#28 (comment)
Also please see my discussion around h-score and request pct in the notebook (e457545). Maybe we should compute the request_pct only on a split and not on the whole dataset. |
@corinne-hcr @GabrielKS, before making the changes to the evaluation pipeline, I did some super hacky analysis to compare the old models with the old settings, and my new, preferred settings. I had to copy over the Here are the results: The old model used very few trips.Due to a combination of the trip filtering, user validity checking, training on a split, and filtering the trips below the cutoff, the old model got few/no trips to train the model. This is particularly true for the later entries which are from the newer datasets. Sorry not sorry, I didn't have time to color code by dataset. This is a big deal for the location based clustering algorithms, which essentially take a nearest neighbor approach. If a particular bin is not included in the model, it will never be matched. The old model predicted very few trips, the new model is better.Note that with the old model, because we have so few trips in the model, we are not even infer labels for already labeled trips. In contrast, with the new model, at least all existing trips are labeled. There are still many users for whom the new model does not predict a lot of trips, but it is much much better.The only users with < 20% trips prediction rate have very few labeled trips.
I'm now going to move this code from the notebook into the server code. |
This reverts commit e457545.
From @corinne-hcr
So, if we are using precision/recall score, we can only use the true tuple, not the numeric labels that assigned by the indices(we would probably have different numeric labels for the same label tuple) From @shankari I explicitly said that we should get the labels for each trip as the predicted labels: |
From @corinne-hcr Some more questions.
From @shankari
|
From @corinne-hcr
If the labels_pred is {}, the score is not correct. It is not giving result as 1/3 From @shankari
From @corinne-hcr
|
There are some more questions:
|
Responses:
Also, the notebooks were an aid for me to convince myself about the settings for the final system. That doesn't preclude having a more extensive evaluation, even across all datasets, to put into a report or a peer reviewed publication. |
Just summarize the answer, please let me know if I understand it incorrectly:
|
|
The comparison boxplot is something like #28 (comment) |
@corinne-hcr those boxplots are for the h-score, which are used to evaluate cluster quality. My point was that I don't think you can use them to evaluate prediction quality. The graphs to evaluate the prediction quality are #28 (comment) but I don't think I made boxplots for them.
First, filter/no filter, etc are not different metrics. They are different configurations, and we want to use metrics such as the h-score and the cluster-to-trip-ratio to understand them. Second, can you clarify what you mean by "discussing metrics ... in one situation"? What would be the rough structure of such a discussion? To me, the boxplots (or similar graphs) are the easiest way of comparing the configurations, but I'm open to hearing other concrete suggestions! |
Right. The graphs for prediction quality are only those you put in there. The boxplot for prediction is not made yet. I was saying that we had three situations - old implementation, treat below cutoff as single label clusters, drop below cutoff. I think we can just use the one that treats below cutoff as single label clusters. Under this situation, the boxplot shows the h-score or cluster-to-trip-ratio for filter/no filter, cutoff/ no cutoff. Then we can say we determine to use no filter and no cutoff in order to keep more trips. I just check the way you compute the h-score, I don't think you have Could you check that again in case I made some mistake? |
Using but gave up exploring in detail due to lack of time.
I am not convinced by this because in that case, as I said in the notebook, there is effectively no difference in this metric between a similarity instance that drops trips below cutoff and one that does not. The metric is not meaningful to show anything important about the cluster quality. |
Please see the results for re-introducing the same mode #28 (comment) and #28 (comment) The related commit is corinne-hcr/e-mission-server@97921a9 |
Last few commits before we close out this PR:
|
So that @hlu109 can take over e-mission#28 (comment)
…private-data into tune_clustering_params
And add a README directing people to the README for my evaluation
@hlu109 I have committed all the pending changes on my laptop and moved the obsolete analyses out. I would suggest running through my notebooks here to understand the analysis step by step. |
So that @hlu109 can take over e-mission#28 (comment)
Primarily to understand why it is worse than the DBSCAN trip clustering code. As you may recall, the results for DBSCAN were pretty respectable. Most trips were in a cluster, and the median cluster : trip-in-cluster ratio was below 40% for all datasets. e-mission#28 (comment) Why is similarity so much worse than the DBSCAN-based clustering? Should we switch to DBSCAN instead (horrifying proposition given the tight deadline)? See the notebook conclusion to find out! @corinne-hcr, this is more on the lines of what I expected you to do back when you were evaluating the first round/common trips, and definitely when we were getting poor results with the clustering. + change the original DBSCAN notebook to have the modified viz code
@corinne-hcr more examples of what the initial analysis might have looked like. Build similarity models for: - 100, 300m, 500m - all combinations of filtering (yes/no) and cutoffs (yes/no) Generate labels for all labeled trips Determine ground truth by looking at: unique tuples and unique values for each of the user inputs Use these models to compute the metrics (homogeneity score and request %) for all combinations, along with a few other metrics like the number of unique tuples, cluster_trip_pct, etc. At this point, we are focusing on ground truth from tuples since the homogeneity score is already fairly high. What we really need to do is to bring down the request %, or determine *why* the user % is so high so that we can fix it (e.g. polygon). Some results in: e-mission#28 (comment)
Major changes were to integrate the functions from the "unrolled" exploration code into this notebook so that we could generalize the "oursim" results across multiple datasets as well. It also appeared that we were building all the models **twice** for reasons that I don't understand; unified it to build the models once. Also pulled out the summary statistics code into a separate cell, so we can experiment with it without having to re-run the models, which take significant time. Added several visualizations to visualize the findings, which are: - oursim and DBSCAN have similar request pct - oursim has higher homogeniety score than DBSCAN - we have lower noise and tighter models if we have 100+ labeled trips Visualizations at: e-mission#28 (comment) @corinne-hcr, at this point, I'm going to move on to actually implementing this in the pipeline so we can get some results before the next meeting on Tuesday.
Our current implementation of the h-score was incorrect because all the noisy trips were in the same `-1` bucket. e-mission#28 (comment) Experiment with two alternate handling methods, need to figure out which one to use e-mission#28 (comment)
…tion h-score calculation: Our current implementation of the h-score was incorrect because all the noisy trips were in the same `-1` bucket. e-mission#28 (comment) Experiment with two alternate handling methods, need to figure out which one to use e-mission#28 (comment) Improvements to h-score and request count calculation are consistent with the changes required for e-mission#28 (comment)
So that @hlu109 can take over e-mission#28 (comment)
So that @hlu109 can take over e-mission#28 (comment)
Finally compare dataset characteristics against each other