Git Product home page Git Product logo

taar's Introduction

Taar

Telemetry-Aware Addon Recommender

CircleCI

Table of Contents

How does it work?

The recommendation strategy is implemented through the RecommendationManager. Once a recommendation is requested for a specific client id, the recommender iterates through all the registered models (e.g. CollaborativeRecommender) linearly in their registered order. Results are returned from the first module that can perform a recommendation.

Each module specifies its own sets of rules and requirements and thus can decide if it can perform a recommendation independently from the other modules.

Supported models

This is the ordered list of the currently supported models:

Order Model Description Conditions Generator job
1 Collaborative recommends add-ons based on add-ons installed by other users (i.e. collaborative filtering) Telemetry data is available for the user and the user has at least one enabled add-on source
2 Similarity recommends add-ons based on add-ons installed by similar representative users Telemetry data is available for the user and a suitable representative donor can be found source
3 Locale recommends add-ons based on the top addons for the user's locale Telemetry data is available for the user and the locale has enough users source
4 Ensemble * recommends add-ons based on the combined (by stacked generalization) recomendations of other available recommender modules. More than one of the other Models are available to provide recommendations. source

All jobs are scheduled in Mozilla's instance of Airflow. The Collaborative, Similarity and Locale jobs are executed on a daily schedule, while the ensemble job is scheduled on a weekly schedule.

Build and run tests

You should be able to build taar using Python 3.5 or 3.7. To run the testsuite, execute ::

$ python setup.py develop
$ python setup.py test

Alternately, if you've got GNUMake installed, a Makefile is included with build and test-container targets.

You can just run make build; make test-container which will build a complete Docker container and run the test suite inside the container.

Pinning dependencies

TAAR uses miniconda and a environment.yml file to manage versioning.

To update versions, edit the environment.yml with the new dependency you need then run make conda_update.

If you are unfamiliar with using conda, see the official documentation for reference.

Instructions for releasing updates to production

Building a new release of TAAR is fairly involved. Documentation to create a new release has been split out into separate instructions.

Dependencies

Google Cloud Storage resources

The final TAAR models are stored in:

gs://moz-fx-data-taar-pr-prod-e0f7-prod-models

The TAAR production model bucket is defined in Airflow under the variable taar_etl_model_storage_bucket

Temporary models that the Airflow ETL jobs require are stored in a temporary bucket defined in the Airflow variable taar_etl_storage_bucket

Recommendation engines load models from GCS.

The following table is a complete list of all resources per recommendation engine.

Recommendation Engine GCS Resource
RecommendationManager Whitelist gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/addon_recommender/only_guids_top_200.json.bz2
Similarity Recommender gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/similarity/donors.json.bz2
gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/similarity/lr_curves.json.bz2
CollaborativeRecommender gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/addon_recommender/item_matrix.json.bz2
gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/addon_recommender/addon_mapping.json.bz2
LocaleRecommender gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/locale/top10_dict.json.bz2
EnsembleRecommender gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/ensemble/ensemble_weight.json.bz2
TAAR lite gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/lite/guid_install_ranking.json.bz2
gs://moz-fx-data-taar-pr-prod-e0f7-prod-models/taar/lite/guid_coinstallation.json.bz2

Production environment variables required for TAAR

Collaborative Recommender

Env Variable Value
TAAR_ITEM_MATRIX_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAAR_ITEM_MATRIX_KEY "addon_recommender/item_matrix.json.bz2"
TAAR_ADDON_MAPPING_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAAR_ADDON_MAPPING_KEY "addon_recommender/addon_mapping.json.bz2"

Ensemble Recommender

Env Variable Value
TAAR_ENSEMBLE_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAAR_ENSEMBLE_KEY "taar/ensemble/ensemble_weight.json.bz2"

Locale Recommender

Env Variable Value
TAAR_LOCALE_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAAR_LOCALE_KEY "taar/locale/top10_dict.json.bz2"

Similarity Recommender

Env Variable Value
TAAR_SIMILARITY_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAAR_SIMILARITY_DONOR_KEY "taar/similarity/donors.json.bz2"
TAAR_SIMILARITY_LRCURVES_KEY "taar/similarity/lr_curves.json.bz2"

TAAR Lite

Env Variable Value
TAARLITE_GUID_COINSTALL_BUCKET "moz-fx-data-taar-pr-prod-e0f7-prod-models"
TAARLITE_GUID_COINSTALL_KEY "taar/lite/guid_coinstallation.json.bz2"
TAARLITE_GUID_RANKING_KEY "taar/lite/guid_install_ranking.json.bz2"

Google Cloud Platform resources

Google Cloud BigQuery

