{ "info": { "author": "Stefan Binder", "author_email": "", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# hypernotes \n[![PyPI version](http://img.shields.io/pypi/v/hypernotes.svg?style=flat-square&color=blue)](https://pypi.python.org/pypi/hypernotes/) [![Python versions](https://img.shields.io/pypi/pyversions/hypernotes.svg?style=flat-square&color=blue)]()\n\nhypernotes is a lightweight Python package for taking notes on your machine learning experiments. It provides a simple way to store hyperparameters, their corresponding evaluation metrics, as well as additional information and retrieve them again later for analyzing. It is written in pure Python and requires no additional dependencies.\n\n# Table of contents \n- [Installation](#installation)\n- [Basic Usage](#basic-usage)\n - [Create note and add to store](#create-note-and-add-to-store)\n - [Load notes](#load-notes)\n - [Update notes](#update-notes)\n - [Remove notes](#remove-notes)\n - [Create note from another one](#create-note-from-another-one)\n- [Bonus](#bonus)\n - [View content of a store in your browser](#view-content-of-a-store-in-your-browser)\n - [Store additional objects](#store-additional-objects)\n- [Alternatives](#alternatives)\n- [Development](#development)\n\n[Changelog for this package](CHANGELOG.md)\n\n# Installation\n```bash\npip install hypernotes\n```\n\nPython 3.6+ is required\n\n# Basic Usage\nhypernotes implements a *Note* and a *Store* class. A *Note* is a small wrapper around Python dictionaries. This means that you can do everything with it, that you could do with a normal dictionary, but in addition, it stores:\n\n* the path to your Python executable,\n* information about the current state of your Git repository (if there is one) such as the last commit, current branch, etc.,\n* start (upon initialization) and end datetime (call note.end() or add to store)\n\nand it provides:\n\n* a useful default dictionary structure\n* access to all initial dictionary keys as attributes for better auto-completion support and readability (for example `note.parameters`, `note.features`)\n\nIf you print a note, you can see what's inside. A note right after initialization looks like this:\n```python\nNote(content={'text': '',\n 'model': None,\n 'parameters': {},\n 'features': {'identifier': [],\n 'binary': [],\n 'categorical': [],\n 'numerical': []},\n 'target': None,\n 'metrics': {},\n 'info': {},\n 'start_datetime': datetime.datetime(2019, 5, 21, 11, 3, 20),\n 'end_datetime': None,\n 'identifier': '3228fe02-d1c8-4251-8b35-bb8ae3d5f227',\n 'python_path': 'C:/example_path/python.exe',\n 'git': {'repo_name': 'C:/path_to_your_repo',\n 'branch': 'master',\n 'commit': '6bbdf31'}}\n```\n\nThe notes are then saved with a *Store* instance, which uses a json file. Due to this, you should only add [json-serializable objects](https://docs.python.org/3/library/json.html#py-to-json-table) + *datetime.datetime* instances to a *Note*.\n\nA note is uniquely identifiable by its `identifier` attribute.\n\n## Create note and add to store\n```python\nfrom hypernotes import Note, Store\n\nnote = Note(\"Some descriptive text about your experiment\")\n\n# Add name of used algorithm\nnote.model = \"randomforest\"\n\n# Add hyperparameters about model training, preprocessing, etc.\nnote.parameters[\"num_estimators\"] = 100\nnote.parameters[\"impute_missings\"] = True\n\n# Add the names of the features and of the target variable\nnote.features[\"identifier\"] = [\"id\"]\nnote.features[\"binary\"] = [\"bool1\"]\nnote.features[\"categorical\"] = [\"cat1\", \"cat2\"]\nnote.features[\"numerical\"] = [\"num1\"]\nnote.target = \"target\"\n\n# Some additional information\nnote.info[\"important_stuff\"] = \"something noteworthy\"\n\n# ... Rest of your code ...\n# train_recall, train_precision test_recall, test_precision = train_and_evaluate_model(\n# parameters=note.params,\n# feature_names=note.features,\n# target_name=note.target)\n# ...\n\n# Add your calculated evaluation metrics\nnote.metrics[\"train\"] = {\"recall\": train_recall, \"precision\": train_precision}\nnote.metrics[\"test\"] = {\"recall\": test_recall, \"precision\": test_precision}\n\nstore = Store(\"hyperstore.json\")\nstore.add(note)\n```\n\n## Load notes\nA Store instance provides the `load` method, which can be used to retrieve the whole store. By default it returns a sorted list (most recent note first).\n```python\nnotes = store.load()\nmost_recent_note = notes[0]\n```\n\nIf you have [pandas](https://github.com/pandas-dev/pandas) installed, you can use the `return_dataframe` argument to return a pandas dataframe.\n```python\nnotes_df = store.load(return_dataframe=True)\nnotes_df.head()\n```\nExample of a returned pandas dataframe:\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
start_datetimeend_datetimetextmodelidentifiermetrics.test.precisionmetrics.test.recallmetrics.train.precisionmetrics.train.recallparameters.min_sample_splitparameters.num_estimatorsparameters.sample_weightfeatures.binaryfeatures.categoricalfeatures.identifierfeatures.numericaltargetgit.branchgit.commitgit.repo_nameinfo.important_stuffpython_path
02019-05-21 16:44:482019-05-21 17:05:21Another useful descriptionrandomforest0f84217d-e01b-466d-9a73-001827c605840.290.290.400.507150None[bool1][cat1, cat2][id][num1]targetmaster5e098abC:/path_to_your_reposomething noteworthyC:/example_path/python.exe
12019-05-21 16:12:532019-05-21 16:30:16Useful descriptionrandomforestdd8bbc32-ff8f-433d-9eec-a24a7859622f0.820.290.910.987100balanced[bool1][cat1, cat2][id][num1]targetmaster5e098abC:/path_to_your_reposomething noteworthyC:/example_path/python.exe
\n\n## Update notes\nIf you want to update notes, you can do this either directly in the json file containing the notes, or load the notes as described above, change the relevant ones, and pass them to the `update` method.\n```python\nnotes = store.load()\nupdated_notes = []\nfor note in notes[:2]:\n note.info[\"something_new\"] = \"...\"\n updated_notes.append(note)\n\nstore.update(updated_notes)\n```\n\n## Remove notes\nIf you want to remove notes, you can do this either directly in the json file containing the notes, or load the notes as described above, and pass the ones which you want to remove to the `remove` method.\n```python\nnotes = store.load()\nnotes_to_remove = notes[:2]\nstore.remove(notes_to_remove)\n```\n\n## Create note from another one\nWhen evaluating multiple model parameters (e.g. in a grid search setup), you might find it useful to create a new note for each parameter set. To do this, you can use the `from_note` method to create a new note from an existing one. This takes over all existing content, but also sets a new start datetime and identifier. After creation, the notes are independent, i.e. modifying one will not affect the other.\n\n```python\noriginal_note = Note(\"Original\")\nnew_note = Note.from_note(original_note)\n```\n\n# Bonus\n## View content of a store in your browser\nTo get a quick glance into a store, you can use the package from the command line. It will start an http server and automatically open the relevant page in your web browser. The page contains an interactive table which shows the most relevant information of all notes in the store such as metrics and parameters. The table is similar in style to the one shown in the [Load notes](#load-notes) section.\n```\n$ python -m hypernotes hyperstore.json\n```\nThis only requires a modern web browser as well as an internet connection to load some javascript libraries and css files.\n\nTo see all available options pass the `--help` argument.\n\n## Store additional objects\nIf you want to store larger artifacts of your experiment, such as a trained model, you could create a separate folder and use the identifier of a note as part of the name.\n\n```python\nexperiment_folder = f\"experiment_{note.identifier}\"\n```\nYou can then store any additional objects into this folder and it will be very easy to lather on link them again to the hyperparameters and metrics stored using hypernotes.\n\n# Alternatives\nCheck out tools such as [MLflow](https://mlflow.org/), [Sacred](https://sacred.readthedocs.io/en/latest/index.html), or [DVC](https://dvc.org/) if you need better multi-user capabilities, more advanced reproducibility features, dataset versioning, ...\n\n# Development\nFeel free to open a GitHub issue or even better submit a pull request if you find a bug or miss a feature.\n\nAny requirements for developing the package can be installed with\n```\npip install -r requirements_dev.txt\n```\n\nMake sure that all tests run by tox pass.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/binste/hypernotes", "keywords": "machine learning,tracking,metrics,experiments,hyperparameters,model evaluation,data science", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "hypernotes", "package_url": "https://pypi.org/project/hypernotes/", "platform": "", "project_url": "https://pypi.org/project/hypernotes/", "project_urls": { "Homepage": "https://github.com/binste/hypernotes" }, "release_url": "https://pypi.org/project/hypernotes/2.0.2/", "requires_dist": null, "requires_python": ">=3.6", "summary": "A lightweight Python package for taking notes on your machine learning experiments", "version": "2.0.2" }, "last_serial": 5389898, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "195b50109832346a6bc3d35def70de58", "sha256": "b1a49ba8904b27b90b252c60a3d408f992ba6df5fe19d5761ed1cd46a1fe1233" }, "downloads": -1, "filename": "hypernotes-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "195b50109832346a6bc3d35def70de58", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 9533, "upload_time": "2019-05-12T13:16:51", "url": "https://files.pythonhosted.org/packages/7b/4a/f22cd195dab443e976b18cefd934fa23230d02040d88aed8e481b87d076f/hypernotes-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b09dacdc8eed96f58423e1a8939fe235", "sha256": "7846b28af7b50950f9403e2214c593cc5d64ef97e330a5963e5cb143f679d661" }, "downloads": -1, "filename": "hypernotes-0.1.0.tar.gz", "has_sig": false, "md5_digest": "b09dacdc8eed96f58423e1a8939fe235", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 9023, "upload_time": "2019-05-12T13:16:54", "url": "https://files.pythonhosted.org/packages/9a/b6/e60a1090c31a49e7c559f6842d9f59ce418ad7ac32198876b80d815bd05b/hypernotes-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "16d3fde485b3a073364335223929f239", "sha256": "c9e4edee8a15d85c3973bfd004bcc506e5b5dd79315eba951ffe30e2a73a7186" }, "downloads": -1, "filename": "hypernotes-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "16d3fde485b3a073364335223929f239", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 9688, "upload_time": "2019-05-12T15:21:45", "url": "https://files.pythonhosted.org/packages/11/6f/a9d50c681070a9d12d269562cdb8fea64c1ee2915cecee2a0ef18fae369f/hypernotes-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3af281a24d6b2365575b5bcf53218ec7", "sha256": "a278b7573cdfe5273ee5d25f14b608369d2dace5524d32345c6fec317254a9ed" }, "downloads": -1, "filename": "hypernotes-0.1.1.tar.gz", "has_sig": false, "md5_digest": "3af281a24d6b2365575b5bcf53218ec7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 9184, "upload_time": "2019-05-12T15:21:49", "url": "https://files.pythonhosted.org/packages/6c/05/644361520f0d88f64a079c40a6601291522007cf1e50bcc744d3acce559b/hypernotes-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "96e8a387888926062cd5902e9afddda4", "sha256": "2f56d9fd3fa5c791408565fbb0f03913c2599a7f3861ac0ecf8a44bbd2a6ba6d" }, "downloads": -1, "filename": "hypernotes-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "96e8a387888926062cd5902e9afddda4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11366, "upload_time": "2019-05-17T22:20:32", "url": "https://files.pythonhosted.org/packages/a5/a8/245eb96fb1d30f8d2457d73d677ff9b902e7b4147490a545707a4dad82ae/hypernotes-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3b79d324395786770741f5dd7c4d4ae7", "sha256": "3af2ef04b6599291608d56947502bbea3e69424f37806535f9fd4ee4e41d1107" }, "downloads": -1, "filename": "hypernotes-0.2.0.tar.gz", "has_sig": false, "md5_digest": "3b79d324395786770741f5dd7c4d4ae7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12132, "upload_time": "2019-05-17T22:20:36", "url": "https://files.pythonhosted.org/packages/b3/11/3f5c9ae4b2ff9bedcaa91e15457c860ff877c89e36eb6fc9cbe6540cef48/hypernotes-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "17ff40eef6b3ce789b56c63b8123d166", "sha256": "0bafaa8e91ba62a145e21c36c802e6933e65d57dff9c86f7b0a7e523d58b52ee" }, "downloads": -1, "filename": "hypernotes-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "17ff40eef6b3ce789b56c63b8123d166", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11866, "upload_time": "2019-05-19T09:29:09", "url": "https://files.pythonhosted.org/packages/e6/7e/8fada3e83a9b7d206c1773ffe3af5f9a1c8b532b908522b4a6cfed3e965d/hypernotes-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0839a44776a7024fe51335fb7e05b53b", "sha256": "01bc74edcfc95cf8e3f892a61427986bc3effcaf6e77d9c660fa66ffb54dd7f5" }, "downloads": -1, "filename": "hypernotes-0.3.0.tar.gz", "has_sig": false, "md5_digest": "0839a44776a7024fe51335fb7e05b53b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12750, "upload_time": "2019-05-19T09:29:14", "url": "https://files.pythonhosted.org/packages/48/32/26d62797cbb1e30ab0718dff0050337d09c321ec91f28c4e7b412c6da559/hypernotes-0.3.0.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "8adc3aa2078857e6dab2d74b7ab2ebe9", "sha256": "06b4137c5e40f9a45959ab0ada7dad7b98d8da2cbd446055ecddfd3311a976ac" }, "downloads": -1, "filename": "hypernotes-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8adc3aa2078857e6dab2d74b7ab2ebe9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 12624, "upload_time": "2019-05-21T17:09:58", "url": "https://files.pythonhosted.org/packages/87/10/03c345fc5b97ef86d559b41a8bd9ef975d01f59e413f3f238dabc23a349b/hypernotes-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "00382e9e6fc26c21577124a1056dbb13", "sha256": "ef4d2188201f9da1107b0e0d6a7c38d98ecd80f40a6ee23df3c51e3db636d5b4" }, "downloads": -1, "filename": "hypernotes-1.0.0.tar.gz", "has_sig": false, "md5_digest": "00382e9e6fc26c21577124a1056dbb13", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 14470, "upload_time": "2019-05-21T17:10:04", "url": "https://files.pythonhosted.org/packages/53/d2/717394c6c0e2d9011b209496462f3f5c4da8fd813e488f9a830e904764e5/hypernotes-1.0.0.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "3efc5ff05eb7b1e73c0f1ec144d69960", "sha256": "3b6ffe74cb896227cae8bd25404420537591ff9d7a68a8352d2eae5af11a38e1" }, "downloads": -1, "filename": "hypernotes-2.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "3efc5ff05eb7b1e73c0f1ec144d69960", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13508, "upload_time": "2019-05-25T12:15:42", "url": "https://files.pythonhosted.org/packages/24/85/a01d9531d9ec80f5a130c70dc2be6455296de37fe092234c1e6ba9a27aed/hypernotes-2.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d637b1b2d20185bdf9dd4088c30bfa5", "sha256": "e13c1fedbc4d5241950b9731775f1e6f105b4d6dbd180620230aad6e73cca0ef" }, "downloads": -1, "filename": "hypernotes-2.0.0.tar.gz", "has_sig": false, "md5_digest": "9d637b1b2d20185bdf9dd4088c30bfa5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 15719, "upload_time": "2019-05-25T12:15:48", "url": "https://files.pythonhosted.org/packages/fd/f1/f61afaaeafd9a196e9a023c895bf16b9502678401384cb22cfd0271189e9/hypernotes-2.0.0.tar.gz" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "cd8649b604c8bf58194a1b182777eb99", "sha256": "7c6051dc9a0680bb79b82f91ec9a013a437f0789acc93d4ba191d502e3837886" }, "downloads": -1, "filename": "hypernotes-2.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "cd8649b604c8bf58194a1b182777eb99", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13639, "upload_time": "2019-05-30T09:03:36", "url": "https://files.pythonhosted.org/packages/3c/dc/8e5c67ba6cc438d6ef1b3e41e284b6c79db38a38377bd590af00602e6c12/hypernotes-2.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "87cc3ac0ba2b7e547a170bc0f1c193b3", "sha256": "780f1465459c8a6b7bfb566b7c751580bb278735adedd309ef63dea28c7d5052" }, "downloads": -1, "filename": "hypernotes-2.0.1.tar.gz", "has_sig": false, "md5_digest": "87cc3ac0ba2b7e547a170bc0f1c193b3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 15974, "upload_time": "2019-05-30T09:03:44", "url": "https://files.pythonhosted.org/packages/e1/d0/3ea8abe6a1ddfb7576adbc1308bbc84d1147bcaf4e225d2470fb71dd80f3/hypernotes-2.0.1.tar.gz" } ], "2.0.2": [ { "comment_text": "", "digests": { "md5": "731fc13c4db8303bdbe986498771e5b1", "sha256": "17e37c12fe40a7f02c34020478b2bc92519084deea1197ffb1ac7140e66131f1" }, "downloads": -1, "filename": "hypernotes-2.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "731fc13c4db8303bdbe986498771e5b1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13729, "upload_time": "2019-06-12T07:29:34", "url": "https://files.pythonhosted.org/packages/f5/3e/fe523b3ae79d7d142a49fa15a35959390eaf9947995f42f74c40a39cc7a5/hypernotes-2.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "924472ee91a00bbc2abc7da538b6fecd", "sha256": "576bfe7c7dd5055d714b256b2e69731551d000a086440071763d0ff3a0a8fdbb" }, "downloads": -1, "filename": "hypernotes-2.0.2.tar.gz", "has_sig": false, "md5_digest": "924472ee91a00bbc2abc7da538b6fecd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 15997, "upload_time": "2019-06-12T07:29:42", "url": "https://files.pythonhosted.org/packages/7f/d1/599994b308cc747e9120ef0f3e7b87fc4e4a1184f6d40c049b3ec6db1e8e/hypernotes-2.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "731fc13c4db8303bdbe986498771e5b1", "sha256": "17e37c12fe40a7f02c34020478b2bc92519084deea1197ffb1ac7140e66131f1" }, "downloads": -1, "filename": "hypernotes-2.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "731fc13c4db8303bdbe986498771e5b1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13729, "upload_time": "2019-06-12T07:29:34", "url": "https://files.pythonhosted.org/packages/f5/3e/fe523b3ae79d7d142a49fa15a35959390eaf9947995f42f74c40a39cc7a5/hypernotes-2.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "924472ee91a00bbc2abc7da538b6fecd", "sha256": "576bfe7c7dd5055d714b256b2e69731551d000a086440071763d0ff3a0a8fdbb" }, "downloads": -1, "filename": "hypernotes-2.0.2.tar.gz", "has_sig": false, "md5_digest": "924472ee91a00bbc2abc7da538b6fecd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 15997, "upload_time": "2019-06-12T07:29:42", "url": "https://files.pythonhosted.org/packages/7f/d1/599994b308cc747e9120ef0f3e7b87fc4e4a1184f6d40c049b3ec6db1e8e/hypernotes-2.0.2.tar.gz" } ] }