
منذ وقت ليس ببعيد ، عقدت مسابقة أنظمة التوصية من سينما
Okko عبر الإنترنت -
Rekko Challenge 2019 على منصة
Boosters . بالنسبة لي كانت أول تجربة للمشاركة في مسابقة مع المتصدرين (سبق لي أن حاولت القوة فقط في hackathon). المهمة مثيرة للاهتمام ومألوفة بالنسبة لي من الناحية العملية ، هناك صندوق جائزة ، مما يعني أنه من المنطقي المشاركة. ونتيجة لذلك ، احتلت المركز الرابع عشر ، حيث أصدر المنظمون قميصًا تذكاريًا. لطيفة. شكرا لك
في هذه المقالة ، سوف أغمرك في هذه المهمة لفترة وجيزة ، وأتحدث عن الفرضيات التي طرحتها ، فضلاً عن كيفية جر المنافسة في أنظمة التوصية والدخول في المراكز الخمسة عشر الأولى دون تكديس خبرة ، والتي ستكون مفيدة بشكل خاص لأولئك الذين سيشاركون فقط في المسابقات.
نظم التوصية
الهدف الرئيسي من أنظمة التوصية هو إعطاء المستخدم ما
يريد شراءه (لسوء الحظ ، يتم فرض مثل هذه النظرة متضخمة على التطبيق التجاري).
هناك عبارات مختلفة للمهام (الترتيب ، والبحث عن تلك المشابهة ، والتنبؤ بعنصر معين) ، وبالتالي ، طرق لحلها. حسنًا ، نحن جميعًا نحب التباين في الاختيار ، والذي توفره مجموعة من الحلول المحتملة المتعددة لكل مشكلة. تم توضيح الطرق المختلفة في مقالة "
تشريح أنظمة التوصية" . بالطبع ، لم يقم أحد بإلغاء
نظرية اتحاد كرة القدم الأميركي ، مما يعني أنه في المشكلة التنافسية ، يمكننا تجربة خوارزميات مختلفة.
بيان المشكلة
اقرأ المزيد عن المهمة والبيانات الموجودة في
المقالة بواسطة المنظمين. TL ؛ DR هنا سأصف الحد الأدنى الضروري لفهم السياق.
تحتوي مجموعة البيانات على أكثر من عشرة آلاف فيلم بسمات مجهولة المصدر. تتوفر الخيارات التالية كمصفوفات تفاعل عنصر المستخدم:
- المعاملات - تحتوي على حقائق للمستخدمين الذين يشترون المحتوى / التأجير / المشاهدة عن طريق الاشتراك ؛
- التقييمات - تصنيفات الأفلام من قبل المستخدمين ؛
- الإشارات المرجعية - حدث إضافة فيلم إلى الإشارات المرجعية
يتم أخذ جميع المعلومات على مدى فترة زمنية محددة ، والتي يتم تقديمها في وحدات تعسفية مرتبطة بواقعي.
احتوى المحتوى على مجموعة السمات التالية:

يمكنك أن تقرأ عنها بالتفصيل في المقال من قبل المنظمين ، لكنني أريد أن أنبه على الفور إلى ما لفت انتباهي: المعلمة "السمات". أنه يحتوي على حقيبة من السمات الفئوية مع أصل حوالي 36 ألف. كان هناك ما معدله 15 قيمة لكل فيلم. للوهلة الأولى ، يتم تشفير فقط السمات الأساسية التي تصف المحتوى في هذه القيم: الممثلون أو المخرجون أو البلد أو الاشتراكات أو المجموعات التي ينتمي إليها الفيلم.
من الضروري التنبؤ بـ 20 فيلمًا سيشاهدها المستخدمون خلال الشهرين المقبلين. اختبار المستخدمين 50 ألف من جميع المستخدمين 500 ألف. في لوحة المتصدرين ، يتم تقسيمهم إلى نصفين: 25 ألف لكل عام / خاص.
متري
اختار المنظمون متوسط تطبيع الدقة على 20 عنصرًا (MNAP @ 20) كمقياس. يتمثل الاختلاف الرئيسي عن خطة MAP المعتادة في أنه بالنسبة للمستخدمين الذين لم يشاهدوا 20 فيلمًا في فترة الاختبار ، لا يحدث التقنين على k ، ولكن على القيمة الفعلية للأفلام التي تمت مشاهدتها.

