{ "info": { "author": "haminiku", "author_email": "haminiku1129@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "Collaborative Filtering Real Time Recommender Engine\n====================================================\n\nIt is a collaborative filtering type RealTime recommendation engine of open source that has been implemented in Python. The Amazon provides a \"Customers who bought this product Customers who bought this product also purchased\" function and, function similar to the \"recommended users\" feature of Twitter.\n\n- \u65e5\u672c\u8a9e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8: `Japanese Document`_\n\nFeatures\n--------\n- get fast within 10ms\n- Real time updating recommendation list \n- easy install\n- High versatility\n- Tags Support\n\nInstallation\n-----------------\n\n.. code-block:: bash\n\n $ pip install cf_recommender\n\nSample Code\n-----------------\n\n.. code-block:: python\n\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n \n cf_settings = {\n # redis\n 'expire': 3600 * 24 * 30,\n 'redis': {\n 'host': 'localhost',\n 'port': 6379,\n 'db': 0\n },\n # recommendation engine settings\n 'recommendation_count': 10,\n 'recommendation': {\n 'update_interval_sec': 600,\n 'search_depth': 100,\n 'max_history': 1000,\n },\n }\n \n \n # Get recommendation list\n item_id = 'Item1'\n recommendation = Recommender(cf_settings)\n print recommendation.get(item_id, count=3)\n >>> ['Item10', 'Item3', 'Item2']\n \n # register history\n user_id = 'user-00001'\n buy_items = ['Item10', 'Item10', 'Item10', 'Item3', 'Item3', 'Item1']\n for item_id in buy_items:\n recommendation.register(item_id)\n recommendation.like(user_id, buy_items)\n\n\n ...\n\nRecommendation Algorithms\n---------------------------------------------------\nDetermine the recommendation target by simple co-occurrence. Ratings are often items will be highly appreciated. For example, among the Item1-10, 51% of 100 people user the purchase history of Item10, when the remaining 49% were bought at random, then appeared Item10 with a high probability as the top recommendation of Item1-9.\n\nConcrete example\n************************************\n\nWe will mention about the logic to determine the recommendation subject to the specific case of Item-3. Expand the latest Item3 purchase user on the 100 persons memory, to create a product purchase list by referring to the latest purchase history 100 cases of purchase user. From the total of items purchased covers the entire history and register as a recommendation subject to the order. The depth of the search can be changed in settings.recommendation.search_depth. default value is set to 100. When the epidemic is shifted Item1 is purchased in large quantities history is updated Item1 will now appear as the top recommendation. The depth of the search it will affect the transition speed of the product to be recommended. Please tune so that it is appropriate recommendation which the product will seek.\n\nTutorial\n---------------------------------------------------\n\n1. you want to install the 1.redis to local PC.\n2. start the 2.redis.\n3. In 3.redis-cli command I do communication confirmation.\n\n.. code-block:: bash\n\n (env)niku > redis-cli\n redis 127.0.0.1:6379> set a 1\n OK\n redis 127.0.0.1:6379> get a\n \"1\"\n\n4. install a cf-recommender\n\n.. code-block:: bash\n\n $ pip install cf_recommender\n\n5. Create and run a py file written sample code\n\n.. code-block:: bash\n\n (env)niku > python cf.py \n []\n ['Item10', 'Item3', 'Item2']\n (env)niku > python cf.py \n ['Item10', 'Item3', 'Item2']\n ['Item10', 'Item3', 'Item2']\n\n\nSettings\n-----------------\n\n.. image:: https://qiita-image-store.s3.amazonaws.com/0/65312/7329c185-0015-02b9-98fb-e3abc62be6b0.png\n :alt: HTTPie compared to cURL\n :align: center\n\nRedis Data structure\n----------------------------------\n\n.. image:: https://qiita-image-store.s3.amazonaws.com/0/65312/4bb5c5d4-a7b0-3a5e-1b30-854377cf75a1.png\n :alt: HTTPie compared to cURL\n :align: center\n\n\nSample1 Django: Player to Player Recommendation \n-----------------------------------------------------------------\n\n.. code-block:: python\n\n # Django - Model\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n from django.conf import settings\n\n\n class GuildRecommendation(object):\n cf = None\n\n def __init__(self):\n self.cf = Recommender(settings.ANALYTICS_REDIS_SETTINGS)\n\n def like(self, player_id, guild_ids):\n \"\"\"\n :param player_id: str\n :param guild_ids: list of int\n \"\"\"\n for guild_id in guild_ids:\n self.cf.register(guild_id)\n self.cf.like(player_id, guild_ids)\n\n def gets(self, guild_id, count=5):\n return self.cf.get(guild_id, count=count)\n\n.. code-block:: python\n\n # Django - View\n # register\n GuildRecommendation().like(player.id, [guild_id])\n\n # get recommendation guild\n GuildRecommendation().gets(guild_id, count=20)\n >>> [8, 4, 3]\n\n\nSample2 Item Remove and Item Update Tag\n-----------------------------------------------------------------\n\n.. code-block:: python\n\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n\n\n r = Recommender(settings={})\n\n user_id = \"user1\"\n goods_id = \"Item1\"\n\n \"\"\"\n Purchase information of the user is deleted from INDEX, also INDEX to the user as garbage data \n if some exist {recommendation.max_history} or more, however the user's purchase \n history of the user's purchase history is deleted history does not already exist continue remaining purchase history\n \"\"\"\n r.remove_user(user_id)\n\n r.remove_goods(goods_id)\n r.update_goods_tag(goods_id, \"book\")\n\n\n\nSample3-1 Published from accumulating the data\n-----------------------------------------------------------------\n\n.. code-block:: python\n\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n\n # register\n user_id = 'user-00001'\n buy_items = ['Item10', 'Item10', 'Item10', 'Item3', 'Item3', 'Item1']\n for item_id in buy_items:\n recommendation.register(item_id)\n recommendation.like(user_id, buy_items)\n\n\nSample3-2 Registered in the bulk data\n-----------------------------------------------------------------\n\n.. code-block:: python\n\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n import random\n\n\n # register all goods\n tags = ['default', 'book', 'computer', 'dvd', 'camera', 'clothes', 'tag7', 'tag8', 'tag9', 'tag10']\n settings = {}\n r = Recommender(settings=settings)\n goods_ids = range(1, 1000)\n for goods_id in goods_ids:\n r.register(goods_id, tag=random.choice(tags))\n\n # register all users history \n users = {\n 'player1': [100, 200, 300],\n 'player2': [100, 200, 300],\n 'player3': [200, 300, 500],\n 'player4': [500, 600, 700],\n 'player5': [300, 400, 500],\n }\n\n ct = 0\n for user_id in users:\n like_goods_ids = users.get(user_id)\n # register by not updating recommendation\n r.like(user_id, like_goods_ids, realtime_update=False)\n if ct % 100 == 0:\n print \"{}/{}\".format(str(ct), str(len(users)))\n ct += 1\n\n # create index heavy memory use\n r.recreate_all_index()\n\n # create all recommendation about [100-500ms x item count]\n r.update_all()\n\n\nSample4 Worker Model\n-----------------------------------------------------------------\n\nWhen implemented in the worker model can be updated to distribute the products list that recommendation. The update of the whole recommendation list needs time items x100~500ms. In order to remove the deleted items from the recommendation list of other goods it was implemented because it requires re-generation of the total recommendation list. Also it can be calculated by distributing the listing generated for recommendation when new installations, it is assumed to be used when collectively changing the tag information of the product.\n\n.. image:: https://qiita-image-store.s3.amazonaws.com/0/65312/14dc0f4d-85e2-69db-34c8-467a9adcb299.png\n :alt: HTTPie compared to cURL\n :align: center\n\n.. code-block:: python\n\n # -*- coding: utf-8 -*-\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n\n # register\n user_id = 'user-00001'\n buy_items = ['Item10', 'Item10', 'Item10', 'Item3', 'Item3', 'Item1']\n for item_id in buy_items:\n recommendation.register(item_id)\n # update by not updating recommendation\n recommendation.like(user_id, buy_items, realtime_update=False)\n\n.. code-block:: python\n\n # worker 1\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n Recommender(settings).update_all(scope=(0, 4))\n\n.. code-block:: python\n\n # worker 2\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n Recommender(settings).update_all(scope=(1, 4))\n\n.. code-block:: python\n\n # worker 3\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n Recommender(settings).update_all(scope=(2, 4))\n\n.. code-block:: python\n\n # worker 4\n from __future__ import absolute_import, unicode_literals\n from cf_recommender.recommender import Recommender\n Recommender(settings).update_all(scope=(3, 4))\n\n\nIf you move the worker in supervisord it moves to feel good. scope = (0, 4) and 4 split all items list that was sort When set to update the recommendation list according to the goods in the first half of the quarter.\n\nTuning Recommendation\n----------------------------------\n\n1. I want to enable real-time update feature\n The default setting real-time update feature is turned OFF. Please be set to 0. To 'recommendation.update_interval_sec' to enable. However, whether the APP server at the time of the spike to secure sufficient resources because there is likely to die, please set the update interval to 5 seconds.\n\n2. changes immediately goods to be recommended\n Please strengthen the history search of past direction by increasing to the To calm 'recommendation.search_depth' changes. However CPU load for calculation time is extended will increase.\n\n3. Product is recommended does not update quickly\n Please set a short update interval of the product that is recommended by changing the 'recommendation.update_interval_sec'. The default value is 10 minutes.\n\n4. I want to add a long time ago were popular items in the list recommend\n It can be achieved by extending the 'recommendation.search_depth and recommendation.max_history'. When the change since there is a possibility that the calculation time is extended big Please execute enough test. To generate a recommendation list in the worker as implementation 4 as a measure of computational time bloated, there is a way to stop the real-time update.\n\n\nTrouble Shooting\n----------------------------------\n\n1. App Server CPU 100%\n \n 'Recommender.like' is the recommendation is likely that takes time in the Product List generation process in the function. Let's review the following settings.\n\n a. 'recommendation.update_interval_sec' of the extended time to raise the update interval.\n\n b. Reduce the value of 'recommendation.search_depth', we want to reduce the amount of calculation when the commodity list generation that recommendation.\n\n2. Over Redis max memory \n\n a. lower the value of 'expire'. When the period expires, goods list to recommendation that has not been read even once during the period will be deleted.\n\n b. it reduces the value of the 'recommendation.max_history'. Past purchase history that overflowed is lost.\n\n\nBench Mark\n-----------------\n\n.. image:: https://qiita-image-store.s3.amazonaws.com/0/65312/d68405e8-900d-1dab-b92e-bc0df8ac08a7.png\n :alt: HTTPie compared to cURL\n :align: center\n\n.. image:: https://qiita-image-store.s3.amazonaws.com/0/65312/6e6810eb-d9d3-959e-9561-5a04ea7d3edc.png\n :alt: HTTPie compared to cURL\n :align: center\n\n\nDocumentation\n-----------------\n\n\n- `Japanese Document`_ in Qiita\n\n.. _`Japanese Document`: http://qiita.com/haminiku/items/0cdf006d667ef8a7494e\n.. _`PayPal here`: http://subc.github.io/payment/cf_recommender.html", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/subc/cf_recommender", "keywords": "recommendation,recommender,cf,Collaborative,Collaborative Filtering", "license": "MIT License", "maintainer": null, "maintainer_email": null, "name": "cf_recommender", "package_url": "https://pypi.org/project/cf_recommender/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/cf_recommender/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/subc/cf_recommender" }, "release_url": "https://pypi.org/project/cf_recommender/1.0.1/", "requires_dist": null, "requires_python": null, "summary": "Real Time Recommendation System of Collaborative Filtering", "version": "1.0.1" }, "last_serial": 2065236, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "5a3420a30895b375196a5b29e51d18ce", "sha256": "00aad9bedc81198e1a01b7b3ea09bedbb410e10f502f4249f5d51f9108307ddc" }, "downloads": -1, "filename": "cf_recommender-0.0.1.tar.gz", "has_sig": false, "md5_digest": "5a3420a30895b375196a5b29e51d18ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5412, "upload_time": "2015-10-28T11:17:58", "url": "https://files.pythonhosted.org/packages/c7/35/aa2491bb1316efa622c161dc8086ea646f330f4827d0016e3560695828aa/cf_recommender-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "3fc9e0b6263f5c8198d70b9481f6123a", "sha256": "f5177c02736a18be7b49ca3df5a4e1723d6dcc436a510eb67ca9b360b23fc87a" }, "downloads": -1, "filename": "cf_recommender-0.0.2.tar.gz", "has_sig": false, "md5_digest": "3fc9e0b6263f5c8198d70b9481f6123a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5415, "upload_time": "2015-10-28T11:38:36", "url": "https://files.pythonhosted.org/packages/a7/4a/f2777cdc2a34926587584d46a9f91e8796f166961bf96b742a8ee1ebd4cd/cf_recommender-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "2f209381f54dae5d5cb26dfdc3721406", "sha256": "1e024913b5837d83bbbac837958ed9c5b89ce2baa35dfcda6801e21e8b4cab1a" }, "downloads": -1, "filename": "cf_recommender-0.0.3.tar.gz", "has_sig": false, "md5_digest": "2f209381f54dae5d5cb26dfdc3721406", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5500, "upload_time": "2015-10-28T11:53:05", "url": "https://files.pythonhosted.org/packages/c9/2e/c99b98c523f1d1f6a356241c3d0abb8b7e9d3b103a06d0217497594d4d2d/cf_recommender-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "5c9c743129cae43a043c213199927c03", "sha256": "8f275ce84c980ef413ca508fda05df09033e2930d3d722ee8fc27bb144f77ab8" }, "downloads": -1, "filename": "cf_recommender-0.0.4.tar.gz", "has_sig": false, "md5_digest": "5c9c743129cae43a043c213199927c03", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5498, "upload_time": "2015-10-28T12:38:41", "url": "https://files.pythonhosted.org/packages/62/ff/0f02e136fb3959e1a3e8569b4ffbc4140758ea394a4507dbe0efc263d071/cf_recommender-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "1b84cdaff1ef0622e7fdd9c00d08ba80", "sha256": "6879e9e373dcd0534fa331dc5949d38bd522306a712772c11abb09fa2ff656b8" }, "downloads": -1, "filename": "cf_recommender-0.0.5.tar.gz", "has_sig": false, "md5_digest": "1b84cdaff1ef0622e7fdd9c00d08ba80", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5511, "upload_time": "2015-10-28T14:22:35", "url": "https://files.pythonhosted.org/packages/a9/0f/3af4e58b953d38e24a96f56a0a7ac1044154604e8dd7c5bccbf5edf7472a/cf_recommender-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "915f8b99b855ef11c6ec2f9311c33ce5", "sha256": "a5afeacc3a68c72255ce82debb21648d98ed60b5e44177fee26aad1d8b7641e1" }, "downloads": -1, "filename": "cf_recommender-0.0.6.tar.gz", "has_sig": false, "md5_digest": "915f8b99b855ef11c6ec2f9311c33ce5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5504, "upload_time": "2015-10-28T14:50:57", "url": "https://files.pythonhosted.org/packages/cc/8a/4f0378c3243cff5189eaf9fb251f12a43e83b6861aa0d1458e7d996edb0f/cf_recommender-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "3ba53b7ff00e72b6385d90e04be5fb00", "sha256": "8f3495bb42f38ef96d4084807101758c23fdca249932100f94d27ae4f13db001" }, "downloads": -1, "filename": "cf_recommender-0.0.7.tar.gz", "has_sig": false, "md5_digest": "3ba53b7ff00e72b6385d90e04be5fb00", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6527, "upload_time": "2015-10-30T01:10:34", "url": "https://files.pythonhosted.org/packages/a2/b4/e9f0f59427e161b26142fedf74d8dbb24ae1f6d9d15ba620cbb3a76d81b1/cf_recommender-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "3aee50b4bfe35520204ee4cecff957c7", "sha256": "c72747c87cc3264692d2c1633df72def237944b341c3b10d800b76ff5ee5ea4f" }, "downloads": -1, "filename": "cf_recommender-0.0.8.tar.gz", "has_sig": false, "md5_digest": "3aee50b4bfe35520204ee4cecff957c7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10085, "upload_time": "2015-10-30T12:46:52", "url": "https://files.pythonhosted.org/packages/be/26/e91cf4478c57cc2396526420006ad8cd8e7233ae380a9f3fbd7fa9f85c26/cf_recommender-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "277a3d6b2ce9edcc364028c19b0da7d7", "sha256": "de78bea7ead8986ed969d2015a61ded3e92ffbbe9a3d33349a6e54474aaa30f9" }, "downloads": -1, "filename": "cf_recommender-0.0.9.tar.gz", "has_sig": false, "md5_digest": "277a3d6b2ce9edcc364028c19b0da7d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10087, "upload_time": "2016-03-17T10:41:06", "url": "https://files.pythonhosted.org/packages/ff/d1/e99583c49491392d76708f40adf9ffd4fcf27d360fb696080cdf09063119/cf_recommender-0.0.9.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "37807e7235d767ccb06d61bc13b79058", "sha256": "c570fb5551936d7f9665077ae9238f9c9f76b4a69f742cca63b3682ea4575805" }, "downloads": -1, "filename": "cf_recommender-1.0.0.tar.gz", "has_sig": false, "md5_digest": "37807e7235d767ccb06d61bc13b79058", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10136, "upload_time": "2016-03-17T10:44:42", "url": "https://files.pythonhosted.org/packages/b8/08/2310a0f30d433afa6f618136490a8cbf85707daac359812ec1fe588e163f/cf_recommender-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "c044ade26d6c6f97a9ec0499673d3609", "sha256": "38f6a77ee6729049c0c7b369c0793be6fab4fd0b91fd08bfd3039ae6750bc73d" }, "downloads": -1, "filename": "cf_recommender-1.0.1.tar.gz", "has_sig": false, "md5_digest": "c044ade26d6c6f97a9ec0499673d3609", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9830, "upload_time": "2016-04-15T10:27:51", "url": "https://files.pythonhosted.org/packages/71/68/473f4cbd17159a09b4c4d538ea93d81dafcc3721a2b0e133d2e1ecf40210/cf_recommender-1.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c044ade26d6c6f97a9ec0499673d3609", "sha256": "38f6a77ee6729049c0c7b369c0793be6fab4fd0b91fd08bfd3039ae6750bc73d" }, "downloads": -1, "filename": "cf_recommender-1.0.1.tar.gz", "has_sig": false, "md5_digest": "c044ade26d6c6f97a9ec0499673d3609", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9830, "upload_time": "2016-04-15T10:27:51", "url": "https://files.pythonhosted.org/packages/71/68/473f4cbd17159a09b4c4d538ea93d81dafcc3721a2b0e133d2e1ecf40210/cf_recommender-1.0.1.tar.gz" } ] }