该模块的主要思路是将现登录用户的个人信息(包括出行目的地、旅游类型、天数、花费等)与数据库中已有的其他用户信息进行相似度匹配,根据相似度值的大小进行排序,同时获得用户去过的景点,然后推荐给用户。这里的相似度计算采用的是余弦相似度,关于它是什么以及如何计算,我是参考的
这个博客(侵删)。
里面是对一段文本先进行分词,但是该模块用到的数据都是像目的地、天数之类的,因此不需要进行分词操作。最后的效果如下:
核心代码:
RecommnedFragment
public class RecommendFragment extends Fragment {
private String mCurrentUserName=UserCenterFragment.mUserName; //当前所登陆的用户,一定要保证已经登录,否则可能有问题
private UserLab mUserLab;
private static List<SimilarityItem> mSimilarityItems=new ArrayList<>();
private RecyclerView mRecyclerView;
public static RecommendFragment newInstance(){
return new RecommendFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.fragment_recommend,container,false);
mRecyclerView=(RecyclerView)v.findViewById(R.id.recommend_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
getSimiliarity(mSimilarityItems); // 先准备数据,并进行排序
Collections.sort(mSimilarityItems, new Comparator<SimilarityItem>() {
@Override
public int compare(SimilarityItem similarityItem, SimilarityItem t1) {
return (int) ((t1.getSimilarity()-similarityItem.getSimilarity())*100);//由于这里返回值必须是int型,而相似度都是小数,故先放大100倍
}
});
int rank=1;
for(SimilarityItem item:mSimilarityItems){
item.setRank(rank);
rank++;
}
setupAdapter();
return v;
}
private class RecommendHolder extends RecyclerView.ViewHolder{
private TextView mRecommendRank;
private TextView mRecommendSimilarity;
private TextView mRecommendScenery;
public RecommendHolder(View itemView){
super(itemView);
mRecommendRank=(TextView)itemView.findViewById(R.id.recommend_rank);
mRecommendSimilarity=(TextView)itemView.findViewById(R.id.recommend_similarity);
mRecommendScenery=(TextView)itemView.findViewById(R.id.recommend_scenery);
}
public void bindItem(SimilarityItem item){
mRecommendRank.setText(item.getRank()+"");
mRecommendSimilarity.setText("相似度:"+item.getSimilarity());
mRecommendScenery.setText(item.getScenery());
}
}
private class RecommendAdapter extends RecyclerView.Adapter<RecommendHolder>{
private List<SimilarityItem> mItems;
public RecommendAdapter(List<SimilarityItem> items){
mItems=items;
}
@Override
public RecommendHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =LayoutInflater.from(getActivity()).inflate(R.layout.list_item_recommend,parent,false);
return new RecommendHolder(view);
}
@Override
public void onBindViewHolder(RecommendHolder holder, int position) {
holder.bindItem(mItems.get(position));
}
@Override
public int getItemCount() {
return mItems.size();
}
}
public void setupAdapter(){
mRecyclerView.setAdapter(new RecommendAdapter(mSimilarityItems));
}
/**
* 得到每条记录的相似度及对应景点,存储在Sinilarity类中最后存在容器里
* @param similarityItems
*/
private void getSimiliarity(List<SimilarityItem> similarityItems){
mUserLab=UserLab.get(getActivity());
List<String> words=mUserLab.getUserWords(mCurrentUserName);
List<Words> wordsArray=mUserLab.getTripWordsArray();
CosineSimilarity cosineSimilarity = new CosineSimilarity();
for (Words w:wordsArray){
List<String> words1=w.getWordArray();
SimilarityItem item=new SimilarityItem();
item.setSimilarity(cosineSimilarity.cos(words, words1));
item.setScenery(w.getScenery());
similarityItems.add(item);
}
}
/**
* 得到推荐相似度最高的景点数组
* @return
*/
public static String[] getRecommendSceneries(){
String sceneries=mSimilarityItems.get(0).getScenery(); //获取相似度最高的,也就是排序后的第一个,这里得到的是字符串
sceneries.trim();
String[] recommendSceneries=sceneries.split(",");
return recommendSceneries;
}
}
整个工
程的源码在这找!
版权声明:本文为wml00000原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。