Cloud BigQuery uses the GCP project defined in Airflow in the variable taar_gcp_project_id.

Dataset

  • taar_tmp

Table ID

  • taar_tmp_profile

Note that this table only exists for the duration of the taar_weekly job, so there should be no need to manually manage this table.

Google Cloud Storage

The taar user profile extraction puts Avro format files into a GCS bucket defined by the following two variables in Airflow:

  • taar_gcp_project_id
  • taar_etl_storage_bucket

The bucket is automatically cleared at the start and end of the TAAR weekly ETL job.

Google Cloud BigTable

The final TAAR user profile data is stored in a Cloud BigTable instance defined by the following two variables in Airflow:

  • taar_gcp_project_id
  • taar_bigtable_instance_id

The table ID for user profile information is taar_profile.


Production Configuration Settings

Production environment settings are stored in a private repository.

Deleting individual user data from all TAAR resources

Deletion of records in TAAR is fairly straight forward. Once a user disables telemetry from Firefox, all that is required is to delete records from TAAR.

Deletion of records from the TAAR BigTable instance will remove the client's list of addons from TAAR. No further work is required.

Removal of the records from BigTable will cause JSON model updates to no longer take the deleted record into account. JSON models are updated on a daily basis via the taar_daily

Updates in the weekly Airflow job in taar_weekly only update the ensemble weights and the user profile information.

If the user profile information in clients_last_seen continues to have data for the user's telemetry-id, TAAR will repopulate the user profile data.

Users who wish to remove their data from TAAR need to:

  1. Disable telemetry in Firefox
  2. Have user telemetry data removed from all telemetry storage systems in GCP. Primarily this means the clients_last_seen table in BigQuery.
  3. Have user data removed from BigTable.

Airflow environment configuration

TAAR requires some configuration to be stored in Airflow variables for the ETL jobs to run to completion correctly.

Airflow Variable Value
taar_gcp_project_id The Google Cloud Platform project where BigQuery temporary tables, Cloud Storage buckets for Avro files and BigTable reside for TAAR.
taar_etl_storage_bucket The Cloud Storage bucket name where temporary Avro files will reside when transferring data from BigQuery to BigTable.
taar_etl_model_storage_bucket The main GCS bucket where the models are stored
taar_bigtable_instance_id The BigTable instance ID for TAAR user profile information
taar_dataflow_subnetwork The subnetwork required to communicate between Cloud Dataflow

Staging Environment

The staging environment of the TAAR service in GCP can be reached using curl.

curl https://user@pass:stage.taar.nonprod.dataops.mozgcp.net/v1/api/recommendations/<hashed_telemetry_id>

Requests for a TAAR-lite recommendation can be made using curl as well:

curl https://stage.taar.nonprod.dataops.mozgcp.net/taarlite/api/v1/addon_recommendations/<addon_guid>/

TAARlite cache tools

There is a taarlite-redis tool to manage the taarlit redis cache.

The cache needs to be populated using the --load command or TAARlite will return no results.

It is safe to reload new data while TAARlite is running - no performance degradation is expected.

The cache contains a 'hot' buffer for reads and a 'cold' buffer to write updated data to.

Subsequent invocations to --load will update the cache in the cold buffer. After data is successfully loaded, the hot and cold buffers are swapped.

Running the the taarlite-redis tool inside the container:

$ docker run -it taar:latest bin/run python /opt/conda/bin/taarlite-redis.py --help

Usage: taarlite-redis.py [OPTIONS]

  Manage the TAARLite redis cache.

  This expecte that the following environment variables are set:

  REDIS_HOST REDIS_PORT

Options:
  --reset  Reset the redis cache to an empty state
  --load   Load data into redis
  --info   Display information about the cache state
  --help   Show this message and exit.

Testing

TAARLite will respond with suggestions given an addon GUID.

A sample URL path may look like this:

/taarlite/api/v1/addon_recommendations/uBlock0%40raymondhill.net/

TAAR will treat any client ID with only repeating digits (ie: 0000) as a test client ID and will return a dummy response.

A URL with the path : /v1/api/recommendations/0000000000/ will return a valid JSON result

A note on cdist optimization.

cdist can speed up distance computation by a factor of 10 for the computations we're doing. We can use it without problems on the canberra distance calculation.

Unfortunately there are multiple problems with it accepting a string array. There are different problems in 0.18.1 (which is what is available on EMR), and on later versions. In both cases cdist attempts to convert a string to a double, which fails. For versions of scipy later than 0.18.1 this could be worked around with:

distance.cdist(v1, v2, lambda x, y: distance.hamming(x, y))

