نظام توصية بسيط للكتاب الإلكتروني يستند إلى خوارزمية تصفية SSM والبند التعاوني (ITEMCF)










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

إذا لم يتم تسجيل الدخول للمستخدم ، فسيتم اعتماد استراتيجية عرض تصنيف المستخدم للسياح. إذا تم تسجيل الدخول إلى المستخدم ، فسيتم اعتماد سياسة عرض تصنيف المستخدم للمستخدم. إذا كان المستخدم الذي تم تسجيل الدخول قد سجل بالفعل الكتاب الإلكتروني على صفحة التفاصيل الحالية ، فسيتم عرض سجل التصنيف الخاص به.


كما هو موضح في مخطط حالة الاستخدام ، هناك ثلاثة مستخدمين أساسيين في هذا النظام. هؤلاء هم السياح والمستخدمين المسجلين والمسؤولين. يمكن للزوار زيارة الصفحة الرئيسية لمنصة توصية الكتاب الإلكتروني ، وصفحة تسجيل المستخدم ، وعرض صفحة الكتاب الإلكتروني. تتمثل وظيفة تسجيل المستخدمين في أنه يمكنهم التقييم والتعليق على الكتب الإلكترونية والتوصية بالكتب الإلكترونية التي تحددها الفائدة المتوقعة للمستخدم. يمكن للمسؤولين استخدام وحدة الزاحف بانتظام لتحديث معلومات الكتاب الإلكتروني واستخدام وحدة الإحصائيات لتحديث الإحصاءات المصنفة ، مصفوفة تواجد الكتب الإلكترونية ومصفوفة تشابه جيب التجربة الكتب الإلكترونية.
! [case.png] (/img/user case.png)
بالنظر إلى أن هناك مشكلة بداية باردة مع هذه الخوارزمية. أي بالنسبة للمستخدمين الجدد ، فإنهم غالبًا ما يفتقرون إلى بيانات التصنيف ، مما يؤدي إلى التوصية بناءً على مستوى الاهتمام المتوقع للمستخدم ولا يمكن تنفيذه بسلاسة. لحل هذه المشكلة ، أضفت وحدة نمطية لاستخدام مصفوفة تشابه جيب التجربة بشكل مباشر لتقديم توصيات للكتب الإلكترونية المشابهة مباشرة ، بحيث يمكن للمستخدمين غير المسجلين والمستخدمين الجدد الحصول على توصيات أفضل. أما بالنسبة لمشاكل مصفوفة البيانات المتفرقة في خوارزميات التصفية التعاونية ، فقد لا يكون لبعض الكتب الإلكترونية غير المحببة أي تقييمات للمستخدم ، وارتباط الكتب الإلكترونية المنخفضة ، وبعض المستخدمين لديهم عدد قليل من تقييمات الكتب الإلكترونية. لحل هذه المشكلة ، أضف وحدة توصية جديدة للكتاب إلى الصفحة الرئيسية للتوصية بشكل أفضل بالكتب الإلكترونية التي لا يتم تصنيفها ؛ أضف وحدة توصية قسم للتوصية بالكتب الإلكترونية بناءً على مصلحة المستخدم من أجل زيادة مصلحة المستخدمين المحددين للتوصية عن الكتب الإلكترونية. تجدر الإشارة إلى أن الكتاب الإلكتروني الموصى به من قبل المستخدمين للتنبؤ بالاهتمام يتم حسابه باستخدام صيغ على مصفوفة تشابه جيب التمام W المحسوبة بواسطة هذه الخوارزمية. بالإضافة إلى ذلك ، فإن الكتاب الإلكتروني المفضل للمستخدم مطلوب أيضًا كمعلمات إدخال أثناء الحساب. الكتاب الإلكتروني المماثل الموصى به هو استخدام مصفوفة تشابه السلسلة W للإحصائيات مباشرة. هذا يعني أن التوصيات المذكورة أعلاه تحتاج إلى إكمال حساب مصفوفة التواجد المشترك للكتاب الإلكتروني ومصفوفة تشابه جيب التمام للكتاب الإلكتروني. نظرًا لأن المصفوفتين أعلاه كبيران من الناحية الحسابية وجميع البيانات مطلوبة لكل عملية حسابية ، يتم تعيينه ليتم تنفيذه بانتظام من قبل المسؤول.

الرمز → يشير إلى أن الفصل هو تشغيل يدوي منتظم للوحدات النمطية

هناك خطوتان رئيسيتان لخوارزمية التصفية التعاونية على أساس العناصر:
لنفترض أن n (i) هو عدد المستخدمين الذين يحبون العنصر i. N (i) ⋂n (j) يمثل عدد المستخدمين الذين يحبون البند I العنصر J في نفس الوقت. ثم التشابه بين البند الأول والبند J هو:

