ระบบคำแนะนำ e-book ที่ง่ายขึ้นอยู่กับเฟรมเวิร์ก SSM และอัลกอริทึมการกรองการทำงานร่วมกันของไอเท็ม (itemcf)










เนื่องจากอัลกอริทึมคำแนะนำบางอย่างจำเป็นต้องใช้ข้อมูลที่ผู้ใช้ชื่นชอบเป็นพารามิเตอร์ หากผู้ใช้ไม่ได้ลงชื่อเข้าใช้กลยุทธ์การแนะนำสำหรับนักท่องเที่ยวจะถูกนำมาใช้ หากผู้ใช้เข้าสู่ระบบนโยบายการแนะนำสำหรับผู้ใช้ที่เข้าสู่ระบบจะถูกนำมาใช้ หากผู้ใช้ที่เข้าสู่ระบบมีบันทึกพาร์ติชันที่น่าสนใจในฐานข้อมูลคำแนะนำจากพาร์ติชันที่คุณสนใจจะถูกเพิ่มเข้ามา ดังนั้นกลยุทธ์การแนะนำจะแบ่งออกเป็นสองสถานการณ์: ไม่ว่าจะเข้าสู่ระบบหรือไม่

หากผู้ใช้ไม่ได้ลงชื่อเข้าใช้กลยุทธ์การแสดงการจัดอันดับผู้ใช้สำหรับนักท่องเที่ยวจะถูกนำมาใช้ หากผู้ใช้เข้าสู่ระบบนโยบายการแสดงการจัดอันดับผู้ใช้สำหรับผู้ใช้ที่เข้าสู่ระบบจะถูกนำมาใช้ หากผู้ใช้ที่เข้าสู่ระบบได้ให้คะแนน e-book ในหน้ารายละเอียดปัจจุบันแล้วบันทึกการจัดอันดับจะปรากฏขึ้น


ดังที่แสดงในแผนภาพกรณีการใช้งานมีผู้ใช้พื้นฐานสามคนในระบบนี้ เหล่านี้คือนักท่องเที่ยวผู้ใช้ที่ลงทะเบียนและผู้ดูแลระบบ ผู้เข้าชมสามารถเยี่ยมชมหน้าแรกของแพลตฟอร์มคำแนะนำ e-book หน้าลงทะเบียนผู้ใช้และดูหน้า e-book ฟังก์ชั่นของการลงทะเบียนผู้ใช้คือพวกเขาสามารถให้คะแนนและแสดงความคิดเห็นเกี่ยวกับ e-books และแนะนำ e-books ที่กำหนดโดยดอกเบี้ยที่คาดการณ์ของผู้ใช้ ผู้ดูแลระบบสามารถใช้โมดูล Crawler เป็นประจำเพื่ออัปเดตข้อมูล e-book และใช้โมดูลสถิติเพื่ออัปเดตสถิติที่เป็นความลับเมทริกซ์การเกิดร่วม e-book และเมทริกซ์ความคล้ายคลึงกันของ e-book
! [case.png] (/img/user case.png)
พิจารณาว่ามีปัญหาการเริ่มต้นเย็นกับอัลกอริทึมนี้ นั่นคือสำหรับผู้ใช้ใหม่พวกเขามักจะขาดข้อมูลการให้คะแนนซึ่งนำไปสู่คำแนะนำตามระดับดอกเบี้ยที่คาดการณ์ไว้ของผู้ใช้และไม่สามารถดำเนินการได้อย่างราบรื่น เพื่อแก้ปัญหานี้ฉันได้เพิ่มโมดูลเพื่อใช้เมทริกซ์ความคล้ายคลึงกันของโคไซน์โดยตรงเพื่อดำเนินการคำแนะนำ e-book ที่คล้ายกันโดยตรงเพื่อให้ผู้ใช้ที่ไม่ได้ลงทะเบียนและผู้ใช้ใหม่สามารถรับคำแนะนำได้ดีขึ้น สำหรับปัญหาเมทริกซ์ข้อมูลที่กระจัดกระจายในอัลกอริทึมการกรองแบบทำงานร่วมกันหนังสืออิเล็กทรอนิกส์ที่ไม่เป็นที่นิยมบางเล่มอาจไม่มีการให้คะแนนผู้ใช้ความสัมพันธ์แบบอิเล็กทรอนิกส์ต่ำและผู้ใช้บางคนมีการจัดอันดับ e-book เพียงเล็กน้อย ในการแก้ปัญหานี้เพิ่มโมดูลคำแนะนำหนังสือเล่มใหม่ในหน้าแรกเพื่อแนะนำ e-books ที่ไม่มีการจัดอันดับ เพิ่มโมดูลคำแนะนำพาร์ติชันเพื่อแนะนำ e-books ตามความสนใจของผู้ใช้เพื่อเพิ่มความสนใจของผู้ใช้เฉพาะเพื่อแนะนำ e-books เป็นที่น่าสังเกตว่า e-book ที่ผู้ใช้แนะนำให้ทำนายดอกเบี้ยคำนวณโดยใช้สูตรในเมทริกซ์ความคล้ายคลึงกันของโคไซน์ที่คำนวณโดยอัลกอริทึมนี้ นอกจากนี้ยังจำเป็นต้องใช้ e-book ที่ผู้ใช้ชื่นชอบเป็นพารามิเตอร์อินพุตระหว่างการคำนวณ e-book ที่คล้ายกันที่แนะนำคือการใช้เมทริกซ์ความคล้ายคลึงกันของสตริงสำหรับสถิติโดยตรง ซึ่งหมายความว่าคำแนะนำสองข้อข้างต้นจำเป็นต้องทำการคำนวณเมทริกซ์การเกิดร่วมของ e-book และเมทริกซ์ความคล้ายคลึงกันของโคไซน์ของ e-book เนื่องจากเมทริกซ์สองตัวข้างต้นมีขนาดใหญ่ในการคำนวณและข้อมูลทั้งหมดเป็นสิ่งจำเป็นสำหรับการคำนวณแต่ละครั้งจึงถูกตั้งค่าให้ดำเนินการอย่างสม่ำเสมอโดยผู้ดูแลระบบ