اقرأ المزيد وشاهد الرمز في Cython
هنا.التحقق من صحة
الوصول إلى حل المشكلة. بادئ ذي بدء ، كان من الضروري تقرير ما تم التحقق منه. نظرًا لأننا نحتاج إلى التنبؤ بالأفلام في المستقبل ، لا يمكننا إجراء توزيع بسيط بواسطة المستخدمين. نظرًا لكون الوقت مجهول الهوية ، فقد اضطررت للبدء على الأقل في فك تشفيره على الأقل تقريبًا. للقيام بذلك ، أخذت عدة مستخدمين ، وأعدت جدولًا للمعاملات وكشفت عن موسمية معينة. كان من المفترض أنه يوميًا ، ومع معرفة فارق التوقيت بين الأيام ، يمكننا حساب الفترة التي تم تحميل البيانات فيها. اتضح أن هذه كانت المعاملات لمدة 6 أشهر. تم تأكيد ذلك لاحقًا في قناة التلغراف حيث تمت مناقشة المسابقة.

يوضح الرسم البياني أعلاه معدل تكرار المعاملات بالساعة باستخدام بيانات مدتها شهر واحد كمثال. تتشابه ثلاث قمم بارزة كل أسبوع مع أمسيات الجمعة والسبت والأحد.
وبالتالي ، لدينا ستة أشهر من المشاهدة ، ويجب التنبؤ بالأفلام في الشهرين التاليين. سنستخدم الثلث الأخير من وقت عينة التدريب كمجموعة بيانات للتحقق من الصحة.

أظهرت التقديمات القليلة التالية أن الانقسام تم اختياره جيدًا وأن سرعة التحقق المحلية مرتبطة بشكل ممتاز بلوحة المتصدرين.
محاولة إلغاء تحديد هوية البيانات
بادئ ذي بدء ، قررت محاولة إلغاء تحديد هوية جميع الأفلام ، بحيث:
- توليد مجموعة من العلامات عن طريق المعلومات الوصفية للمحتوى. على الأقل ، يتبادر إلى ذهن الأشخاص التاليين: الأنواع ، الممثلون ، الاشتراك في الاشتراكات ، وصف النص ، إلخ.
- رمي في فرن التفاعلات من الجانب للحد من تباعد المصفوفة. نعم ، لم تحظر قواعد المنافسة استخدام البيانات الخارجية. بالطبع ، لم يكن هناك أمل في المباراة مع مجموعات البيانات المفتوحة ، لكن لم يلغ أحد تحليل بوابات البوابات الروسية.
يبدو أن هناك دافعًا منطقيًا ، وفقًا لتوقعاتي ، كان ليصبح حلاً متميزًا.
بادئ ذي بدء ، قررت تحليل موقع Okko وسحب جميع الأفلام مع خصائصها (التصنيف ، المدة ، القيود العمرية وغيرها). حسنًا ، كيفية التحليل - كل شيء أصبح بسيطًا ، في هذه الحالة ، يمكنك استخدام واجهة برمجة التطبيقات:

بعد الدخول في الكتالوج واختيار نوع معين أو اشتراك ، كان عليك فقط الدخول في أي عنصر من العناصر. استجابةً للطلب أعلاه ، فإن المجموعة الكاملة من الأفلام في النوع / الاشتراك مع جميع السمات تتساقط. مريح جدا :)
لذلك بدت سمات عنصر واحد في الهيكل"element": { "id": "c2f98ef4-2eb5-4bfd-b765-b96589d4c470", "type": "SERIAL", "name": " ", "originalName": " ", "covers": {...}, "basicCovers": {...}, "description": " , ...", "title": null, "worldReleaseDate": 1558731600000, "ageAccessType": "16", "ageAccessDescription": "16+ 16 ", "duration": null, "trailers": {...}, "kinopoiskRating": 6, "okkoRating": 4, "imdbRating": null, "alias": "staraja-gvardija", "has3d": false, "hasHd": true, "hasFullHd": true, "hasUltraHd": false, "hasDolby": false, "hasSound51": false, "hasMultiAudio": false, "hasSubtitles": false, "inSubscription": true, "inNovelty": true, "earlyWindow": false, "releaseType": "RELEASE", "playbackStartDate": null, "playbackTimeMark": null, "products": { "items": [ { "type": "PURCHASE", "consumptionMode": "SUBSCRIPTION", "fromConsumptionMode": null, "qualities": [ "Q_FULL_HD" ], "fromQuality": null, "price": { "value": 0, "currencyCode": "RUB" }, "priceCategory": "679", "startDate": 1554670800000, "endDate": null, "description": null, "subscription": { "element": { "id": "bc682dc6-c0f7-498e-9064-7d6cafd8ca66", "type": "SUBSCRIPTION", "alias": "119228" } }, "offer": null, "originalPrice": null }, ... ], "emptyReason": null }, "licenses": null, "assets": {...}, "genres": { "items": [ { "element": { "id": "Detective", "type": "GENRE", "name": "", "alias": "Detective" } }, ... ], "totalSize": 2 }, "countries": { "items": [ { "element": { "id": "3b9706f4-a681-47fb-918e-182ea9dfef0b", "type": "COUNTRY", "name": "", "alias": "russia" } } ], "totalSize": 1 }, "subscriptions": { "items": [ { "element": { "id": "bc682dc6-c0f7-498e-9064-7d6cafd8ca66", "type": "SUBSCRIPTION", "name": " ", "alias": "119228" } }, ... ], "totalSize": 7 }, "promoText": null, "innerColor": null, "updateRateDescription": null, "contentCountDescription": null, "copyright": null, "subscriptionStartDate": null, "subscriptionEndDate": null, "subscriptionActivateDate": null, "stickerText": null, "fullSeasonPriceText": null, "purchaseDate": null, "expireDate": null, "lastWatchedChildId": null, "bookmarkDate": null, "userRating": null, "consumeDate": null, "lastStartingDate": null, "watchDate": null, "startingDate": null, "earlyWatchDate": null }
يبقى أن نستعرض كل الأنواع ، أعمل تحليل JSON ، ثم سمح بالنسخ المكررة ، حيث يمكن أن ينتمي فيلم واحد إلى عدة أنواع / اشتراكات.
نعم ، لقد كنت محظوظًا ووفرت الكثير من الوقت. إذا لم تكن هذه هي حالتك ، وتحتاج إلى تحليل محتوى html ، فهناك مقالات على المحور يمكن أن تساعدك في هذا ، على سبيل المثال ،
هنا .
"لقد كانت القبعة ،" فكرت ، "لا يمكننا إلا كبحها." "النقطة المهمة هي القبعة" ، أدركت في اليوم التالي: لم تكن البيانات مطابقة تمامًا. عن ذلك أدناه.
أولاً ، كان حجم الكتالوج مختلفًا بشكل كبير: في مجموعة البيانات - 10،200 ، التي تم جمعها من الموقع - 8870. هذا يتبع من تاريخ مجموعة البيانات: تم تنزيله فقط على ما هو موجود الآن على الموقع وبيانات المنافسة لعام 2018. أصبحت بعض الأفلام غير متوفرة. عفوا.
ثانياً ، من السمات المحتملة للمباراة كان الحدس المستمر فقط حول ما يلي:
feature5 - الحد الأدنى للسن. كان من السهل بما فيه الكفاية لفهم. العلاقة الأساسية للسمة هي 5 قيم تعويم فريدة و "-1". من بين البيانات التي تم جمعها ، تم العثور على السمة "ageAccessType" برمز 5 فقط.
catalogue.age_rating = catalogue.age_rating.map({0: 0, 0.4496666915: 6 0.5927161087: 12 0.6547073468: 16 0.6804096966000001: 18})
ميزة 2 - تحويل الفيلم من تصنيف البحث الفيلم. في البداية ، في مرحلة EDA ، تم تقديم فكرة أننا نتعامل مع التصنيف من خلال ارتباط المعلمة مع إجمالي عدد المشاهدات. في وقت لاحق ، أكد الاعتقاد بأن هذا التصنيف كان من خلال بحث فيلم وجود المعلمة "kinopoiskRating" في بيانات الموقع.
خطوة واحدة أقرب إلى المباراة! يبقى الآن العثور على طريقة لعكس التحويل لمعلمة
feature2 المقدمة في نموذج مجهول.
إليك ما يبدو عليه توزيع القيم في
ميزة 2 :