ومع ذلك ، فإن الصيغة أعلاه لها عيب: عندما يكون العنصر J منتجًا شائعًا جدًا ويحبه الجميع ، فإن Wij سيكون قريبًا جدًا من 1 ، أي أن الصيغة أعلاه ستجعل العديد من العناصر لها تشابه كبير مع المنتجات الشائعة ، بحيث يمكنك تحسين الصيغة:

قم بإنشاء قائمة بعناصر المستخدم المقلوبة (افترض أن الأحرف الكبيرة تمثل المستخدمين ، وتمثل الحروف الصغيرة العناصر):

احسب مصفوفة التواجد المشترك C (تمثل مصفوفة التواجد المشترك عدد المستخدمين الذين يحبون عنصرين في نفس الوقت ، ويتم حسابه بناءً على جدول انقلاب عنصر المستخدم):

كما هو موضح في الشكل ، يمكننا أن نرى أن العناصر القطرية لمصفوفة التواجد المشترك كلها 0 وهي مصفوفات متناثرة حقيقية. يتم تنفيذ الخوارزمية على النحو التالي:
com.Statistics.ItemCollaborationFilter
/**
* 计算共现矩阵C
*/
private void computerMatrixC (){
// 建立用户物品倒排表
// 若用户对物品评分大于等于4则认为喜欢(出现)
List < User > allUser = userDao . queryAllUser ();
for ( int i = 0 ; i < allUser . size (); i ++){ // 遍历全部用户
// 获取一个用户的评分列表中>=4的评分记录
List < RatingList > likeList = ratingListDao . selectRatingListByUidAndRatingValue ( allUser . get ( i ). getUid (), 4 );
if ( likeList . size () <= 1 ){ // 若用户只喜欢一本或不喜欢任何图书
continue ;
}
for ( int j = 0 ; j < likeList . size (); j ++){ // 计算likeList中两两出现的图书并写入同现矩阵C
for ( int k = j + 1 ; k < likeList . size (); k ++){
int a = Integer . valueOf ( likeList . get ( j ). getEid ());
int b = Integer . valueOf ( likeList . get ( k ). getEid ());
// 生成key
String key = null ;
if ( a < b ){
key = a + "," + b ;
} else {
key = b + "," + a ;
}
// 检查key是否已经存在
if ( this . matrixC . get ( key ) != null ){
int value = this . matrixC . get ( key );
this . matrixC . put ( key , value + 1 );
} else {
this . matrixC . put ( key , 1 );
}
}
}
System . out . println ( "[" + df . format ( new Date ())+ "]" + "[已完成" + i + ",共" + allUser . size ()+ "]:用户uid=" + allUser . get ( i ). getUid ()+ "的记录以计算完成,共" + likeList . size ()+ "本图书" );
}
}عدد المرات التي يظهر فيها كل عنصر هو:

حساب مصفوفة تشابه جيب التمام W: يمكن الحصول على مصفوفة تشابه جيب التمام باستخدام الصيغة المحسنة.