สัญลักษณ์→ระบุว่าคลาสเป็นการทำงานด้วยตนเองปกติของโมดูล

มีสองขั้นตอนหลักสำหรับอัลกอริทึมการกรองความร่วมมือตามรายการ:
สมมติว่า n (i) คือจำนวนผู้ใช้ที่ชอบรายการ i n (i) ⋂n (j) แสดงจำนวนผู้ใช้ที่ชอบรายการ I รายการ j ในเวลาเดียวกัน จากนั้นความคล้ายคลึงกันระหว่างรายการ I และรายการ J คือ:

อย่างไรก็ตามสูตรข้างต้นมีข้อบกพร่อง: เมื่อรายการ J เป็นผลิตภัณฑ์ที่ได้รับความนิยมอย่างมากและทุกคนชอบมัน WIJ จะใกล้เคียงกับ 1 มากนั่นคือสูตรข้างต้นจะทำให้หลายรายการมีความคล้ายคลึงกับผลิตภัณฑ์ยอดนิยมมากดังนั้นคุณสามารถปรับปรุงสูตร:

สร้างรายการรายการผู้ใช้กลับด้าน (สมมติว่าตัวอักษรตัวพิมพ์ใหญ่เป็นตัวแทนของผู้ใช้ตัวอักษรตัวพิมพ์เล็กแสดงรายการ):

คำนวณเมทริกซ์การเกิดร่วม Co-co-co-co-co-co-currence แสดงถึงจำนวนผู้ใช้ที่ชอบสองรายการในเวลาเดียวกันและคำนวณตามตารางรายการผู้ใช้ผกผัน):

ดังที่แสดงในรูปเราจะเห็นได้ว่าองค์ประกอบในแนวทแยงของเมทริกซ์การเกิดร่วมเป็น 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 กระบวนการคำนวณทั้งหมดแบ่งออกเป็น 2 ขั้นตอน ขั้นตอนแรกคำนวณเมทริกซ์การเกิดร่วม C. ระยะที่สองคำนวณความคล้ายคลึงกันของโคไซน์ w ของ e-books ที่ปรากฏเป็นคู่ สำหรับฟังก์ชั่นที่แนะนำตามความสนใจของผู้ใช้ที่คาดการณ์เนื่องจากผู้ใช้ชอบจำนวนการคำนวณแบบเรียลไทม์และทั้งหมดของข้อมูล e-book มีขนาดใหญ่เกินไปผู้ใช้จะใช้การคำนวณแบบเรียลไทม์เมื่อเข้าถึงหน้า หลังจากการทดสอบหลายครั้งเวลารอคอยโดยเฉลี่ยของผู้ใช้อยู่ในช่วงที่ยอมรับได้
เนื่องจากการอัพเกรดหน้าเว็บ Douban ได้เพิ่มมาตรการต่อต้านการคลานข้อมูลที่ใช้ในการเรียกใช้อัลกอริทึมที่แนะนำนั้นมีให้ที่นี่