وبالتالي فإن توزيع قيم المعلمات
kinopoiskRating :

عندما عرضت هذه الصور لزميلي ساشا ، رأى على الفور أن هذه كانت درجة من ثلاث. لا يتم احترام ثلاثة علماء رياضيات ، ولكن الرقم Pi متساوٍ للغاية. نتيجة لذلك ، اتضح مثل هذا:

يبدو أن كل شيء ، ولكن ليس تماما. نرى توزيعات متطابقة ، لكن القيم الاسمية والكمية لا تزال غير متقاربة. إذا كنا نعرف عددًا معينًا من أمثلة المقارنة ، فستبقى تقريبًا وظيفة خطية للعثور على العامل. ولكن لم يكن لدينا لهم.
للتقريب ، بالمناسبة ، ليست الكلمة الأكثر ملاءمة. نحن بحاجة إلى حل مع وجود خطأ يساوي تقريبًا الصفر. الدقة في البيانات التي تم جمعها هي 2 أحرف بعد الفاصل. إذا كنت تعتقد أن هناك الكثير من الأفلام بمعدل 6.xx وهناك أفلام بنفس التصنيف ، فعليك الكفاح من أجل الدقة هنا.
ماذا يمكنك أن تجرب؟ يمكنك الاعتماد على الحد الأدنى والحد الأقصى للقيم واستخدام MinMaxScaler ، لكن عدم موثوقية هذه الطريقة تثير الشكوك على الفور. اسمحوا لي أن أذكركم بأن عدد الأفلام لم يتزامن في البداية ، وأن مجموعة البيانات الخاصة بنا تاريخية ، والحالة الراهنة على الموقع. أي لا توجد ضمانات بأن الأفلام التي لها تصنيفات الحد الأدنى والحد الأقصى في كلا المجموعتين متطابقة (اتضح أن لديهم قيودًا مختلفة بحسب العمر ، ولم تتقارب المدة من كلمة "تمامًا") ، بالإضافة إلى عدم فهم عدد المرات التي يتم فيها تحديث OKKO في API يوميا تغيير تصنيف البحث الفيلم.
لذلك أصبح من الواضح أنني بحاجة إلى المزيد من المرشحين للامتياز.
ماذا هو مثير للاهتمام؟ميزة 1 هو نوع من التاريخ. نظريًا ، بالنسبة للتواريخ ، وعد المنظمون بالحفاظ على الفصل بين الولايات ، مما يعني ضمناً وظيفة خطية. بشكل عام ، كان يجب أن يكون التحويل مطابقًا لسمة
ts لمصفوفات التفاعل. إذا نظرت إلى توزيع الأفلام حسب
الميزة_1 ...

... ثم يتم على الفور فرضية تاريخ إصدار الفيلم. يشير الحدس إلى أن عدد الأفلام التي تنتجها الصناعة يجب أن يزداد بمرور الوقت. وأكد هذا أدناه.
هناك 14 سمة في البيانات التي تلقيناها من الموقع. في الواقع ، للأسف ، تم احتواء القيم فقط لما يلي:



لا يشبه أي من الأمثلة المذكورة أعلاه
ميزة_1 . حسنًا ، لم تكن هناك أفكار أخرى للمقارنة ، ويبدو أن كل هذه الضجة حول هذه المهمة كانت بلا جدوى. بالطبع ، سمعت عن المسابقات ، حيث قام الشباب بترميز البيانات يدويًا ، ولكن ليس عندما يتعلق الأمر بمئات وآلاف النسخ.
قرار
1. نماذج بسيطةمع إدراك أنه ليس كل شيء بسيطًا جدًا ، بدأت العمل بكل تواضع مع ما هو عليه. بالنسبة للمبتدئين ، أردت أن أبدأ بكل بساطة. جربت العديد من الحلول المستخدمة غالبًا في الصناعة ، وهي:
التصفية التعاونية (في حالتنا القائمة على العنصر)
وعوامل المصفوفات .
يستخدم المجتمع على نطاق واسع عددًا من مكتبات python المناسبة لهذه المهام:
الضمنية و
LightFM . أول واحد قادر على العوملة بناءً على ALS ، وكذلك أقرب تصفية جماعية متجاورة مع العديد من الخيارات للمعالجة المسبقة لمصفوفة عنصر العنصر. الثاني له عاملان مميزان:
- يعتمد التخصيم على SGD ، مما يتيح استخدام وظائف الخسارة القائمة على أخذ العينات ، بما في ذلك WARP .
- يستخدم أسلوبًا مختلطًا ، يجمع بين معلومات حول سمات المستخدم وعناصره في النموذج بطريقة تجعل المتجه الكامن للمستخدم هو مجموع المتجهات الكامنة في سماته. وبالمثل للعناصر. يصبح هذا النهج مناسبًا للغاية عندما تكون هناك مشكلة في البدء البارد للمستخدم / العنصر.
ليس لدينا أي سمات مستخدم (بصرف النظر عن القدرة على عرضها بناءً على التفاعل مع الأفلام) ، لذلك استخدمت فقط سمات العناصر.
في المجموع ، ذهب 6 إعدادات لتعداد المعلمات. تم استخدام مزيج من ثلاثة مصفوفات كمصفوفة التفاعل ، حيث تم تحويل التصنيفات إلى ثنائي. نتائج المقارنة مع أفضل البارامترات لكل إعداد في الجدول أدناه.
كما ترون ، أثبتت التصفية التعاونية الكلاسيكية أنها أفضل بكثير من الموديلات الأخرى. ليست مثالية ، ولكن الكثير غير مطلوب من خط الأساس. يقدم مع هذا التكوين أعطى 0.03048 على المتصدرين العامة. لا أتذكر هذا الموقف في ذلك الوقت ، لكن في وقت اختتام المسابقة ، سيكون هذا التقديم بالتأكيد قد حقق أفضل 80 نقطة وقدم ميدالية برونزية.
2. مرحبا تعزيزماذا يمكن أن يكون أفضل من نموذج واحد؟ صحيح: عدة نماذج.
لذلك ، كان الخيار التالي هو المجموعة أو ، في سياق التوصيات ، نموذج تصنيف للمستوى الثاني. كنهج ، أخذت
هذه المقالة من اللاعبين من Avito. يبدو أنه يطبخ بدقة وفقا للوصفة ، مع التحريك الدوري والتوابل مع سمات الأفلام. كان الانحراف الوحيد هو عدد المرشحين: لقد حصلت على أفضل 200 من LightFM ، لأنه مع 500000 مستخدم ، أكثر بساطة لم تنسجم مع الذاكرة.
نتيجة لذلك ، كانت السرعة التي حصلت عليها عند التحقق من صحة أسوأ من نموذج واحد.
بعد عدة أيام من التجربة ، جاء الإدراك أنه لا يوجد شيء يعمل ولن يعمل أي شيء بمفرده. أو لا أعرف كيف أطبخها (المفسد: الإجابة الصحيحة الثانية). ماذا أفعل الخطأ؟ جاء سببان إلى الذهن:
- فمن ناحية ، يعتبر أخذ أفضل 200 من نموذج المستوى الأول معقولًا من وجهة نظر إنشاء عينات "سلبية سالبة" ، أي تلك الأفلام التي لها صلة أيضًا بالمستخدم ، ولكن لا يشاهدها. من ناحية أخرى ، يمكن مشاهدة بعض هذه الأفلام خلال فترة الاختبار ، ونقدم هذه الأمثلة سلبية. بعد ذلك ، قررت تقليل مخاطر هذه الحقيقة ، وإعادة فحص الفرضية من خلال التجربة التالية: أخذت كل الأمثلة الإيجابية + عشوائيًا لعينة التدريب. لم تتحسن سرعة عينة الاختبار. من الضروري هنا توضيح أنه في أخذ العينات في الاختبار ، كانت هناك أيضًا أفضل التنبؤات من نموذج المستوى الأول ، لأنه في لوحة المتصدرين لن يخبرني كل الأمثلة الإيجابية.
- من بين 10200 فيلم متوفر في الكتالوج ، قام 8296 فيلما فقط بإجراء أي تفاعل. تم حرمان ما يقرب من 2000 فيلم من انتباه المستخدم ، ويعزى ذلك جزئيًا إلى عدم توفرها للشراء / التأجير / كجزء من الاشتراك. سأل الرجال في الدردشة عما إذا كانت الأفلام التي يتعذر الوصول إليها يمكن أن تصبح متاحة في فترة الاختبار. الجواب كان نعم. من المستحيل بالتأكيد طردهم. لذلك ، اقترحت أن يتوفر حوالي 2000 فيلم إضافي في الشهرين المقبلين. خلاف ذلك ، لماذا رميهم في مجموعة البيانات؟
3. الخلايا العصبيةمن الفقرة السابقة تم طرح السؤال التالي: كيف يمكننا العمل مع الأفلام التي لا توجد فيها تفاعلات على الإطلاق؟ نعم ، نتذكر ميزات العنصر في LightFM ، ولكن كما نتذكر ، فإنها لم تدخل. ماذا بعد؟ Neyronki!
تحتوي ترسانة المصادر المفتوحة على عدد من المكتبات رفيعة المستوى ذات الشعبية العالية للعمل مع أنظمة التوصية:
Spotlight من Maciej Kula (مؤلف LightFM) و
TensorRec . الأول تحت غطاء محرك السيارة PyTorch ، والثاني - Tensorflow.
يمكن أن يسلط الضوء على مجموعات البيانات الضمنية / الواضحة مع الخلايا العصبية وتسلسل النماذج. في الوقت نفسه ، لا توجد طريقة لإضافة ميزات مستخدم / عنصر ، في عملية التهيئة "خارج الصندوق".
على النقيض من ذلك ، فإن TensorRec لا يعرف إلا كيفية تحديد العوامل ويعد إطارًا مثيرًا للاهتمام:
- رسم بياني للتمثيل - طريقة للتحويل (يمكن ضبطه بشكل مختلف للمستخدم / العنصر) لبيانات الإدخال في التضمين ، بناءً على العمليات الحسابية في الرسم البياني للتنبؤ. يتكون الاختيار من طبقات لها خيارات تنشيط مختلفة. من الممكن أيضًا استخدام فئة مجردة والعصا في تحويل مخصص ، يتكون من سلسلة من طبقات keras.
- يسمح لك الرسم البياني للتنبؤ باختيار العملية في النهاية: المنتج النقطي المفضل ، والمسافة الإقليدية وجيب التمام.
- خسارة - هناك أيضا الكثير للاختيار من بينها. كنا سعداء بتنفيذ WMRB (أساسا نفس WARP ، يعرف فقط كيفية تعلم دفعة وتوزع)
الأهم من ذلك ، TensorRec قادر على العمل مع ميزات سياقية ، وبالفعل يعترف المؤلف أنه استلهم في الأصل من فكرة LightFM. حسنا ، دعنا نرى. نأخذ التفاعلات (المعاملات فقط) وميزات العنصر.
نرسل للبحث عن التكوينات المختلفة والانتظار. مقارنةً بـ LightFM ، يستغرق التدريب والتحقق وقتًا طويلاً.
بالإضافة إلى ذلك ، كان هناك بعض الإزعاجات التي يجب مواجهتها:
- من تغيير علامة المطوّل ، لم تغير طريقة الملاءمة أي شيء ولم يتم توفير عمليات رد اتصال لك. اضطررت إلى كتابة وظيفة تم تدريبها داخليًا في حقبة ما باستخدام طريقة fit_partial ، ثم أجريت عملية التحقق من الصحة للتدريب والاختبار (في كلتا الحالتين ، استخدمت العينات لتسريع العملية).
- بشكل عام ، مؤلف الإطار هو زميل كبير ويستخدم tf.SparseTensor في كل مكان. ومع ذلك ، يجدر أن نفهم أنه كتنبؤ ، بما في ذلك التحقق من الصحة ، تحصل على النتيجة كثيفة كمتجه ذي طول n_items لكل مستخدم. يتبع نصيحتان: إنشاء دورة لتوليد تنبؤات باستخدام الدُفعات (طريقة المكتبة لا تحتوي على مثل هذه المعلمة) مع تصفية k الأعلى وإعداد الشرائح باستخدام ذاكرة الوصول العشوائي.
في النهاية ، في أفضل خيار للتكوين ، تمكنت من الضغط على 0.02869 في عينة الاختبار الخاصة بي. كان هناك شيء مشابه لـ LB.
حسنًا ، ماذا أتمنى؟ أن إضافة غير الخطية إلى ميزات العنصر سوف يعطي زيادة مضاعفة في القياس؟ إنه ساذج.
4. بيك هذه المهمةلذا انتظر لحظة. يبدو أنني واجهت مرة أخرى في الخلايا العصبية شعوذة. ما الفرضية التي كنت أرغب في اختبارها عند تولي هذا العمل؟ كانت الفرضية: "في الشهرين التاليين من الاختيار المتأخر ، سيتم عرض ما يقرب من 2000 فيلم جديد على لوحة المتصدرين. بعضهم سيأخذ نصيبًا كبيرًا من وجهات النظر ".
حتى تتمكن من التحقق من ذلك في خطوتين:
- سيكون من الجميل أن نرى عدد الأفلام التي أضفناها في فترة الاختبار المنقسم عليها بصدق فيما يتعلق بالقطار. إذا أخذنا فقط وجهات النظر ، فإن الأفلام "الجديدة" هي فقط 240 (!). هزت الفرضية على الفور. يبدو أن شراء محتوى جديد لا يمكن أن يختلف بهذا المبلغ من فترة إلى أخرى.
- ننتهي. لدينا الفرصة لتدريب النموذج على استخدام العرض التقديمي فقط استنادًا إلى ميزات العنصر (في LightFM ، على سبيل المثال ، يتم ذلك افتراضيًا ، إذا لم نقم مسبقًا بملء مصفوفة السمة بمصفوفة الهوية). علاوة على ذلك ، من أجل الضيق ، يمكننا تقديم هذا النموذج فقط (!) أفلامنا التي يتعذر الوصول إليها ولم نرها من قبل. من هذه النتائج ، نرسل ونحصل على 0.0000136.
البنغو! هذا يعني أنه يمكنك إيقاف الضغط على الدلالات خارج سمات الفيلم. بالمناسبة ، في وقت لاحق ، في DataFest ، قال شباب من OKKO إن معظم المحتوى الذي يتعذر الوصول إليه كان مجرد بعض الأفلام القديمة.
تحتاج إلى تجربة شيء جديد ، وجديد - قديم طي النسيان. في حالتنا ، لم ينس تماما ، ولكن ما حدث قبل بضعة أيام. تصفية التعاونية؟
5. لحن الخط الأساسيكيف يمكنني مساعدة خط الأساس CF؟
الفكرة رقم 1على الإنترنت ، وجدت عرضًا تقديميًا حول استخدام اختبار نسبة الاحتمال لتصفية الأفلام الثانوية.
أدناه ، سأترك شفرة الثعبان لحساب درجة LLR ، والتي كان علي أن أكتبها على ركبتي لاختبار هذه الفكرة.
حساب LLR import numpy as np from scipy.sparse import csr_matrix from tqdm import tqdm class LLR: def __init__(self, interaction_matrix, interaction_matrix_2=None): interactions, lack_of_interactions = self.make_two_tables(interaction_matrix) if interaction_matrix_2 is not None: interactions_2, lack_of_interactions_2 = self.make_two_tables(interaction_matrix_2) else: interactions_2, lack_of_interactions_2 = interactions, lack_of_interactions self.num_items = interaction_matrix.shape[1] self.llr_matrix = np.zeros((self.num_items, self.num_items))
نتيجة لذلك ، يمكن استخدام المصفوفة الناتجة كقناع لترك التفاعلات الأكثر أهمية فقط وهناك خياران: استخدام العتبة أو ترك عناصر top-k ذات القيمة الأعلى. بنفس الطريقة ، يتم استخدام مجموعة من التأثيرات المتعددة على عملية الشراء بسرعة واحدة لترتيب العناصر ، بمعنى آخر ، يُظهر الاختبار مدى أهميته ، على سبيل المثال ، إضافة إلى المفضلة فيما يتعلق بالتحويل المحتمل لعملية شراء. يبدو واعدًا ، لكن الاستخدام أظهر أن التصفية باستخدام درجة LLR تعطي زيادة مصغرة جدًا ، والجمع بين العديد من الدرجات يؤدي إلى تفاقم النتيجة. على ما يبدو ، فإن الطريقة ليست لهذه البيانات. من الإيجابيات ، لا يمكنني إلا أن أشير إلى أنه ، أثناء معرفة كيفية تنفيذ هذه الفكرة ، كان علي أن أحفر داخل الضمني.
سيتم ترك مثال لتطبيق هذا المنطق المخصص ضمنيًا تحت القطة.
الفكرة رقم 2ظهرت فكرة أخرى يمكن أن تحسن التوقعات بشأن التصفية التعاونية البسيطة. غالبًا ما تستخدم الصناعة نوعًا من وظيفة التخميد في التقديرات القديمة ، ولكن لدينا حالة ليست بهذه البساطة. ربما تحتاج إلى مراعاة الحالتين المحتملتين بطريقة أو بأخرى:
- المستخدمين الذين يشاهدون الخدمة هم في الغالب جديدون
- "لتفتيشها." وهذا هو ، أولئك الذين جاءوا مؤخرا نسبيا ويمكن أن يشاهدوا الأفلام الشعبية سابقا.
وبالتالي ، يمكن تقسيم المكون التعاوني إلى مجموعتين مختلفتين تلقائيًا. للقيام بذلك ، اخترعت وظيفة ، بدلاً من القيم الضمنية المعينة إلى "1" أو "0" عند تقاطع المستخدم والفيلم ، وهي قيمة تُظهر مدى أهمية هذا الفيلم في سجل عرض المستخدم.