However, when you manually provide a callable to cdist, cdist can not do it's baked in optimizations (https://github.com/scipy/scipy/blob/v1.0.0/scipy/spatial/distance.py#L2408) so we can just apply the function distance.hamming to our array manually and get the same performance.

taar's People

Contributors

birdsarah avatar crankycoder avatar dexterp37 avatar eu9ene avatar florian avatar jasonthomas avatar maurodoglio avatar mlopatka avatar mozilla-github-standards avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

taar's Issues

Rework the hybrid recommendations

We are reworking the addon recommendations where some addons which need to be promoted regardless of whatever recommendations TAAR returns.

We'll need to sync with amo team to determine how we want this to be implemented.

Our requirements are that we must be able to definitively know the set of addons displayed to the user so that we can measure TAAR efficacy.

Fix s3 file cache

It looks like we have a bug here. The last with block should be out of the if not os.path.exists... block

TAAR v.3 add-on is wrongly installed and functional on profiles out of the 2 to 30 days lifespan

[Affected versions]:

  • Firefox Beta 61.0b2

[Affected Platforms]:

  • All Windows
  • All Linux
  • All Mac

[Prerequisites]:

  • Have a new Firefox profile with the latest version of the "TAAR v3" add-on installed (downloaded from https://bugzilla.mozilla.org/show_bug.cgi?id=1469546).
  • Create the following prefs in the "about:config" page:
    "shieldStudy.logLevel" as string and set it to "All";
    "extensions.taarexpv3_shield_mozilla_org.test.variationName" as string and set it to "control", "intervention-a" or "intervention-b"

[Steps to reproduce]:

  1. Open the browser with the profile from prerequisites.
  2. Navigate to three websites and observe the behavior.

[Expected result]:

  • The TAAR pop-up is not triggered.

[Actual result]:

  • The TAAR pop-up is triggered.

[Notes]:

  • This is also reproducible with profiles older than 30 days.
  • Attached a screen recording of the issue:

fresh profile

Remove all uses of client_id and use a hashed telemetry ID

The telemetry ID is being deprecated in favor of a sha256 hashed ID.

Rename variables from client_id toclient_hash in taar for clarity.

Update all ETL jobs in python_mozetl related to TAAR to compute and use hashes instead of raw telemetry client ID.

Refactor the caching system

The main idea is to use a cache object passed to the RecommendationManager instead of reinventing the wheel. This object will be passed by taar api and it will likely be powered by the django cache system.

Augment taar service logging to enable comparision of recommendations vs installation

We need to land a patch into to log events detailing :

  • hashed telemetry id
  • which addons were recommended

The intent is to be able to compare the main telemetry data which shows all addon installations vs the add-ons which we presents to a particular Firefox instance.

We need to be able to run analytics to compare organic vs suggested installations. Note that this depends on #117

Create recommender instances lazily

The recommender manager should not create instances of its recommenders until it's necessary. Some of the recommenders may have expensive code in their constructors and we can avoid running that code when either the user_info is not available or when the first recommender can recommend.

TAAR performance needs to be measured automatically

The fullstack call time for TAAR seems to have gone up substantially - or at least it's much more variable comparing TAARv2 and TAARv3

Screenshots below from New Relic show very consistent performance ~70 ms for TAARv2 and variation between 60ms to 120ms for TAARv3.

I suspect this is the probably because of the way we're generating the random sample of add-on suggestions from the whitelist. We currently randomly shuffle the whitelist and pop items off the end which isn't the smartest thing in the world.

Performance profiling will give us definitive answers to this but as a first attempt, we should probably just store an index into the shuffled whitelist array and just treat the array as a circular buffer and read items off as random add-on suggestions.

More importantly, we should try to get an automated performance benchmark where we can spin up webheads in the dev enviroment and throw a load test and snapshot the metrics out of New Relic so we don't have surprise regressions in performance.

taar_v2_overview

taar_api__prod__-_new_relic

`python setup.py test` fails

(taar) {13:33}~/Dev/mozilla/taar:crankycoder-features/issue-65 ✓ ➭ python setup.py test
zip_safe flag not set; analyzing archive contents...

Installed /home/bird/Dev/mozilla/taar/.eggs/pytest_runner-4.0-py2.7.egg
Searching for setuptools_scm
Reading https://pypi.python.org/simple/setuptools_scm/
Downloading https://pypi.python.org/packages/76/6e/3ba3d9c3409af4375b6c4512f78423381e9ed99375e7791586189207ea6a/setuptools_scm-1.15.7-py2.7.egg#md5=4385ebde52ea23f85fb490acb902095e
Best match: setuptools-scm 1.15.7
Processing setuptools_scm-1.15.7-py2.7.egg
Moving setuptools_scm-1.15.7-py2.7.egg to /home/bird/Dev/mozilla/taar/.eggs

Installed /home/bird/Dev/mozilla/taar/.eggs/setuptools_scm-1.15.7-py2.7.egg
running pytest
Traceback (most recent call last):
  File "setup.py", line 36, in <module>
    zip_safe=False,
  File "/home/bird/miniconda3/envs/taar/lib/python2.7/distutils/core.py", line 151, in setup
    dist.run_commands()
  File "/home/bird/miniconda3/envs/taar/lib/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/home/bird/miniconda3/envs/taar/lib/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "build/bdist.linux-x86_64/egg/ptr.py", line 157, in run
  File "build/bdist.linux-x86_64/egg/ptr.py", line 118, in install_dists
AttributeError: class test has no attribute 'install_dists'

This was run on py2.7

Use fixtures for mock data

recent test added uses a const for mock data and one test updates it which means that it will be changed for other tests.

using a fixture would give fresh data each test to manipulate at will

Make cached model files expire

The off-line recommender jobs produce JSON blobs that get consumed by TAAR. These JSON files are refreshed/updated weekly.

We should make sure that, if a file is downloaded and cached by TAAR and a new version is available, the refreshed model is used.

Adjust recommender field in RecommenderManager log message

This is a sample log line that is produced by https://github.com/mozilla/taar/blob/master/taar/recommenders/recommendation_manager.py#L52

{"EnvVersion":"2.0","Severity":6,"Fields":{"message":"Recommender selected","recommender":"<taar.recommenders.collaborative_recommender.CollaborativeRecommender object at 0x7f98287cbc18>","client_id":"<snip>"},"Hostname":"ip-172-31-34-129","Pid":19,"Timestamp":"2017-09-27 19:52:23","Logger":"taar_api","Type":"taar.recommenders.recommendation_manager"}

It would be nice if recommender field only returned the class name rather then the full object info. It should make querying the data easier.

some taar tests in python_mozetl seem to be intermittently failing

This started happening sometime in the last week or so, here's an example log:

https://circleci.com/gh/mozilla/python_mozetl/70#tests/containers/4

This may be related to a pyspark upgrade:

mozilla/python_mozetl@0b97226

Note that upgrade actually just keeps the version we're using for testing in sync with the one we're using in production, so we really want to fix the root cause here rather than just revert versions.

For now I've filed a PR to temporarily disable the failing tests:

mozilla/python_mozetl#253

The "TAAR v3" shield study wrongly works on an ineligible Firefox build

Also logged in Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1471216


[Affected versions]:

  • Firefox Beta (61.0) locales other than en-Us, en-GB, de, fr, ru, pt-BR, es-ES, pl, it, ar, ja.

[Affected Platforms]:

  • All Windows
  • All Linux
  • All Mac

[Prerequisites]:

  • Have a new Firefox profile with the latest version of the "TAAR v3" add-on (downloaded from https://bugzilla.mozilla.org/show_bug.cgi?id=1469546) installed.
  • Create the following prefs in the "about:config" page:
    • "shieldStudy.logLevel" as string and set it to "All";
    • "extensions.taarexpv3_shield_mozilla_org.test.variationName" as string and set it to "control", "intervention-a" or "intervention-b"

[Steps to reproduce]:

  1. Open the browser with the profile from prerequisites.
  2. Navigate to three websites and observe the behavior.

[Expected result]:

  • The websites are correctly opened.

[Actual result]:

  • A "File not found" doorhanger is opened on the third website.

[Notes]:

  • Also, the shield study's pings are displayed in the Browser Console and on the "about:telemetry" page.
  • Attached a screen recording of the issue:
    rec of the issue

EnsembleRecommender needs a filter to remove addon GUIDs that are already installed

The Ensemble Recommender has a unique behavior that does not exist in the existing Collaborative, Legacy, Locale and Similarity recommenders.

Ensemble recommender can recommend addon GUIDs that are already installed by the user.

We need to filter out GUIDs just prior to applying the limit to constrain the number of recommendations.

Add documentation on how to run tests

We should really document the sequence of commands needed in order to run the tests locally, from installing the dependencies and running the tests.

Embed taar-lite as a recommendation module

We want to be able to use taar-lite as a recommendation engine within TAAR's ensemble recommender.

This means:

  • adapt taar-lite to be an ETL job to generate recommendation graphs
  • generate a list of recommendation lists for each of the addons that are installed by a particular client

Merging the list of lists by weight should be relatively straightforward. Merging duplicate recommendations should more heavily weight those particular GUIDs but we have no predefined merge method yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.