يتم تنفيذ الخوارزمية على النحو التالي:
com.Statistics.ItemCollaborationFilter
/**
* 计算余弦相似度矩阵W
* 计算方法:
* 使用矩阵C的每个value作为分子,key中的两个图书的喜欢人数的积开根号作为分母
*/
private Double computerMatrixW ( String eida , String eidb , int value ){
DecimalFormat df = new DecimalFormat ( "#.##" );
// 查询每个图书有多少人喜欢
try {
Statement statemenet = conn . createStatement ();
ResultSet rs = statemenet . executeQuery ( "select count(rid) from ratinglist where eid = '" + eida + "' and ratingValue >= 4;" );
rs . next ();
int likeANum = rs . getInt ( "count(rid)" );
rs = statemenet . executeQuery ( "select count(rid) from ratinglist where eid = '" + eidb + "' and ratingValue >= 4;" );
rs . next ();
int likeBNum = rs . getInt ( "count(rid)" );
if ( likeANum == 0 )
likeANum = 1 ;
if ( likeBNum == 0 )
likeBNum = 1 ;
// 开始计算
Double answer = value * 1.0 / Math . sqrt ( likeANum * likeBNum );
// 精确到小数点后两位
Double result = Double . parseDouble ( df . format ( answer ));
// 返回计算结果
return result ;
} catch ( SQLException e ) {
e . printStackTrace ();
}
return null ;
}ما هو العنصر الموصى به في النهاية يتم تحديده من خلال التنبؤ بالاهتمام.
العنصر J يتنبأ بالفائدة = مصلحة العنصر I أن المستخدم يحب × التشابه بين العنصر الأول والبند J.
على سبيل المثال: يحب المستخدم العناصر A و B و C. اهتمامهم هو 1 و 2 و 2 على التوالي. ثم الاهتمام المتوقع للعناصر C و D و E و F هي:
لذلك ، يجب التوصية بالبند D للمستخدم. يتم تنفيذ الخوارزمية على النحو التالي:
@ Override
public List < EBook > userRecommendedList ( String uid ) {
// 获取用户喜爱图书列表
List < RatingList > likeList = this . ratingListDao . selectRatingListByUidAndRatingValue ( uid , 4 );
// debug
System . out . println ( "uid=" + uid + "用户喜爱图书列表" );
for ( RatingList r : likeList ){
System . out . println ( r . getEid ()+ "," + r . getRatingValue ());
}
System . out . println ( "likeList.size=" + likeList . size ());
// 定义计算用矩阵
List < Item > matrix = new ArrayList <>();
// 将用户喜爱的图书作为矩阵的列
// 将与用户喜爱的图书同现的图书作为矩阵的行
// 建立工作矩阵
for ( int i = 0 ; i < likeList . size (); i ++){ // 遍历用户喜爱的图书
RatingList temp = likeList . get ( i );
// 获取同现图书
List < MatrixC > itemList = this . matrixCDao . selectMatrixCByEidAOrEidB ( temp . getEid (), temp . getEid ());
for ( int j = 0 ; j < itemList . size (); j ++){
MatrixC c = itemList . get ( j );
// 从matrixC的key中选出同现图书的eid
String sEid = null ;
if ( c . getEida (). equals ( temp . getEid ())){
sEid = c . getEidb ();
} else {
sEid = c . getEida ();
}
// 在行中查询同现图书是否存在
if ( matrix . indexOf ( sEid ) == - 1 ){ // 若列中不存在
double [] col = new double [ likeList . size ()];
// 将同现图书所在行对应喜爱图书的数组值设为对应的余弦相似度*用户喜爱程度(4分为1,5分为2)
col [ likeList . indexOf ( temp )] = c . getCos_similarity ()*( temp . getRatingValue ()- 3 );
matrix . add ( new Item ( sEid , col )); // 增加行
} else { // 若列中存在
// 则将同现图书所在行对应喜爱图书的数组值设为对应的余弦相似度*用户喜爱程度(4分为1,5分为2)
matrix . get ( matrix . indexOf ( sEid )). col [ likeList . indexOf ( temp )] = c . getCos_similarity ()*( temp . getRatingValue ()- 3 );
}
}
}
// 计算预测兴趣度
for ( int i = 0 ; i < matrix . size (); i ++){
Item item = matrix . get ( i );
double interestValue = 0 ;
for ( int j = 0 ; j < item . col . length ; j ++){
interestValue += item . col [ j ];
}
matrix . get ( i ). interestValue = interestValue ;
}
// 根据预测兴趣度进行排序
Collections . sort ( matrix );
// 返回推荐图书列表
List < EBook > resultList = new ArrayList <>();
for ( int i = 0 ; i < matrix . size () && i < 20 ; i ++){ // 返回排前10的书
if ( matrix . get ( i ). interestValue > 0 ){
EBook eBook = this . eBookDao . queryEBookByEid ( matrix . get ( i ). eid );
resultList . add ( eBook );
// debug
System . out . println ( matrix . get ( i ). eid + "," + eBook . getEname ()+ ",interestValue=" + matrix . get ( i ). interestValue );
}
}
return EBookServiceImpl . initEBookImgAddress ( resultList );
}تستخدم الوحدة النمطية الموصى بها البيانات التي يزحفها الزاحف كمدخل لإخراج نتائج الحساب في جدول Matrixc. تنقسم عملية الحساب بأكملها إلى مرحلتين. تحسب المرحلة الأولى مصفوفة التورط المشترك C. المرحلة الثانية تحسب تشابه جيب التمام مع الكتب الإلكترونية التي تظهر في أزواج. بالنسبة للوظيفة الموصى بها استنادًا إلى الفائدة المتوقعة للمستخدم ، لأن المستخدم يحب الوقت الفعلي والمبلغ الإجمالي لبيانات الكتب الإلكترونية كبيرة جدًا ، سيستخدم المستخدم الحسابات في الوقت الفعلي عند الوصول إلى الصفحة. بعد اختبارات متعددة ، يكون متوسط وقت انتظار المستخدم ضمن نطاق مقبول.
نظرًا لأن ترقية صفحة Web Movie Douban قد أضافت تدابير مضادة للتزحلق ، يتم توفير البيانات المستخدمة لتشغيل الخوارزمية الموصى بها هنا.