حيث
StartTime هو تاريخ إصدار الفيلم ، و
atchWatchTime هو الفرق بين تاريخ الإصدار والتاريخ الذي شاهده المستخدم ، و
α و
β هي
معلمات تشعبية .
هنا ، يكون الفصل الأول مسؤولاً عن زيادة سرعة الأفلام التي تم إصدارها مؤخرًا ، والثاني هو مراعاة إدمان المستخدمين للأفلام القديمة. إذا تم إصدار فيلم منذ فترة طويلة ، وقام المستخدم بشرائه على الفور ، فلا ينبغي أن تؤخذ هذه الحقيقة في الاعتبار كثيرًا اليوم. إذا كان هذا نوعًا من الحداثة ، فيجب علينا التوصية به لعدد أكبر من المستخدمين الذين يشاهدون أيضًا عناصر جديدة. إذا كان الفيلم قديمًا تمامًا ، ولم يشاهده المستخدم سوى الآن ، فقد يكون هذا مهمًا أيضًا لأولئك الذين يحبونه.
هناك اليسار تافه - لفرز المعاملات
α و
β . إجازة لليل ، ويتم العمل. لم تكن هناك افتراضات حول النطاق على الإطلاق ، لذلك كانت كبيرة في البداية ، وأدناه هي نتائج البحث المحلي الأمثل.

باستخدام هذه الفكرة ، أعطى نموذج بسيط على مصفوفة واحدة 0.03627 على التحقق من الصحة المحلية و 0.03685 على LB العامة ، والتي تبدو على الفور وكأنها دفعة جيدة مقارنة بالنتائج السابقة. في ذلك الوقت ، أوصلني إلى قائمة العشرين الأوائل.
№3, , , . CF . :

, 25 .
, , 0.040312 , 0.03870 0.03990 public/private 14- .
Acknowledgments
jupyter notebook — . , . output . .
cookiecutter-data-science — Ocean. .
. .
( )
private , . , . :

, , , :

, 2 . . , .

استنتاج
— . , . ? , — feature importance , , «» . , .
, . ; , , .