├── .gitignore ├── README.md ├── dependency-reduced-pom.xml ├── doc ├── allclasses-frame.html ├── allclasses-noframe.html ├── constant-values.html ├── deprecated-list.html ├── edu │ ├── cuc │ │ └── dmt │ │ │ └── demo │ │ │ ├── RecommenderDemo.html │ │ │ ├── class-use │ │ │ └── RecommenderDemo.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ └── recm │ │ ├── algorithm │ │ ├── algorithm │ │ │ ├── AbstractCFRecommender.html │ │ │ ├── ContentBasedRecommender.html │ │ │ ├── ItemBasedCFRecommender.html │ │ │ ├── MyRecommender.html │ │ │ ├── MyRecommenderBuilder.html │ │ │ ├── UserBasedCFRecommender.html │ │ │ ├── WaterfallMixRecommender.html │ │ │ ├── WeightedMixRecommender.html │ │ │ ├── class-use │ │ │ │ ├── AbstractCFRecommender.html │ │ │ │ ├── ContentBasedRecommender.html │ │ │ │ ├── ItemBasedCFRecommender.html │ │ │ │ ├── MyRecommender.html │ │ │ │ ├── MyRecommenderBuilder.html │ │ │ │ ├── UserBasedCFRecommender.html │ │ │ │ ├── WaterfallMixRecommender.html │ │ │ │ └── WeightedMixRecommender.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── data │ │ │ ├── AbstractPreferenceData.html │ │ │ ├── FilePreferenceData.html │ │ │ ├── MySQLContentData.html │ │ │ ├── MySQLPreferenceData.html │ │ │ ├── QueryOccur.html │ │ │ ├── QueryUnit.html │ │ │ ├── ResultBean.html │ │ │ ├── class-use │ │ │ │ ├── AbstractPreferenceData.html │ │ │ │ ├── FilePreferenceData.html │ │ │ │ ├── MySQLContentData.html │ │ │ │ ├── MySQLPreferenceData.html │ │ │ │ ├── QueryOccur.html │ │ │ │ ├── QueryUnit.html │ │ │ │ └── ResultBean.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── evaluate │ │ │ ├── MyRecommenderEvaluator.html │ │ │ ├── class-use │ │ │ │ └── MyRecommenderEvaluator.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ └── similarity │ │ │ ├── SimilarityFactory.html │ │ │ ├── UserNeighborhoodFactory.html │ │ │ ├── class-use │ │ │ ├── SimilarityFactory.html │ │ │ └── UserNeighborhoodFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── config │ │ ├── model │ │ │ ├── AbstractAlgorithmConfigModel.html │ │ │ ├── AbstractDataConfigModel.html │ │ │ ├── AbstractMixAlgorithmConfigModel.html │ │ │ ├── AbstractPreferenceDataConfigModel.html │ │ │ ├── AbstractSimilarityConfigModel.html │ │ │ ├── AbstractSingleAlgorithmConfigModel.html │ │ │ ├── ContentBasedAlgorithmConfigModel.html │ │ │ ├── DBConfigModel.html │ │ │ ├── DataListConfigModel.html │ │ │ ├── EvaluatorConfigModel.html │ │ │ ├── FilePreferenceDataConfigModel.html │ │ │ ├── IntegralAlgorithmConfigModel.html │ │ │ ├── IntegralConfigModel.html │ │ │ ├── IntegralDataConfigModel.html │ │ │ ├── ItemBasedCFAlgorithmConfigModel.html │ │ │ ├── ItemSimilarityConfigModel.html │ │ │ ├── MySQLContentDataConfigModel.html │ │ │ ├── MySQLPreferenceDataConfigModel.html │ │ │ ├── QueryUnitConfigModel.html │ │ │ ├── SimilarityListConfigModel.html │ │ │ ├── UserBasedCFAlgorithmConfigModel.html │ │ │ ├── UserSimilarityConfigModel.html │ │ │ ├── WaterfallMixAlgorithmConfigModel.html │ │ │ ├── WeightedMixAlgorithmConfigModel.html │ │ │ ├── class-use │ │ │ │ ├── AbstractAlgorithmConfigModel.html │ │ │ │ ├── AbstractDataConfigModel.html │ │ │ │ ├── AbstractMixAlgorithmConfigModel.html │ │ │ │ ├── AbstractPreferenceDataConfigModel.html │ │ │ │ ├── AbstractSimilarityConfigModel.html │ │ │ │ ├── AbstractSingleAlgorithmConfigModel.html │ │ │ │ ├── ContentBasedAlgorithmConfigModel.html │ │ │ │ ├── DBConfigModel.html │ │ │ │ ├── DataListConfigModel.html │ │ │ │ ├── EvaluatorConfigModel.html │ │ │ │ ├── FilePreferenceDataConfigModel.html │ │ │ │ ├── IntegralAlgorithmConfigModel.html │ │ │ │ ├── IntegralConfigModel.html │ │ │ │ ├── IntegralDataConfigModel.html │ │ │ │ ├── ItemBasedCFAlgorithmConfigModel.html │ │ │ │ ├── ItemSimilarityConfigModel.html │ │ │ │ ├── MySQLContentDataConfigModel.html │ │ │ │ ├── MySQLPreferenceDataConfigModel.html │ │ │ │ ├── QueryUnitConfigModel.html │ │ │ │ ├── SimilarityListConfigModel.html │ │ │ │ ├── UserBasedCFAlgorithmConfigModel.html │ │ │ │ ├── UserSimilarityConfigModel.html │ │ │ │ ├── WaterfallMixAlgorithmConfigModel.html │ │ │ │ └── WeightedMixAlgorithmConfigModel.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── web │ │ │ ├── WebParamAnalyzer.html │ │ │ ├── class-use │ │ │ │ └── WebParamAnalyzer.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ └── xml │ │ │ ├── XMLAnalyzer.html │ │ │ ├── XMLCreator.html │ │ │ ├── class-use │ │ │ ├── XMLAnalyzer.html │ │ │ └── XMLCreator.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── service │ │ ├── common │ │ │ ├── JettyServer.html │ │ │ ├── RecommenderBuilder.html │ │ │ ├── class-use │ │ │ │ ├── JettyServer.html │ │ │ │ └── RecommenderBuilder.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ └── controller │ │ │ ├── WebConfigController.html │ │ │ ├── WebServiceController.html │ │ │ ├── class-use │ │ │ ├── WebConfigController.html │ │ │ └── WebServiceController.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ └── util │ │ ├── ConfigVariables.html │ │ ├── MyEntry.html │ │ ├── MySQLUtil.html │ │ ├── class-use │ │ ├── ConfigVariables.html │ │ ├── MyEntry.html │ │ └── MySQLUtil.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── package-use.html ├── help-doc.html ├── index-files │ ├── index-1.html │ ├── index-10.html │ ├── index-11.html │ ├── index-12.html │ ├── index-13.html │ ├── index-14.html │ ├── index-15.html │ ├── index-16.html │ ├── index-17.html │ ├── index-18.html │ ├── index-2.html │ ├── index-3.html │ ├── index-4.html │ ├── index-5.html │ ├── index-6.html │ ├── index-7.html │ ├── index-8.html │ └── index-9.html ├── index.html ├── overview-frame.html ├── overview-summary.html ├── overview-tree.html ├── package-list ├── resources │ ├── background.gif │ ├── tab.gif │ ├── titlebar.gif │ └── titlebar_end.gif ├── stylesheet.css └── test │ ├── algorithm │ ├── algorithm │ │ ├── ContentBasedRecommenderTest.html │ │ ├── ItemBasedCFRecommenderTest.html │ │ ├── UserBasedCFRecommenderTest.html │ │ ├── WaterfallMixRecommenderTest.html │ │ ├── WeightedMixRecommenderTest.html │ │ ├── class-use │ │ │ ├── ContentBasedRecommenderTest.html │ │ │ ├── ItemBasedCFRecommenderTest.html │ │ │ ├── UserBasedCFRecommenderTest.html │ │ │ ├── WaterfallMixRecommenderTest.html │ │ │ └── WeightedMixRecommenderTest.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── package-use.html │ └── data │ │ ├── FilePreferenceDataTest.html │ │ ├── MySQLPreferenceDataTest.html │ │ ├── class-use │ │ ├── FilePreferenceDataTest.html │ │ └── MySQLPreferenceDataTest.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── package-use.html │ ├── config │ ├── web │ │ ├── WebParamAnalyzerTest.html │ │ ├── class-use │ │ │ └── WebParamAnalyzerTest.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── package-use.html │ └── xml │ │ ├── XMLAnalyzerTest.html │ │ ├── XMLCreatorTest.html │ │ ├── class-use │ │ ├── XMLAnalyzerTest.html │ │ └── XMLCreatorTest.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ ├── package-tree.html │ │ └── package-use.html │ └── service │ ├── RecommenderBuilderTest.html │ ├── class-use │ └── RecommenderBuilderTest.html │ ├── package-frame.html │ ├── package-summary.html │ ├── package-tree.html │ └── package-use.html ├── pom.xml └── src ├── main ├── java │ └── edu │ │ └── recm │ │ ├── algorithm │ │ ├── algorithm │ │ │ ├── AbstractCFRecommender.java │ │ │ ├── ContentBasedRecommender.java │ │ │ ├── ItemBasedCFRecommender.java │ │ │ ├── MyRecommender.java │ │ │ ├── MyRecommenderBuilder.java │ │ │ ├── UserBasedCFRecommender.java │ │ │ ├── WaterfallMixRecommender.java │ │ │ ├── WeightedMixRecommender.java │ │ │ └── package-info.java │ │ ├── data │ │ │ ├── AbstractPreferenceData.java │ │ │ ├── FilePreferenceData.java │ │ │ ├── MySQLContentData.java │ │ │ ├── MySQLPreferenceData.java │ │ │ ├── QueryUnit.java │ │ │ ├── ResultBean.java │ │ │ └── package-info.java │ │ ├── evaluate │ │ │ ├── MyRecommenderEvaluator.java │ │ │ └── package-info.java │ │ └── similarity │ │ │ ├── SimilarityFactory.java │ │ │ ├── UserNeighborhoodFactory.java │ │ │ └── package-info.java │ │ ├── config │ │ ├── model │ │ │ ├── AbstractAlgorithmConfigModel.java │ │ │ ├── AbstractDataConfigModel.java │ │ │ ├── AbstractMixAlgorithmConfigModel.java │ │ │ ├── AbstractPreferenceDataConfigModel.java │ │ │ ├── AbstractSimilarityConfigModel.java │ │ │ ├── AbstractSingleAlgorithmConfigModel.java │ │ │ ├── ContentBasedAlgorithmConfigModel.java │ │ │ ├── DBConfigModel.java │ │ │ ├── DataListConfigModel.java │ │ │ ├── EvaluatorConfigModel.java │ │ │ ├── FilePreferenceDataConfigModel.java │ │ │ ├── IntegralAlgorithmConfigModel.java │ │ │ ├── IntegralConfigModel.java │ │ │ ├── IntegralDataConfigModel.java │ │ │ ├── ItemBasedCFAlgorithmConfigModel.java │ │ │ ├── ItemSimilarityConfigModel.java │ │ │ ├── MySQLContentDataConfigModel.java │ │ │ ├── MySQLPreferenceDataConfigModel.java │ │ │ ├── QueryUnitConfigModel.java │ │ │ ├── SimilarityListConfigModel.java │ │ │ ├── UserBasedCFAlgorithmConfigModel.java │ │ │ ├── UserSimilarityConfigModel.java │ │ │ ├── WaterfallMixAlgorithmConfigModel.java │ │ │ ├── WeightedMixAlgorithmConfigModel.java │ │ │ └── package-info.java │ │ ├── web │ │ │ ├── WebParamAnalyzer.java │ │ │ └── package-info.java │ │ └── xml │ │ │ ├── XMLAnalyzer.java │ │ │ ├── XMLCreator.java │ │ │ └── package-info.java │ │ ├── service │ │ ├── common │ │ │ ├── JettyServer.java │ │ │ ├── RecommenderBuilder.java │ │ │ └── package-info.java │ │ └── controller │ │ │ ├── WebConfigController.java │ │ │ ├── WebServiceController.java │ │ │ └── package-info.java │ │ └── util │ │ ├── ConfigVariables.java │ │ ├── MyEntry.java │ │ ├── MySQLUtil.java │ │ └── package-info.java └── resources │ ├── .idea │ ├── .name │ ├── encodings.xml │ ├── misc.xml │ ├── modules.xml │ ├── resources.iml │ ├── scopes │ │ └── scope_settings.xml │ ├── vcs.xml │ └── workspace.xml │ ├── applicationContext.xml │ ├── css │ ├── images │ │ ├── add-button.gif │ │ ├── button.gif │ │ ├── close.gif │ │ ├── del.gif │ │ ├── edit.gif │ │ ├── footer.gif │ │ ├── header.gif │ │ ├── msg-error.gif │ │ ├── msg-ok.gif │ │ ├── pagging.gif │ │ ├── tab.gif │ │ └── th.gif │ └── style.css │ ├── dispatcherServlet-servlet.xml │ ├── html │ ├── algorithmconfig.html │ ├── dataconfig.html │ ├── evaluatorconfig.html │ ├── finishconfig.html │ ├── similarityconfig.html │ └── startconfig.html │ ├── js │ ├── algorithmConfig.js │ ├── dataConfig.js │ ├── evaluatorConfig.js │ ├── finishConfig.js │ ├── jquery-1.11.3.js │ ├── jquery-1.11.3.min.js │ ├── jquery.cookie.js │ ├── similarityConfig.js │ └── startConfig.js │ ├── log4j.properties │ ├── recommender-demo.xml │ ├── recommender.xsd │ └── web.xml └── test └── java └── test ├── algorithm ├── algorithm │ ├── ContentBasedRecommenderTest.java │ ├── ItemBasedCFRecommenderTest.java │ ├── UserBasedCFRecommenderTest.java │ ├── WaterfallMixRecommenderTest.java │ ├── WeightedMixRecommenderTest.java │ └── package-info.java └── data │ ├── FilePreferenceDataTest.java │ ├── MySQLPreferenceDataTest.java │ └── package-info.java ├── config ├── web │ ├── WebParamAnalyzerTest.java │ └── package-info.java └── xml │ ├── XMLAnalyzerTest.java │ ├── XMLCreatorTest.java │ └── package-info.java └── service ├── RecommenderBuilderTest.java └── package-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings 4 | target 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | easy-recommender 2 | ================ 3 | 4 | 个性化推荐算法的通用处理框架,基于Mahout和Lucene 5 | -------------------------------------------------------------------------------- /dependency-reduced-pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | edu.cuc.dmt 5 | easy-recommender 6 | easy-recommender 7 | 0.0.1-SNAPSHOT 8 | 9 | easy-recommender 10 | 11 | 12 | maven-shade-plugin 13 | 2.2 14 | 15 | 16 | package 17 | 18 | shade 19 | 20 | 21 | 22 | 23 | edu.recm.service.common.JettyServer 24 | 25 | 26 | META-INF/spring.handlers 27 | 28 | 29 | META-INF/spring.schemas 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | UTF-8 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /doc/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 已过时的列表 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

已过时的 API

68 |

目录

69 |
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/cuc/dmt/demo/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.cuc.dmt.demo 8 | 9 | 10 | 11 | 12 |

edu.cuc.dmt.demo

13 |
14 |

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/edu/cuc/dmt/demo/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.cuc.dmt.demo的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.cuc.dmt.demo
的使用

68 |
69 |
没有edu.cuc.dmt.demo的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/algorithm/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.algorithm.algorithm 8 | 9 | 10 | 11 | 12 |

edu.recm.algorithm.algorithm

13 |
14 |

接口

15 | 18 |

19 | 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/data/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.algorithm.data 8 | 9 | 10 | 11 | 12 |

edu.recm.algorithm.data

13 |
14 |

15 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/evaluate/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.algorithm.evaluate 8 | 9 | 10 | 11 | 12 |

edu.recm.algorithm.evaluate

13 |
14 |

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/evaluate/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.algorithm.evaluate的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.algorithm.evaluate
的使用

68 |
69 |
没有edu.recm.algorithm.evaluate的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/similarity/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.algorithm.similarity 8 | 9 | 10 | 11 | 12 |

edu.recm.algorithm.similarity

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/edu/recm/algorithm/similarity/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.algorithm.similarity的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.algorithm.similarity
的使用

68 |
69 |
没有edu.recm.algorithm.similarity的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/config/model/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.config.model 8 | 9 | 10 | 11 | 12 |

edu.recm.config.model

13 |
14 |

15 | 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /doc/edu/recm/config/web/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.config.web 8 | 9 | 10 | 11 | 12 |

edu.recm.config.web

13 |
14 |

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/edu/recm/config/web/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.config.web的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.config.web
的使用

68 |
69 |
没有edu.recm.config.web的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/config/xml/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.config.xml 8 | 9 | 10 | 11 | 12 |

edu.recm.config.xml

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/edu/recm/config/xml/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.config.xml的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.config.xml
的使用

68 |
69 |
没有edu.recm.config.xml的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/service/common/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.service.common 8 | 9 | 10 | 11 | 12 |

edu.recm.service.common

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/edu/recm/service/common/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.service.common的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.service.common
的使用

68 |
69 |
没有edu.recm.service.common的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/service/controller/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.service.controller 8 | 9 | 10 | 11 | 12 |

edu.recm.service.controller

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/edu/recm/service/controller/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.service.controller的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.service.controller
的使用

68 |
69 |
没有edu.recm.service.controller的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/util/class-use/MyEntry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 类 edu.recm.util.MyEntry的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

类 edu.recm.util.MyEntry
的使用

68 |
69 |
没有edu.recm.util.MyEntry的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/util/class-use/MySQLUtil.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 类 edu.recm.util.MySQLUtil的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

类 edu.recm.util.MySQLUtil
的使用

68 |
69 |
没有edu.recm.util.MySQLUtil的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/edu/recm/util/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | edu.recm.util 8 | 9 | 10 | 11 | 12 |

edu.recm.util

13 |
14 |

15 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /doc/edu/recm/util/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 edu.recm.util的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 edu.recm.util
的使用

68 |
69 |
没有edu.recm.util的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 生成的文档 (无标题) 8 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <noscript> 69 | <div>您的浏览器已禁用 JavaScript。</div> 70 | </noscript> 71 | <h2>框架预警</h2> 72 | <p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href="overview-summary.html">非框架版本</a>。</p> 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /doc/overview-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 概览列表 8 | 9 | 10 | 11 | 12 |
所有类
13 |
14 |

程序包

15 | 32 |
33 |

 

34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/package-list: -------------------------------------------------------------------------------- 1 | edu.recm.algorithm.algorithm 2 | edu.recm.algorithm.data 3 | edu.recm.algorithm.evaluate 4 | edu.recm.algorithm.similarity 5 | edu.recm.config.model 6 | edu.recm.config.web 7 | edu.recm.config.xml 8 | edu.recm.service.common 9 | edu.recm.service.controller 10 | edu.recm.util 11 | test.algorithm.algorithm 12 | test.algorithm.data 13 | test.config.web 14 | test.config.xml 15 | test.service 16 | -------------------------------------------------------------------------------- /doc/resources/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/doc/resources/background.gif -------------------------------------------------------------------------------- /doc/resources/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/doc/resources/tab.gif -------------------------------------------------------------------------------- /doc/resources/titlebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/doc/resources/titlebar.gif -------------------------------------------------------------------------------- /doc/resources/titlebar_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/doc/resources/titlebar_end.gif -------------------------------------------------------------------------------- /doc/test/algorithm/algorithm/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.algorithm.algorithm 8 | 9 | 10 | 11 | 12 |

test.algorithm.algorithm

13 |
14 |

15 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /doc/test/algorithm/algorithm/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 test.algorithm.algorithm的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 test.algorithm.algorithm
的使用

68 |
69 |
没有test.algorithm.algorithm的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/test/algorithm/data/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.algorithm.data 8 | 9 | 10 | 11 | 12 |

test.algorithm.data

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/test/algorithm/data/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 test.algorithm.data的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 test.algorithm.data
的使用

68 |
69 |
没有test.algorithm.data的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/test/config/web/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.config.web 8 | 9 | 10 | 11 | 12 |

test.config.web

13 |
14 |

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/test/config/web/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 test.config.web的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 test.config.web
的使用

68 |
69 |
没有test.config.web的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/test/config/xml/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.config.xml 8 | 9 | 10 | 11 | 12 |

test.config.xml

13 |
14 |

15 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/test/config/xml/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 test.config.xml的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 test.config.xml
的使用

68 |
69 |
没有test.config.xml的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/test/service/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.service 8 | 9 | 10 | 11 | 12 |

test.service

13 |
14 |

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/test/service/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 test.service的使用 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 37 |
38 | 65 | 66 |
67 |

程序包 test.service
的使用

68 |
69 |
没有test.service的用法
70 | 71 |
72 | 73 | 74 | 75 | 76 | 86 |
87 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | edu.cuc.dmt 5 | easy-recommender 6 | 0.0.1-SNAPSHOT 7 | easy-recommender 8 | 9 | 10 | 11 | org.apache.mahout 12 | mahout-core 13 | 0.9 14 | 15 | 16 | org.apache.mahout 17 | mahout-integration 18 | 0.9 19 | 20 | 21 | mysql 22 | mysql-connector-java 23 | 5.1.35 24 | 25 | 26 | org.springframework 27 | spring-test 28 | 3.0.5.RELEASE 29 | 30 | 31 | junit 32 | junit 33 | 4.12 34 | 35 | 36 | org.apache.lucene 37 | lucene-queryparser 38 | 4.6.1 39 | 40 | 41 | dom4j 42 | dom4j 43 | 1.6.1 44 | 45 | 46 | org.springframework 47 | spring-webmvc 48 | 3.0.5.RELEASE 49 | 50 | 51 | org.eclipse.jetty.aggregate 52 | jetty-all 53 | 8.0.0.M2 54 | 55 | 56 | net.sf.json-lib 57 | json-lib 58 | 2.4 59 | jdk15 60 | 61 | 62 | log4j 63 | log4j 64 | 1.2.17 65 | 66 | 67 | 68 | easy-recommender 69 | 70 | 71 | 75 | 76 | 78 | 79 | org.apache.maven.plugins 80 | maven-shade-plugin 81 | 2.2 82 | 83 | 84 | package 85 | 86 | shade 87 | 88 | 89 | 90 | 92 | edu.recm.service.common.JettyServer 93 | 94 | 96 | META-INF/spring.handlers 97 | 98 | 100 | META-INF/spring.schemas 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | UTF-8 111 | 112 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/AbstractCFRecommender.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.algorithm; 2 | 3 | import java.util.List; 4 | 5 | 6 | 7 | import org.apache.mahout.cf.taste.recommender.Recommender; 8 | 9 | import edu.recm.algorithm.data.AbstractPreferenceData; 10 | import edu.recm.algorithm.data.ResultBean; 11 | 12 | /** 13 | * 协同过滤推荐器的抽象父类,它有两个实现类:ItemBasedCFRecommender和UserBasedCFRecommender 14 | * @author niuzhixiang 15 | * 16 | */ 17 | public abstract class AbstractCFRecommender implements MyRecommender { 18 | 19 | /** 20 | * 该协同过滤推荐器所属的推荐系统名称 21 | */ 22 | private String recommenderSystemName; 23 | 24 | /** 25 | * 用户偏好数据源 26 | */ 27 | private AbstractPreferenceData preferenceData; 28 | 29 | /** 30 | * 该协同过滤推荐器所使用的相似度度量方法 31 | */ 32 | private String similarityType; 33 | 34 | /** 35 | * Mahout的Recommender 36 | */ 37 | private Recommender recommender; 38 | 39 | public String getRecommenderSystemName() { 40 | return recommenderSystemName; 41 | } 42 | 43 | public void setRecommenderSystemName(String recommenderSystemName) { 44 | this.recommenderSystemName = recommenderSystemName; 45 | } 46 | 47 | public AbstractPreferenceData getPreferenceData() { 48 | return preferenceData; 49 | } 50 | 51 | public void setPreferenceData(AbstractPreferenceData preferenceData) { 52 | this.preferenceData = preferenceData; 53 | } 54 | 55 | public String getSimilarityType() { 56 | return similarityType; 57 | } 58 | 59 | public void setSimilarityType(String similarityType) { 60 | this.similarityType = similarityType; 61 | } 62 | 63 | public Recommender getRecommender() { 64 | return recommender; 65 | } 66 | 67 | public void setRecommender(Recommender recommender) { 68 | this.recommender = recommender; 69 | } 70 | 71 | public AbstractCFRecommender(String recommenderSystemName, 72 | AbstractPreferenceData preferenceData, String similarityType) { 73 | super(); 74 | this.recommenderSystemName = recommenderSystemName; 75 | this.preferenceData = preferenceData; 76 | this.similarityType = similarityType; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/ItemBasedCFRecommender.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.algorithm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.log4j.Logger; 7 | import org.apache.mahout.cf.taste.common.TasteException; 8 | import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender; 9 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 10 | import org.apache.mahout.cf.taste.model.DataModel; 11 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 12 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 13 | import org.apache.mahout.cf.taste.recommender.Recommender; 14 | import org.apache.mahout.cf.taste.similarity.ItemSimilarity; 15 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 16 | 17 | import edu.recm.algorithm.data.AbstractPreferenceData; 18 | import edu.recm.algorithm.data.ResultBean; 19 | import edu.recm.algorithm.similarity.SimilarityFactory; 20 | 21 | /** 22 | * 基于项目的协同过滤推荐器 23 | * @author niuzhixiang 24 | * 25 | */ 26 | public class ItemBasedCFRecommender extends AbstractCFRecommender { 27 | 28 | static Logger logger = Logger.getLogger(ItemBasedCFRecommender.class); 29 | 30 | public ItemBasedCFRecommender(String recommenderSystemName, 31 | AbstractPreferenceData preferenceData, 32 | String similarityType) throws TasteException { 33 | super(recommenderSystemName, preferenceData, similarityType); 34 | 35 | DataModel dataModel = this.getPreferenceData().getDataModel(); 36 | ItemSimilarity itemSimilarity = SimilarityFactory.createItemSimilarity(this.getSimilarityType(), dataModel); 37 | this.setRecommender(new GenericItemBasedRecommender(dataModel, itemSimilarity)); 38 | } 39 | 40 | public List doRecommend(int userid, int resultNum) throws Exception { 41 | List recommendedItems = this.getRecommender().recommend(userid, resultNum); 42 | List resultList = new ArrayList(); 43 | for (RecommendedItem recommendedItem : recommendedItems) { 44 | ResultBean rb = new ResultBean(); 45 | rb.setId(Integer.parseInt(recommendedItem.getItemID()+"")); 46 | rb.setScore(recommendedItem.getValue()); 47 | logger.info("id:" + rb.getId() + ", score:" + rb.getScore()); 48 | resultList.add(rb); 49 | } 50 | logger.info("========================"); 51 | return resultList; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/MyRecommender.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.algorithm; 2 | 3 | import java.util.List; 4 | import edu.recm.algorithm.data.ResultBean; 5 | 6 | /** 7 | * 推荐器接口,包括基于内容的推荐器、基于用户和基于项目的协同过滤推荐器均实现这个接口 8 | * @author niuzhixiang 9 | * 10 | */ 11 | public interface MyRecommender { 12 | 13 | /** 14 | * 为指定的用户进行推荐 15 | * @param userid 用户ID 16 | * @param resultNum 推荐结果数目 17 | * @return 推荐结果集 18 | * @throws Exception 19 | */ 20 | public List doRecommend(int userid, int resultNum) throws Exception; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/MyRecommenderBuilder.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.algorithm; 2 | 3 | import org.apache.mahout.cf.taste.common.TasteException; 4 | import org.apache.mahout.cf.taste.eval.RecommenderBuilder; 5 | import org.apache.mahout.cf.taste.model.DataModel; 6 | import org.apache.mahout.cf.taste.recommender.Recommender; 7 | 8 | /** 9 | * Mahout中RecommenderBuilder的自定义实现类,在算法评估模块中使用 10 | * @author niuzhixiang 11 | * 12 | */ 13 | public class MyRecommenderBuilder implements RecommenderBuilder { 14 | 15 | private Recommender recommender; 16 | 17 | public Recommender getRecommender() { 18 | return recommender; 19 | } 20 | 21 | public void setRecommender(Recommender recommender) { 22 | this.recommender = recommender; 23 | } 24 | 25 | public MyRecommenderBuilder(Recommender recommender) { 26 | super(); 27 | this.recommender = recommender; 28 | } 29 | 30 | public Recommender buildRecommender(DataModel dataModel) 31 | throws TasteException { 32 | // TODO Auto-generated method stub 33 | return this.getRecommender(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/UserBasedCFRecommender.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.algorithm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.log4j.Logger; 7 | import org.apache.mahout.cf.taste.common.TasteException; 8 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 9 | import org.apache.mahout.cf.taste.model.DataModel; 10 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 11 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 12 | import org.apache.mahout.cf.taste.recommender.Recommender; 13 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 14 | 15 | import edu.recm.algorithm.data.AbstractPreferenceData; 16 | import edu.recm.algorithm.data.ResultBean; 17 | import edu.recm.algorithm.similarity.SimilarityFactory; 18 | import edu.recm.algorithm.similarity.UserNeighborhoodFactory; 19 | 20 | /** 21 | * 基于用户的协同过滤推荐器 22 | * @author niuzhixiang 23 | * 24 | */ 25 | public class UserBasedCFRecommender extends AbstractCFRecommender { 26 | 27 | static Logger logger = Logger.getLogger(UserBasedCFRecommender.class); 28 | 29 | /** 30 | * 固定大小的用户邻域大小,该字段为null时表示不使用固定大小的用户邻域,而使用基于阈值的用户邻域 31 | */ 32 | private Integer nNearestUser; 33 | 34 | /** 35 | * 基于阈值的用户邻域阈值,该字段为null时表示不使用基于阈值的用户邻域,而使用固定大小的用户邻域 36 | */ 37 | private Double threshold; 38 | 39 | public Integer getnNearestUser() { 40 | return nNearestUser; 41 | } 42 | 43 | public void setnNearestUser(Integer nNearestUser) { 44 | this.nNearestUser = nNearestUser; 45 | } 46 | 47 | public Double getThreshold() { 48 | return threshold; 49 | } 50 | 51 | public void setThreshold(Double threshold) { 52 | this.threshold = threshold; 53 | } 54 | 55 | public UserBasedCFRecommender(String recommenderSystemName, 56 | AbstractPreferenceData preferenceData, String similarityType, 57 | Integer nNearestUser, Double threshold) 58 | throws Exception { 59 | super(recommenderSystemName, preferenceData, similarityType); 60 | this.nNearestUser = nNearestUser; 61 | this.threshold = threshold; 62 | 63 | DataModel dataModel = this.getPreferenceData().getDataModel(); 64 | UserSimilarity userSimilarity = SimilarityFactory.createUserSimilarity(this.getSimilarityType(), dataModel); 65 | UserNeighborhood userNeighborhood = UserNeighborhoodFactory.createUserNeighborhood(this.nNearestUser, this.threshold, userSimilarity, dataModel); 66 | this.setRecommender(new GenericUserBasedRecommender(dataModel, userNeighborhood, userSimilarity)); 67 | } 68 | 69 | public List doRecommend(int userid, int resultNum) throws Exception { 70 | List recommendedItems = this.getRecommender().recommend(userid, resultNum); 71 | List resultList = new ArrayList(); 72 | for (RecommendedItem recommendedItem : recommendedItems) { 73 | ResultBean rb = new ResultBean(); 74 | rb.setId(Integer.parseInt(recommendedItem.getItemID()+"")); 75 | rb.setScore(recommendedItem.getValue()); 76 | logger.info("id:" + rb.getId() + ", score:" + rb.getScore()); 77 | resultList.add(rb); 78 | } 79 | logger.info("========================"); 80 | return resultList; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/algorithm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 推荐算法处理模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.algorithm.algorithm; -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/AbstractPreferenceData.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.data; 2 | 3 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 4 | import org.apache.mahout.cf.taste.model.DataModel; 5 | 6 | /** 7 | * 表示用户偏好数据的抽象父类 8 | * @author niuzhixiang 9 | * 10 | */ 11 | public abstract class AbstractPreferenceData { 12 | 13 | private DataModel dataModel; 14 | 15 | public DataModel getDataModel() { 16 | return dataModel; 17 | } 18 | 19 | public void setDataModel(DataModel dataModel) { 20 | this.dataModel = dataModel; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/FilePreferenceData.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.data; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.List; 6 | 7 | import org.apache.mahout.cf.taste.impl.model.file.FileDataModel; 8 | import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 9 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 10 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 11 | import org.apache.mahout.cf.taste.model.DataModel; 12 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 13 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 14 | import org.apache.mahout.cf.taste.recommender.Recommender; 15 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 16 | 17 | /** 18 | * 表示来自文件的用户偏好数据的POJO类 19 | * @author niuzhixiang 20 | * 21 | */ 22 | public class FilePreferenceData extends AbstractPreferenceData { 23 | 24 | private String filePath; 25 | 26 | /** 27 | * 用户偏好数据文件存储路径 28 | * @return 29 | */ 30 | public String getFilePath() { 31 | return filePath; 32 | } 33 | 34 | public void setFilePath(String filePath) { 35 | this.filePath = filePath; 36 | } 37 | 38 | public FilePreferenceData(String filePath) { 39 | super(); 40 | this.filePath = filePath; 41 | try { 42 | this.setDataModel(new FileDataModel(new File(filePath))); 43 | } catch (IOException e) { 44 | // TODO Auto-generated catch block 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/MySQLContentData.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.data; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.util.List; 8 | 9 | /** 10 | * 表示来自MySQL的用户与项目特征数据的POJO类 11 | * @author niuzhixiang 12 | * 13 | */ 14 | public class MySQLContentData { 15 | 16 | private String dbServerName; 17 | 18 | private String dbUser; 19 | 20 | private String dbPassword; 21 | 22 | private String dbDatabaseName; 23 | 24 | private String userTableName; 25 | 26 | private String itemTableName; 27 | 28 | private List queryList; 29 | 30 | /** 31 | * 数据库主机名 32 | * @return 33 | */ 34 | public String getDbServerName() { 35 | return dbServerName; 36 | } 37 | 38 | public void setDbServerName(String dbServerName) { 39 | this.dbServerName = dbServerName; 40 | } 41 | 42 | /** 43 | * 数据库用户名 44 | * @return 45 | */ 46 | public String getDbUser() { 47 | return dbUser; 48 | } 49 | 50 | public void setDbUser(String dbUser) { 51 | this.dbUser = dbUser; 52 | } 53 | 54 | /** 55 | * 数据库密码 56 | * @return 57 | */ 58 | public String getDbPassword() { 59 | return dbPassword; 60 | } 61 | 62 | public void setDbPassword(String dbPassword) { 63 | this.dbPassword = dbPassword; 64 | } 65 | 66 | /** 67 | * 数据库名称 68 | * @return 69 | */ 70 | public String getDbDatabaseName() { 71 | return dbDatabaseName; 72 | } 73 | 74 | public void setDbDatabaseName(String dbDatabaseName) { 75 | this.dbDatabaseName = dbDatabaseName; 76 | } 77 | 78 | /** 79 | * 用户特征表 80 | * @return 81 | */ 82 | public String getUserTableName() { 83 | return userTableName; 84 | } 85 | 86 | public void setUserTableName(String userTableName) { 87 | this.userTableName = userTableName; 88 | } 89 | 90 | /** 91 | * 项目特征表 92 | * @return 93 | */ 94 | public String getItemTableName() { 95 | return itemTableName; 96 | } 97 | 98 | public void setItemTableName(String itemTableName) { 99 | this.itemTableName = itemTableName; 100 | } 101 | 102 | /** 103 | * 查询条件列表 104 | * @return 105 | */ 106 | public List getQueryList() { 107 | return queryList; 108 | } 109 | 110 | public void setQueryList(List queryList) { 111 | this.queryList = queryList; 112 | } 113 | 114 | public MySQLContentData() { 115 | super(); 116 | // TODO Auto-generated constructor stub 117 | } 118 | 119 | public MySQLContentData(String dbServerName, String dbUser, 120 | String dbPassword, String dbDatabaseName, String userTableName, 121 | String itemTableName, List queryList) { 122 | super(); 123 | this.dbServerName = dbServerName; 124 | this.dbUser = dbUser; 125 | this.dbPassword = dbPassword; 126 | this.dbDatabaseName = dbDatabaseName; 127 | this.userTableName = userTableName; 128 | this.itemTableName = itemTableName; 129 | this.queryList = queryList; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/QueryUnit.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.data; 2 | 3 | import org.apache.lucene.search.BooleanClause.Occur; 4 | 5 | /** 6 | * 表示单个查询条件的POJO类 7 | * @author niuzhixiang 8 | * 9 | */ 10 | public class QueryUnit { 11 | 12 | /** 13 | * 用户特征字段 14 | */ 15 | private String userField; 16 | 17 | /** 18 | * 项目特征字段 19 | */ 20 | private String itemField; 21 | 22 | /** 23 | * 单个查询条件的逻辑关系 24 | */ 25 | private Occur occur; 26 | 27 | public String getUserField() { 28 | return userField; 29 | } 30 | public void setUserField(String userField) { 31 | this.userField = userField; 32 | } 33 | public String getItemField() { 34 | return itemField; 35 | } 36 | public void setItemField(String itemField) { 37 | this.itemField = itemField; 38 | } 39 | public Occur getOccur() { 40 | return occur; 41 | } 42 | public void setOccur(Occur occur) { 43 | this.occur = occur; 44 | } 45 | 46 | public QueryUnit() { 47 | super(); 48 | // TODO Auto-generated constructor stub 49 | } 50 | public QueryUnit(String userField, String itemField, Occur occur) { 51 | super(); 52 | this.userField = userField; 53 | this.itemField = itemField; 54 | this.occur = occur; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/ResultBean.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.data; 2 | 3 | /** 4 | * 表示单个推荐结果的POJO类 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class ResultBean{ 9 | 10 | /** 11 | * 项目id 12 | */ 13 | private int id; 14 | 15 | /** 16 | * 项目评分 17 | */ 18 | private float score; 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | public void setId(int id) { 24 | this.id = id; 25 | } 26 | public float getScore() { 27 | return score; 28 | } 29 | public void setScore(float score) { 30 | this.score = score; 31 | } 32 | public ResultBean(int id, float score) { 33 | super(); 34 | this.id = id; 35 | this.score = score; 36 | } 37 | public ResultBean() { 38 | super(); 39 | // TODO Auto-generated constructor stub 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/data/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 数据抽象模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.algorithm.data; -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/evaluate/MyRecommenderEvaluator.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.evaluate; 2 | 3 | import org.apache.mahout.cf.taste.eval.IRStatistics; 4 | import org.apache.mahout.cf.taste.eval.RecommenderBuilder; 5 | import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator; 6 | import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator; 7 | import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator; 8 | import org.apache.mahout.common.RandomUtils; 9 | 10 | import edu.recm.algorithm.algorithm.AbstractCFRecommender; 11 | import edu.recm.algorithm.algorithm.MyRecommender; 12 | import edu.recm.algorithm.algorithm.MyRecommenderBuilder; 13 | 14 | /** 15 | * 推荐算法评估器,可以评估查准率、查全率、预测评分误差等指标(仅限于对协同过滤推荐器进行评估);
16 | * 由于评估方法会进行大量计算与资源访问,容易引起内存溢出和资源泄露等操作系统问题,因此在硬件配置较低的情况下请慎用评估器 17 | * @author niuzhixiang 18 | * 19 | */ 20 | public class MyRecommenderEvaluator { 21 | 22 | /** 23 | * 计算给定推荐器的查准率、查全率等各项指标(仅限于协同过滤推荐器) 24 | * @param myRecommender 给定的推荐器 25 | * @return 存有查准率、查全率等各项指标的IRStatistics对象 26 | * @throws Exception 27 | */ 28 | public IRStatistics calculateIRStatistics(MyRecommender myRecommender) throws Exception { 29 | if (myRecommender instanceof AbstractCFRecommender) { 30 | RandomUtils.useTestSeed(); 31 | RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator(); 32 | RecommenderBuilder builder = new MyRecommenderBuilder(((AbstractCFRecommender) myRecommender).getRecommender()); 33 | return evaluator.evaluate(builder, null, ((AbstractCFRecommender) myRecommender).getPreferenceData().getDataModel(), null, 5, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0); 34 | } else { 35 | throw new Exception("推荐器不是协同过滤推荐器,框架无法计算查准率和查全率等指标!"); 36 | } 37 | } 38 | 39 | /** 40 | * 计算给定推荐器的预测评分与实际评分的偏差(仅限于协同过滤推荐器) 41 | * @param myRecommender 给定的推荐器 42 | * @return 预测评分与实际评分的偏差 43 | * @throws Exception 44 | */ 45 | public double calculateDeviation(MyRecommender myRecommender) throws Exception { 46 | if (myRecommender instanceof AbstractCFRecommender) { 47 | RandomUtils.useTestSeed(); 48 | org.apache.mahout.cf.taste.eval.RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator(); 49 | RecommenderBuilder builder = new MyRecommenderBuilder(((AbstractCFRecommender) myRecommender).getRecommender()); 50 | return evaluator.evaluate(builder, null, ((AbstractCFRecommender) myRecommender).getPreferenceData().getDataModel(), 0.7, 0.3); 51 | } else { 52 | throw new Exception("推荐器不是协同过滤推荐器,框架无法计算预测评分误差!"); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/evaluate/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 算法评估模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.algorithm.evaluate; -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/similarity/SimilarityFactory.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.similarity; 2 | 3 | import org.apache.lucene.search.similarities.DefaultSimilarity; 4 | import org.apache.mahout.cf.taste.common.TasteException; 5 | import org.apache.mahout.cf.taste.impl.similarity.CityBlockSimilarity; 6 | import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity; 7 | import org.apache.mahout.cf.taste.impl.similarity.LogLikelihoodSimilarity; 8 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 9 | import org.apache.mahout.cf.taste.impl.similarity.SpearmanCorrelationSimilarity; 10 | import org.apache.mahout.cf.taste.impl.similarity.TanimotoCoefficientSimilarity; 11 | import org.apache.mahout.cf.taste.model.DataModel; 12 | import org.apache.mahout.cf.taste.similarity.ItemSimilarity; 13 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 14 | 15 | import edu.recm.algorithm.data.AbstractPreferenceData; 16 | 17 | /** 18 | * 创建相似度度量方法的工厂类 19 | * @author niuzhixiang 20 | * 21 | */ 22 | public class SimilarityFactory { 23 | 24 | /** 25 | * 创建指定类型的用户相似度度量机制 26 | * @param similarityType 指定的类型 27 | * @param dataModel 数据源 28 | * @return 指定类型的用户相似度度量机制实现类 29 | * @throws TasteException 30 | */ 31 | public static UserSimilarity createUserSimilarity(String similarityType, DataModel dataModel) throws TasteException { 32 | if (similarityType.toLowerCase().equals("pearsoncorrelationsimilarity")) { 33 | return new PearsonCorrelationSimilarity(dataModel); 34 | } 35 | if (similarityType.toLowerCase().equals("euclideandistancesimilarity")) { 36 | return new EuclideanDistanceSimilarity(dataModel); 37 | } 38 | if (similarityType.toLowerCase().equals("tanimotocoefficientsimilarity")) { 39 | return new TanimotoCoefficientSimilarity(dataModel); 40 | } 41 | if (similarityType.toLowerCase().equals("spearmancorrelationsimilarity")) { 42 | return new SpearmanCorrelationSimilarity(dataModel); 43 | } 44 | if (similarityType.toLowerCase().equals("loglikelihoodsimilarity")) { 45 | return new LogLikelihoodSimilarity(dataModel); 46 | } 47 | if (similarityType.toLowerCase().equals("cityblocksimilarity")) { 48 | return new CityBlockSimilarity(dataModel); 49 | } 50 | //默认返回皮尔逊相关系数相似度 51 | return new PearsonCorrelationSimilarity(dataModel); 52 | } 53 | 54 | /** 55 | * 创建指定类型的项目相似度度量机制 56 | * @param similarityType 指定的类型 57 | * @param dataModel 数据源 58 | * @return 指定类型的项目相似度度量机制实现类 59 | * @throws TasteException 60 | */ 61 | public static ItemSimilarity createItemSimilarity(String similarityType, DataModel dataModel) throws TasteException { 62 | if (similarityType.toLowerCase().equals("pearsoncorrelationsimilarity")) { 63 | return new PearsonCorrelationSimilarity(dataModel); 64 | } 65 | if (similarityType.toLowerCase().equals("euclideandistancesimilarity")) { 66 | return new EuclideanDistanceSimilarity(dataModel); 67 | } 68 | if (similarityType.toLowerCase().equals("tanimotocoefficientsimilarity")) { 69 | return new TanimotoCoefficientSimilarity(dataModel); 70 | } 71 | if (similarityType.toLowerCase().equals("loglikelihoodsimilarity")) { 72 | return new LogLikelihoodSimilarity(dataModel); 73 | } 74 | if (similarityType.toLowerCase().equals("cityblocksimilarity")) { 75 | return new CityBlockSimilarity(dataModel); 76 | } 77 | //默认返回皮尔逊相关系数相似度 78 | return new PearsonCorrelationSimilarity(dataModel); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/similarity/UserNeighborhoodFactory.java: -------------------------------------------------------------------------------- 1 | package edu.recm.algorithm.similarity; 2 | 3 | import org.apache.mahout.cf.taste.common.TasteException; 4 | import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 5 | import org.apache.mahout.cf.taste.impl.neighborhood.ThresholdUserNeighborhood; 6 | import org.apache.mahout.cf.taste.model.DataModel; 7 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 8 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 9 | 10 | /** 11 | * 创建用户邻域的工厂类 12 | * @author niuzhixiang 13 | * 14 | */ 15 | public class UserNeighborhoodFactory { 16 | 17 | /** 18 | * 创建固定大小的用户邻域 19 | * @param n 用户邻域的大小 20 | * @param userSimilarity 用户相似度度量机制 21 | * @param dataModel 数据源 22 | * @return 固定大小的用户邻域对象 23 | * @throws TasteException 24 | */ 25 | private static UserNeighborhood createNearestNUserNeighborhood(Integer n, UserSimilarity userSimilarity, DataModel dataModel) throws TasteException { 26 | return new NearestNUserNeighborhood(n, userSimilarity, dataModel); 27 | } 28 | 29 | /** 30 | * 创建基于阈值的用户邻域 31 | * @param threshold 阈值 32 | * @param userSimilarity 用户相似度度量机制 33 | * @param dataModel 数据源 34 | * @return 基于阈值的用户邻域对象 35 | * @throws TasteException 36 | */ 37 | private static UserNeighborhood createThresholdUserNeighborhood(Double threshold, UserSimilarity userSimilarity, DataModel dataModel) throws TasteException { 38 | return new ThresholdUserNeighborhood(threshold, userSimilarity, dataModel); 39 | } 40 | 41 | /** 42 | * 创建指定类型的用户邻域(固定大小的、或基于阈值的);
43 | * 该方法参数n和threshold有且仅有一个为null 44 | * @param n 固定大小的用户邻域的大小,该参数为null时表示应当创建基于阈值的用户邻域 45 | * @param threshold 基于阈值的用户邻域的阈值,该参数为null时表示应当创建固定大小的用户邻域 46 | * @param userSimilarity 用户相似度度量机制 47 | * @param dataModel 数据源 48 | * @return 指定类型的(固定大小或基于阈值的)用户邻域对象 49 | * @throws Exception 50 | */ 51 | public static UserNeighborhood createUserNeighborhood(Integer n, Double threshold, UserSimilarity userSimilarity, DataModel dataModel) throws Exception { 52 | if (n != null && threshold == null) { 53 | return createNearestNUserNeighborhood(n, userSimilarity, dataModel); 54 | } 55 | if (n == null && threshold != null) { 56 | return createThresholdUserNeighborhood(threshold, userSimilarity, dataModel); 57 | } 58 | throw new Exception("创建用户邻域失败!n和threshold中有且仅有一个为null!"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/algorithm/similarity/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 相似度度量和用户邻域模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.algorithm.similarity; -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 推荐算法流程参数配置模型的抽象父类,其子类包括基本推荐算法参数配置模型的实现类、混合推荐算法参数配置模型的实现类 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractAlgorithmConfigModel { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 输入数据源参数配置模型的抽象父类,其子类包括来源于MySQL的特征数据参数配置模型、来源于MySQL的用户偏好数据参数配置模型、来源于文件的用户偏好数据参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractDataConfigModel { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractMixAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 混合推荐算法参数配置模型的抽象父类,其子类包括加权型混合推荐算法参数配置模型的实现类、瀑布型混合推荐算法参数配置模型的实现类 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractMixAlgorithmConfigModel extends AbstractAlgorithmConfigModel { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractPreferenceDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 用户偏好数据参数配置模型的抽象父类。其子类包括来源于MySQL的用户偏好数据参数配置模型、来源于文件的用户偏好数据参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractPreferenceDataConfigModel extends 9 | AbstractDataConfigModel { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractSimilarityConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 相似性度量方法参数配置模型的抽象父类,其子类包括用户间的相似度度量方法参数配置模型、项目间的相似度度量方法参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractSimilarityConfigModel { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/AbstractSingleAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 基本推荐算法参数配置模型的抽象父类,其子类包括基于内容推荐算法参数配置模型的实现类、基于用户的协同过滤推荐算法参数配置模型的实现类、基于项目的协同过滤推荐算法参数配置模型的实现类 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public abstract class AbstractSingleAlgorithmConfigModel extends AbstractAlgorithmConfigModel { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/ContentBasedAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 基于内容推荐算法的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class ContentBasedAlgorithmConfigModel extends 9 | AbstractSingleAlgorithmConfigModel { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/DBConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * MySQL数据源连接配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class DBConfigModel { 9 | 10 | private String dbServerName; 11 | 12 | private String dbUser; 13 | 14 | private String dbPassword; 15 | 16 | /** 17 | * 数据库主机名 18 | * @return 19 | */ 20 | public String getDbServerName() { 21 | return dbServerName; 22 | } 23 | 24 | public void setDbServerName(String dbServerName) { 25 | this.dbServerName = dbServerName; 26 | } 27 | 28 | /** 29 | * 数据库用户名 30 | * @return 31 | */ 32 | public String getDbUser() { 33 | return dbUser; 34 | } 35 | 36 | public void setDbUser(String dbUser) { 37 | this.dbUser = dbUser; 38 | } 39 | 40 | /** 41 | * 数据库密码 42 | * @return 43 | */ 44 | public String getDbPassword() { 45 | return dbPassword; 46 | } 47 | 48 | public void setDbPassword(String dbPassword) { 49 | this.dbPassword = dbPassword; 50 | } 51 | 52 | public DBConfigModel() { 53 | super(); 54 | // TODO Auto-generated constructor stub 55 | } 56 | 57 | public DBConfigModel(String dbServerName, String dbUser, String dbPassword) { 58 | super(); 59 | this.dbServerName = dbServerName; 60 | this.dbUser = dbUser; 61 | this.dbPassword = dbPassword; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/DataListConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 存储多个完整的输入数据源参数配置模型的列表 7 | * @author niuzhixiang 8 | * 9 | */ 10 | public class DataListConfigModel { 11 | 12 | private List dataConfigModelList; 13 | 14 | /** 15 | * 完整的输入数据源参数配置模型的列表 16 | * @return 17 | */ 18 | public List getDataConfigModelList() { 19 | return dataConfigModelList; 20 | } 21 | 22 | public void setDataConfigModelList(List dataConfigModelList) { 23 | this.dataConfigModelList = dataConfigModelList; 24 | } 25 | 26 | public DataListConfigModel() { 27 | super(); 28 | // TODO Auto-generated constructor stub 29 | } 30 | 31 | public DataListConfigModel(List dataConfigModelList) { 32 | super(); 33 | this.dataConfigModelList = dataConfigModelList; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/EvaluatorConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 推荐算法评估机制的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class EvaluatorConfigModel { 9 | 10 | private Boolean deviation; 11 | 12 | private Boolean precision; 13 | 14 | private Boolean recall; 15 | 16 | private Boolean runningTime; 17 | 18 | /** 19 | * 是否评估预测评分差(仅在推荐算法为基本推荐算法、并且是协同过滤推荐算法时该值才有意义) 20 | * @return 21 | */ 22 | public Boolean getDeviation() { 23 | return deviation; 24 | } 25 | 26 | public void setDeviation(Boolean deviation) { 27 | this.deviation = deviation; 28 | } 29 | 30 | /** 31 | * 是否评估查准率(仅在推荐算法为基本推荐算法、并且是协同过滤推荐算法时该值才有意义) 32 | * @return 33 | */ 34 | public Boolean getPrecision() { 35 | return precision; 36 | } 37 | 38 | public void setPrecision(Boolean precision) { 39 | this.precision = precision; 40 | } 41 | 42 | /** 43 | * 是否评估查全率(仅在推荐算法为基本推荐算法、并且是协同过滤推荐算法时该值才有意义) 44 | * @return 45 | */ 46 | public Boolean getRecall() { 47 | return recall; 48 | } 49 | 50 | public void setRecall(Boolean recall) { 51 | this.recall = recall; 52 | } 53 | 54 | /** 55 | * 是否评估算法运行时间 56 | * @return 57 | */ 58 | public Boolean getRunningTime() { 59 | return runningTime; 60 | } 61 | 62 | public void setRunningTime(Boolean runningTime) { 63 | this.runningTime = runningTime; 64 | } 65 | 66 | public EvaluatorConfigModel() { 67 | super(); 68 | // TODO Auto-generated constructor stub 69 | } 70 | 71 | public EvaluatorConfigModel(Boolean deviation, Boolean precision, 72 | Boolean recall, Boolean runningTime) { 73 | super(); 74 | this.deviation = deviation; 75 | this.precision = precision; 76 | this.recall = recall; 77 | this.runningTime = runningTime; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/FilePreferenceDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 来源于文件的用户偏好数据的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class FilePreferenceDataConfigModel extends AbstractPreferenceDataConfigModel { 9 | 10 | private String filePath; 11 | 12 | /** 13 | * 用户偏好数据的文件路径 14 | * @return 15 | */ 16 | public String getFilePath() { 17 | return filePath; 18 | } 19 | 20 | public void setFilePath(String filePath) { 21 | this.filePath = filePath; 22 | } 23 | 24 | public FilePreferenceDataConfigModel() { 25 | super(); 26 | // TODO Auto-generated constructor stub 27 | } 28 | 29 | public FilePreferenceDataConfigModel(String filePath) { 30 | super(); 31 | this.filePath = filePath; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/IntegralAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 完整的推荐算法流程参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class IntegralAlgorithmConfigModel { 9 | 10 | private String algorithmType; 11 | 12 | private AbstractAlgorithmConfigModel algorithmConfigModel; 13 | 14 | /** 15 | * 推荐算法类型,取值为“single”、“weighted”或“waterfall” 16 | * @return 17 | */ 18 | public String getAlgorithmType() { 19 | return algorithmType; 20 | } 21 | 22 | public void setAlgorithmType(String algorithmType) { 23 | this.algorithmType = algorithmType; 24 | } 25 | 26 | /** 27 | * 推荐算法流程的参数配置模型 28 | * @return 29 | */ 30 | public AbstractAlgorithmConfigModel getAlgorithmConfigModel() { 31 | return algorithmConfigModel; 32 | } 33 | 34 | public void setAlgorithmConfigModel( 35 | AbstractAlgorithmConfigModel algorithmConfigModel) { 36 | this.algorithmConfigModel = algorithmConfigModel; 37 | } 38 | 39 | public IntegralAlgorithmConfigModel() { 40 | super(); 41 | // TODO Auto-generated constructor stub 42 | } 43 | 44 | public IntegralAlgorithmConfigModel(String algorithmType, 45 | AbstractAlgorithmConfigModel algorithmConfigModel) { 46 | super(); 47 | this.algorithmType = algorithmType; 48 | this.algorithmConfigModel = algorithmConfigModel; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/IntegralConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 整个推荐系统的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class IntegralConfigModel { 9 | 10 | private String recommenderName; 11 | 12 | private DataListConfigModel dataList; 13 | 14 | private SimilarityListConfigModel similarityList; 15 | 16 | private IntegralAlgorithmConfigModel algorithm; 17 | 18 | private EvaluatorConfigModel evaluator; 19 | 20 | /** 21 | * 推荐系统的唯一名称 22 | * @return 23 | */ 24 | public String getRecommenderName() { 25 | return recommenderName; 26 | } 27 | 28 | public void setRecommenderName(String recommenderName) { 29 | this.recommenderName = recommenderName; 30 | } 31 | 32 | /** 33 | * 输入数据源参数配置模型的列表 34 | * @return 35 | */ 36 | public DataListConfigModel getDataList() { 37 | return dataList; 38 | } 39 | 40 | public void setDataList(DataListConfigModel dataList) { 41 | this.dataList = dataList; 42 | } 43 | 44 | /** 45 | * 相似度度量方法参数配置模型的列表 46 | * @return 47 | */ 48 | public SimilarityListConfigModel getSimilarityList() { 49 | return similarityList; 50 | } 51 | 52 | public void setSimilarityList(SimilarityListConfigModel similarityList) { 53 | this.similarityList = similarityList; 54 | } 55 | 56 | /** 57 | * 推荐算法处理流程参数配置模型 58 | * @return 59 | */ 60 | public IntegralAlgorithmConfigModel getAlgorithm() { 61 | return algorithm; 62 | } 63 | 64 | public void setAlgorithm(IntegralAlgorithmConfigModel algorithm) { 65 | this.algorithm = algorithm; 66 | } 67 | 68 | /** 69 | * 推荐算法评估机制参数配置模型 70 | * @return 71 | */ 72 | public EvaluatorConfigModel getEvaluator() { 73 | return evaluator; 74 | } 75 | 76 | public void setEvaluator(EvaluatorConfigModel evaluator) { 77 | this.evaluator = evaluator; 78 | } 79 | 80 | public IntegralConfigModel() { 81 | super(); 82 | // TODO Auto-generated constructor stub 83 | } 84 | 85 | public IntegralConfigModel(String recommenderName, 86 | DataListConfigModel dataList, 87 | SimilarityListConfigModel similarityList, 88 | IntegralAlgorithmConfigModel algorithm, 89 | EvaluatorConfigModel evaluator) { 90 | super(); 91 | this.recommenderName = recommenderName; 92 | this.dataList = dataList; 93 | this.similarityList = similarityList; 94 | this.algorithm = algorithm; 95 | this.evaluator = evaluator; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/IntegralDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 完整的输入数据源参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class IntegralDataConfigModel { 9 | 10 | private String dataType; 11 | 12 | private String sourceType; 13 | 14 | private DBConfigModel dbConfigModel; 15 | 16 | private AbstractDataConfigModel dataConfigModel; 17 | 18 | /** 19 | * 输入数据源的类型,取值为“content”或“preference” 20 | * @return 21 | */ 22 | public String getDataType() { 23 | return dataType; 24 | } 25 | 26 | public void setDataType(String dataType) { 27 | this.dataType = dataType; 28 | } 29 | 30 | /** 31 | * 输入数据源的来源,取值为“mysql”或“file”(当dataType取值为“content”时只能取值为“mysql”) 32 | * @return 33 | */ 34 | public String getSourceType() { 35 | return sourceType; 36 | } 37 | 38 | public void setSourceType(String sourceType) { 39 | this.sourceType = sourceType; 40 | } 41 | 42 | /** 43 | * MySQL数据源连接配置模型。若该字段为null,说明是文件数据源 44 | * @return 45 | */ 46 | public DBConfigModel getDbConfigModel() { 47 | return dbConfigModel; 48 | } 49 | 50 | public void setDbConfigModel(DBConfigModel dbConfigModel) { 51 | this.dbConfigModel = dbConfigModel; 52 | } 53 | 54 | /** 55 | * 输入数据源的参数配置模型 56 | * @return 57 | */ 58 | public AbstractDataConfigModel getDataConfigModel() { 59 | return dataConfigModel; 60 | } 61 | 62 | public void setDataConfigModel(AbstractDataConfigModel dataConfigModel) { 63 | this.dataConfigModel = dataConfigModel; 64 | } 65 | 66 | public IntegralDataConfigModel() { 67 | super(); 68 | // TODO Auto-generated constructor stub 69 | } 70 | 71 | public IntegralDataConfigModel(String dataType, String sourceType, 72 | DBConfigModel dbConfigModel, AbstractDataConfigModel dataConfigModel) { 73 | super(); 74 | this.dataType = dataType; 75 | this.sourceType = sourceType; 76 | this.dbConfigModel = dbConfigModel; 77 | this.dataConfigModel = dataConfigModel; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/ItemBasedCFAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 基于项目的协同过滤推荐算法参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class ItemBasedCFAlgorithmConfigModel extends 9 | AbstractSingleAlgorithmConfigModel { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/ItemSimilarityConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 项目间的相似度度量方法参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class ItemSimilarityConfigModel extends AbstractSimilarityConfigModel { 9 | 10 | private String similarityType; 11 | 12 | /** 13 | * 相似度度量方法的类型 14 | * @return 15 | */ 16 | public String getSimilarityType() { 17 | return similarityType; 18 | } 19 | 20 | public void setSimilarityType(String similarityType) { 21 | this.similarityType = similarityType; 22 | } 23 | 24 | public ItemSimilarityConfigModel() { 25 | super(); 26 | // TODO Auto-generated constructor stub 27 | } 28 | 29 | public ItemSimilarityConfigModel(String similarityType) { 30 | super(); 31 | this.similarityType = similarityType; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/MySQLContentDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 来源于MySQL的用户及项目特征数据的参数配置模型 7 | * @author niuzhixiang 8 | * 9 | */ 10 | public class MySQLContentDataConfigModel extends AbstractDataConfigModel { 11 | 12 | private String dbDatabaseName; 13 | 14 | private String userTableName; 15 | 16 | private String itemTableName; 17 | 18 | private List queryUnitConfigModelList; 19 | 20 | /** 21 | * 数据库名 22 | * @return 23 | */ 24 | public String getDbDatabaseName() { 25 | return dbDatabaseName; 26 | } 27 | 28 | public void setDbDatabaseName(String dbDatabaseName) { 29 | this.dbDatabaseName = dbDatabaseName; 30 | } 31 | 32 | /** 33 | * 用户表名 34 | * @return 35 | */ 36 | public String getUserTableName() { 37 | return userTableName; 38 | } 39 | 40 | public void setUserTableName(String userTableName) { 41 | this.userTableName = userTableName; 42 | } 43 | 44 | /** 45 | * 项目表名 46 | * @return 47 | */ 48 | public String getItemTableName() { 49 | return itemTableName; 50 | } 51 | 52 | public void setItemTableName(String itemTableName) { 53 | this.itemTableName = itemTableName; 54 | } 55 | 56 | /** 57 | * 查询条件参数配置模型的列表 58 | * @return 59 | */ 60 | public List getQueryUnitConfigModelList() { 61 | return queryUnitConfigModelList; 62 | } 63 | 64 | public void setQueryUnitConfigModelList( 65 | List queryUnitConfigModelList) { 66 | this.queryUnitConfigModelList = queryUnitConfigModelList; 67 | } 68 | 69 | public MySQLContentDataConfigModel() { 70 | super(); 71 | // TODO Auto-generated constructor stub 72 | } 73 | 74 | public MySQLContentDataConfigModel(String dbDatabaseName, String userTableName, 75 | String itemTableName, 76 | List queryUnitConfigModelList) { 77 | super(); 78 | this.dbDatabaseName = dbDatabaseName; 79 | this.userTableName = userTableName; 80 | this.itemTableName = itemTableName; 81 | this.queryUnitConfigModelList = queryUnitConfigModelList; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/MySQLPreferenceDataConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 来源于MySQL的用户偏好数据的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class MySQLPreferenceDataConfigModel extends AbstractPreferenceDataConfigModel { 9 | 10 | private String dbDatabaseName; 11 | 12 | private String preferenceTable; 13 | 14 | private String userIDColumn; 15 | 16 | private String itemIDColumn; 17 | 18 | private String preferenceColumn; 19 | 20 | private String timestampColumn; 21 | 22 | /** 23 | * 数据库名 24 | * @return 25 | */ 26 | public String getDbDatabaseName() { 27 | return dbDatabaseName; 28 | } 29 | 30 | public void setDbDatabaseName(String dbDatabaseName) { 31 | this.dbDatabaseName = dbDatabaseName; 32 | } 33 | 34 | /** 35 | * 用户偏好数据表名 36 | * @return 37 | */ 38 | public String getPreferenceTable() { 39 | return preferenceTable; 40 | } 41 | 42 | public void setPreferenceTable(String preferenceTable) { 43 | this.preferenceTable = preferenceTable; 44 | } 45 | 46 | /** 47 | * 用户ID字段名 48 | * @return 49 | */ 50 | public String getUserIDColumn() { 51 | return userIDColumn; 52 | } 53 | 54 | public void setUserIDColumn(String userIDColumn) { 55 | this.userIDColumn = userIDColumn; 56 | } 57 | 58 | /** 59 | * 项目ID字段名 60 | * @return 61 | */ 62 | public String getItemIDColumn() { 63 | return itemIDColumn; 64 | } 65 | 66 | public void setItemIDColumn(String itemIDColumn) { 67 | this.itemIDColumn = itemIDColumn; 68 | } 69 | 70 | /** 71 | * 偏好值字段名 72 | * @return 73 | */ 74 | public String getPreferenceColumn() { 75 | return preferenceColumn; 76 | } 77 | 78 | public void setPreferenceColumn(String preferenceColumn) { 79 | this.preferenceColumn = preferenceColumn; 80 | } 81 | 82 | /** 83 | * 时间戳字段名 84 | * @return 85 | */ 86 | public String getTimestampColumn() { 87 | return timestampColumn; 88 | } 89 | 90 | public void setTimestampColumn(String timestampColumn) { 91 | this.timestampColumn = timestampColumn; 92 | } 93 | 94 | public MySQLPreferenceDataConfigModel() { 95 | super(); 96 | // TODO Auto-generated constructor stub 97 | } 98 | 99 | public MySQLPreferenceDataConfigModel(String dbDatabaseName, 100 | String preferenceTable, String userIDColumn, String itemIDColumn, 101 | String preferenceColumn, String timestampColumn) { 102 | super(); 103 | this.dbDatabaseName = dbDatabaseName; 104 | this.preferenceTable = preferenceTable; 105 | this.userIDColumn = userIDColumn; 106 | this.itemIDColumn = itemIDColumn; 107 | this.preferenceColumn = preferenceColumn; 108 | this.timestampColumn = timestampColumn; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/QueryUnitConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 表示单个查询对象的参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class QueryUnitConfigModel { 9 | 10 | private String userColumn; 11 | 12 | private String itemColumn; 13 | 14 | private String occur; 15 | 16 | /** 17 | * 用户特征字段 18 | * @return 19 | */ 20 | public String getUserColumn() { 21 | return userColumn; 22 | } 23 | 24 | public void setUserColumn(String userColumn) { 25 | this.userColumn = userColumn; 26 | } 27 | 28 | /** 29 | * 项目特征字段 30 | * @return 31 | */ 32 | public String getItemColumn() { 33 | return itemColumn; 34 | } 35 | 36 | public void setItemColumn(String itemColumn) { 37 | this.itemColumn = itemColumn; 38 | } 39 | 40 | /** 41 | * 单个查询条件的逻辑关系 42 | * @return 43 | */ 44 | public String getOccur() { 45 | return occur; 46 | } 47 | 48 | public void setOccur(String occur) { 49 | this.occur = occur; 50 | } 51 | 52 | public QueryUnitConfigModel() { 53 | super(); 54 | // TODO Auto-generated constructor stub 55 | } 56 | 57 | public QueryUnitConfigModel(String userColumn, String itemColumn, 58 | String occur) { 59 | super(); 60 | this.userColumn = userColumn; 61 | this.itemColumn = itemColumn; 62 | this.occur = occur; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/SimilarityListConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 存储多个相似度度量参数配置模型的列表 7 | * @author niuzhixiang 8 | * 9 | */ 10 | public class SimilarityListConfigModel { 11 | 12 | private List similarityConfigModelList; 13 | 14 | /** 15 | * 相似度度量参数配置模型的列表 16 | * @return 17 | */ 18 | public List getSimilarityConfigModelList() { 19 | return similarityConfigModelList; 20 | } 21 | 22 | public void setSimilarityConfigModelList( 23 | List similarityConfigModelList) { 24 | this.similarityConfigModelList = similarityConfigModelList; 25 | } 26 | 27 | public SimilarityListConfigModel() { 28 | super(); 29 | // TODO Auto-generated constructor stub 30 | } 31 | 32 | public SimilarityListConfigModel( 33 | List similarityConfigModelList) { 34 | super(); 35 | this.similarityConfigModelList = similarityConfigModelList; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/UserBasedCFAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 基于用户的协同过滤推荐算法参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class UserBasedCFAlgorithmConfigModel extends 9 | AbstractSingleAlgorithmConfigModel { 10 | 11 | private String userNeighborhoodType; 12 | 13 | private Double threshold; 14 | 15 | private Integer nUser; 16 | 17 | /** 18 | * 用户邻域类型,取值为“nearestN”或“threshold” 19 | * @return 20 | */ 21 | public String getUserNeighborhoodType() { 22 | return userNeighborhoodType; 23 | } 24 | 25 | public void setUserNeighborhoodType(String userNeighborhoodType) { 26 | this.userNeighborhoodType = userNeighborhoodType; 27 | } 28 | 29 | /** 30 | * 基于阈值的用户邻域的阈值,当userNeighborhoodType字段取值为“threshold”时该字段不为null 31 | * @return 32 | */ 33 | public Double getThreshold() { 34 | return threshold; 35 | } 36 | 37 | public void setThreshold(Double threshold) { 38 | this.threshold = threshold; 39 | } 40 | 41 | /** 42 | * 固定大小的用户邻域的大小,当userNeighborhoodType字段取值为“nearestN”时该字段不为null 43 | * @return 44 | */ 45 | public Integer getnUser() { 46 | return nUser; 47 | } 48 | 49 | public void setnUser(Integer nUser) { 50 | this.nUser = nUser; 51 | } 52 | 53 | public UserBasedCFAlgorithmConfigModel() { 54 | super(); 55 | // TODO Auto-generated constructor stub 56 | } 57 | 58 | public UserBasedCFAlgorithmConfigModel(String userNeighborhoodType, 59 | Double threshold, Integer nUser) { 60 | super(); 61 | this.userNeighborhoodType = userNeighborhoodType; 62 | this.threshold = threshold; 63 | this.nUser = nUser; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/UserSimilarityConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | /** 4 | * 用户间的相似度度量方法参数配置模型 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class UserSimilarityConfigModel extends AbstractSimilarityConfigModel { 9 | 10 | private String similarityType; 11 | 12 | /** 13 | * 相似度度量方法的类型 14 | * @return 15 | */ 16 | public String getSimilarityType() { 17 | return similarityType; 18 | } 19 | 20 | public void setSimilarityType(String similarityType) { 21 | this.similarityType = similarityType; 22 | } 23 | 24 | public UserSimilarityConfigModel() { 25 | super(); 26 | // TODO Auto-generated constructor stub 27 | } 28 | 29 | public UserSimilarityConfigModel(String similarityType) { 30 | super(); 31 | this.similarityType = similarityType; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/WaterfallMixAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | import java.util.List; 4 | import java.util.Map.Entry; 5 | 6 | /** 7 | * 瀑布型混合推荐算法的参数配置模型 8 | * @author niuzhixiang 9 | * 10 | */ 11 | public class WaterfallMixAlgorithmConfigModel extends AbstractMixAlgorithmConfigModel { 12 | 13 | private List> list; 14 | 15 | /** 16 | * 该List存储瀑布型混合推荐算法中包含的各个基本推荐算法及其相应的筛选数目 17 | * @return 18 | */ 19 | public List> getList() { 20 | return list; 21 | } 22 | 23 | public void setList( 24 | List> list) { 25 | this.list = list; 26 | } 27 | 28 | public WaterfallMixAlgorithmConfigModel() { 29 | super(); 30 | // TODO Auto-generated constructor stub 31 | } 32 | 33 | public WaterfallMixAlgorithmConfigModel( 34 | List> list) { 35 | super(); 36 | this.list = list; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/WeightedMixAlgorithmConfigModel.java: -------------------------------------------------------------------------------- 1 | package edu.recm.config.model; 2 | 3 | import java.util.List; 4 | import java.util.Map.Entry; 5 | 6 | /** 7 | * 加权型混合推荐算法的参数配置模型 8 | * @author niuzhixiang 9 | * 10 | */ 11 | public class WeightedMixAlgorithmConfigModel extends 12 | AbstractMixAlgorithmConfigModel { 13 | 14 | private List> list; 15 | 16 | /** 17 | * 该List存储加权型混合推荐算法中包含的各个基本推荐算法及其相应的权重 18 | * @return 19 | */ 20 | public List> getList() { 21 | return list; 22 | } 23 | 24 | public void setList(List> list) { 25 | this.list = list; 26 | } 27 | 28 | public WeightedMixAlgorithmConfigModel() { 29 | super(); 30 | // TODO Auto-generated constructor stub 31 | } 32 | 33 | public WeightedMixAlgorithmConfigModel( 34 | List> list) { 35 | super(); 36 | this.list = list; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/model/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 描述推荐系统的参数配置模型 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.config.model; -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/web/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Web配置页面传入参数的解析 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.config.web; -------------------------------------------------------------------------------- /src/main/java/edu/recm/config/xml/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 描述推荐系统的XML配置文件的创建与解析 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.config.xml; -------------------------------------------------------------------------------- /src/main/java/edu/recm/service/common/JettyServer.java: -------------------------------------------------------------------------------- 1 | package edu.recm.service.common; 2 | 3 | import org.eclipse.jetty.server.Server; 4 | import org.eclipse.jetty.servlet.ServletHandler; 5 | import org.eclipse.jetty.webapp.WebAppContext; 6 | 7 | /** 8 | * 启动Jetty服务器 9 | * @author niuzhixiang 10 | * 11 | */ 12 | public class JettyServer { 13 | 14 | protected static final int PORT = 9999; 15 | protected static final String RESOURCE_BASE = "src/main/resources"; 16 | protected static final String CONTEXT_PATH = "/sr"; 17 | 18 | public static void main(String[] args) { 19 | Server server = new Server(PORT); 20 | WebAppContext context = new WebAppContext(); 21 | context.setDescriptor(JettyServer.class.getClassLoader().getResource("web.xml").toString()); 22 | context.setResourceBase(RESOURCE_BASE); 23 | context.setClassLoader(Thread.currentThread().getContextClassLoader()); 24 | context.setContextPath(CONTEXT_PATH); 25 | server.setHandler(context); 26 | ServletHandler servletHandler = new ServletHandler(); 27 | context.setServletHandler(servletHandler); 28 | try { 29 | server.start(); 30 | } catch (Exception e) { 31 | // TODO Auto-generated catch block 32 | e.printStackTrace(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/service/common/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 服务模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.service.common; -------------------------------------------------------------------------------- /src/main/java/edu/recm/service/controller/WebConfigController.java: -------------------------------------------------------------------------------- 1 | package edu.recm.service.controller; 2 | 3 | import javax.servlet.http.Cookie; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | 7 | import net.sf.json.JSONArray; 8 | import net.sf.json.JSONObject; 9 | 10 | import org.apache.log4j.Logger; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.CookieValue; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | import org.springframework.web.servlet.ModelAndView; 17 | 18 | import edu.recm.config.model.IntegralConfigModel; 19 | import edu.recm.config.web.WebParamAnalyzer; 20 | import edu.recm.config.xml.XMLCreator; 21 | 22 | /** 23 | * Web配置模块的后端Controller 24 | * @author niuzhixiang 25 | * 26 | */ 27 | @Controller 28 | @RequestMapping("/config") 29 | public class WebConfigController { 30 | 31 | static Logger logger = Logger.getLogger(WebConfigController.class); 32 | 33 | @RequestMapping(value="/start", method=RequestMethod.GET) 34 | public ModelAndView showStartPage() { 35 | return new ModelAndView("startconfig"); 36 | } 37 | 38 | @RequestMapping(value="/dataconfig", method=RequestMethod.GET) 39 | public ModelAndView showDataConfigPage() { 40 | return new ModelAndView("dataconfig"); 41 | } 42 | 43 | @RequestMapping(value="/similarityconfig", method=RequestMethod.GET) 44 | public ModelAndView showSimilarityConfigPage() { 45 | return new ModelAndView("similarityconfig"); 46 | } 47 | 48 | @RequestMapping(value="/algorithmconfig", method=RequestMethod.GET) 49 | public ModelAndView showAlgorithmConfigPage() { 50 | return new ModelAndView("algorithmconfig"); 51 | } 52 | 53 | @RequestMapping(value="/evaluatorconfig", method=RequestMethod.GET) 54 | public ModelAndView showEvaluatorConfigPage() { 55 | return new ModelAndView("evaluatorconfig"); 56 | } 57 | 58 | @RequestMapping(value="/finish", method=RequestMethod.GET) 59 | public ModelAndView showFinishPage() { 60 | return new ModelAndView("finishconfig"); 61 | } 62 | 63 | /** 64 | * 接收前端配置页面传入的参数,创建推荐系统的XML配置文件 65 | * @param request 66 | * @param response 67 | * @return 68 | */ 69 | @RequestMapping(value="/receiveconfig", method=RequestMethod.POST) 70 | @ResponseBody 71 | public String receiveConfig(HttpServletRequest request, HttpServletResponse response) { 72 | String jsonParam = request.getParameter("configJSON").replaceAll("\"", "'"); 73 | logger.info(jsonParam); 74 | WebParamAnalyzer webParamAnalyzer = new WebParamAnalyzer(); 75 | XMLCreator xmlCreator = new XMLCreator(); 76 | try { 77 | IntegralConfigModel config = webParamAnalyzer.buildConfigModel(jsonParam); 78 | xmlCreator.createXMLConfigFile(config); 79 | return "success"; 80 | } catch (Exception e) { 81 | // TODO Auto-generated catch block 82 | e.printStackTrace(); 83 | return "fail:" + e.getMessage(); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/service/controller/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Web后端模块,包括Web配置模块的后端程序和提供推荐服务的后端程序 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.service.controller; -------------------------------------------------------------------------------- /src/main/java/edu/recm/util/ConfigVariables.java: -------------------------------------------------------------------------------- 1 | package edu.recm.util; 2 | 3 | /** 4 | * 框架中使用的常量定义 5 | * @author niuzhixiang 6 | * 7 | */ 8 | public class ConfigVariables { 9 | 10 | public static final String XML_CONFIG_FILE_DIR = "D:/xmlconfigfiles/"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/util/MyEntry.java: -------------------------------------------------------------------------------- 1 | package edu.recm.util; 2 | 3 | import java.util.Map.Entry; 4 | 5 | import edu.recm.algorithm.algorithm.MyRecommender; 6 | 7 | /** 8 | * java.util.Map.Entry的自定义实现类 9 | * @author niuzhixiang 10 | * 11 | */ 12 | public class MyEntry implements Entry { 13 | 14 | private final K key; 15 | private V value; 16 | 17 | public MyEntry(K key, V value) { 18 | super(); 19 | this.key = key; 20 | this.value = value; 21 | } 22 | 23 | public K getKey() { 24 | // TODO Auto-generated method stub 25 | return this.key; 26 | } 27 | 28 | public V getValue() { 29 | // TODO Auto-generated method stub 30 | return this.value; 31 | } 32 | 33 | public V setValue(V value) { 34 | // TODO Auto-generated method stub 35 | V old = this.value; 36 | this.value = value; 37 | return old; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/util/MySQLUtil.java: -------------------------------------------------------------------------------- 1 | package edu.recm.util; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | 8 | /** 9 | * 处理MySQL相关操作的工具类 10 | * @author niuzhixiang 11 | * 12 | */ 13 | public class MySQLUtil { 14 | 15 | /** 16 | * 连接MySQL 17 | * @param serverName 数据库主机名 18 | * @param user 数据库用户名 19 | * @param password 数据库密码 20 | * @param dbName 数据库名称 21 | * @return 用于执行SQL查询的Statement对象 22 | */ 23 | public static Statement connectMySQL(String serverName, String user, String password, String dbName) { 24 | try { 25 | Class.forName("com.mysql.jdbc.Driver"); 26 | } catch (ClassNotFoundException e) { 27 | // TODO Auto-generated catch block 28 | e.printStackTrace(); 29 | return null; 30 | } 31 | try { 32 | Connection connection = DriverManager.getConnection("jdbc:mysql://" + serverName + ":3306/" + dbName, user, password); 33 | Statement statement = connection.createStatement(); 34 | return statement; 35 | } catch (SQLException e) { 36 | // TODO Auto-generated catch block 37 | e.printStackTrace(); 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/edu/recm/util/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 工具类 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package edu.recm.util; -------------------------------------------------------------------------------- /src/main/resources/.idea/.name: -------------------------------------------------------------------------------- 1 | resources -------------------------------------------------------------------------------- /src/main/resources/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/.idea/resources.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /src/main/resources/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/css/images/add-button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/add-button.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/button.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/close.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/close.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/del.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/del.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/edit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/edit.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/footer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/footer.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/header.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/msg-error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/msg-error.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/msg-ok.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/msg-ok.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/pagging.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/pagging.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/tab.gif -------------------------------------------------------------------------------- /src/main/resources/css/images/th.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drogba321/easy-recommender/0b12b89f5ac46b149cf6154c1fb273b35090c7af/src/main/resources/css/images/th.gif -------------------------------------------------------------------------------- /src/main/resources/dispatcherServlet-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/resources/html/startconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 欢迎使用Simple Recommender 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 35 | 36 | 37 | 38 |
39 |
40 | 41 | 42 | 47 | 48 | 49 | 50 |
51 |
 
52 | 53 | 54 |
55 | 56 | 57 |
58 | 59 |
60 |

开始配置

61 |
62 | 63 | 64 |
65 | 66 | 67 |
68 |
69 |

70 | 71 | 72 |
73 |

74 |
75 |
76 | 77 |
78 |
79 | 80 | 81 | 82 |
83 | 84 | 85 | 108 | 109 | 110 |
 
111 |
112 | 113 |
114 |
115 | 116 | 117 | 118 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /src/main/resources/js/evaluatorConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 算法评估机制配置页面JS 3 | */ 4 | 5 | $(function(){ 6 | 7 | }); 8 | 9 | /** 10 | * 向后端提交推荐系统的配置信息 11 | * */ 12 | function commitConfig(){ 13 | $.ajax({ 14 | async : false, 15 | type : "POST", 16 | dataType : "text", 17 | mode : "block", 18 | url : "/sr/config/receiveconfig", 19 | data : $("#configForm").serialize(), 20 | success : function(data){ 21 | if(data == "success"){ 22 | window.location.href = "/sr/config/finish"; 23 | } else { 24 | alert(data); 25 | } 26 | }, 27 | error : function(){ 28 | alert("发生错误,请重试!"); 29 | } 30 | }); 31 | } 32 | 33 | /** 34 | * 建立算法评估机制参数配置模型的JSON对象 35 | * */ 36 | function buildEvaluator(){ 37 | var evaluator = new Object(); 38 | evaluator.deviation = $("select[name='deviation']").val(); 39 | evaluator.precision = $("select[name='precision']").val(); 40 | evaluator.recall = $("select[name='recall']").val(); 41 | evaluator.runningTime = $("select[name='runningTime']").val(); 42 | 43 | $.cookie("evaluator", JSON.stringify(evaluator)); 44 | console.log("evaluator:" + JSON.stringify(evaluator)); 45 | } 46 | 47 | /** 48 | * 建立整个推荐系统参数配置模型的JSON对象 49 | * */ 50 | function buildConfig(){ 51 | buildEvaluator(); 52 | var config = new Object(); 53 | 54 | var recommenderName = $.cookie("recommenderName"); 55 | var dataList = $.parseJSON($.cookie("dataList")); 56 | var similarityList = $.parseJSON($.cookie("similarityList")); 57 | var algorithm = $.parseJSON($.cookie("algorithm")); 58 | var evaluator = $.parseJSON($.cookie("evaluator")); 59 | 60 | config.recommenderName = recommenderName; 61 | config.dataList = dataList; 62 | config.similarityList = similarityList; 63 | config.algorithm = algorithm; 64 | config.evaluator = evaluator; 65 | 66 | 67 | var finalConfig = JSON.stringify(config).replace(/\"/g, "'").replace(/\\\\/g, "/").replace(/\\/g, "/"); 68 | console.log("config:" + JSON.stringify(finalConfig)); 69 | 70 | $("#configJSON").val(finalConfig); 71 | 72 | commitConfig(); 73 | } 74 | -------------------------------------------------------------------------------- /src/main/resources/js/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.4.1 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD 11 | define(['jquery'], factory); 12 | } else if (typeof exports === 'object') { 13 | // CommonJS 14 | factory(require('jquery')); 15 | } else { 16 | // Browser globals 17 | factory(jQuery); 18 | } 19 | }(function ($) { 20 | 21 | var pluses = /\+/g; 22 | 23 | function encode(s) { 24 | return config.raw ? s : encodeURIComponent(s); 25 | } 26 | 27 | function decode(s) { 28 | return config.raw ? s : decodeURIComponent(s); 29 | } 30 | 31 | //为了防止JSON数据中的特殊字符“{”、“}”和“:”被转义,因此不进行encode操作,牛志向编辑于2015-05-21 32 | function stringifyCookieValue(value) { 33 | //return encode(config.json ? JSON.stringify(value) : String(value)); 34 | return config.json ? JSON.stringify(value) : String(value); 35 | } 36 | 37 | function parseCookieValue(s) { 38 | if (s.indexOf('"') === 0) { 39 | // This is a quoted cookie as according to RFC2068, unescape... 40 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 41 | } 42 | 43 | try { 44 | // Replace server-side written pluses with spaces. 45 | // If we can't decode the cookie, ignore it, it's unusable. 46 | // If we can't parse the cookie, ignore it, it's unusable. 47 | s = decodeURIComponent(s.replace(pluses, ' ')); 48 | return config.json ? JSON.parse(s) : s; 49 | } catch(e) {} 50 | } 51 | 52 | function read(s, converter) { 53 | var value = config.raw ? s : parseCookieValue(s); 54 | return $.isFunction(converter) ? converter(value) : value; 55 | } 56 | 57 | var config = $.cookie = function (key, value, options) { 58 | 59 | // Write 60 | 61 | if (value !== undefined && !$.isFunction(value)) { 62 | options = $.extend({}, config.defaults, options); 63 | 64 | if (typeof options.expires === 'number') { 65 | var days = options.expires, t = options.expires = new Date(); 66 | t.setTime(+t + days * 864e+5); 67 | } 68 | 69 | return (document.cookie = [ 70 | encode(key), '=', stringifyCookieValue(value), 71 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 72 | options.path ? '; path=' + options.path : '', 73 | options.domain ? '; domain=' + options.domain : '', 74 | options.secure ? '; secure' : '' 75 | ].join('')); 76 | } 77 | 78 | // Read 79 | 80 | var result = key ? undefined : {}; 81 | 82 | // To prevent the for loop in the first place assign an empty array 83 | // in case there are no cookies at all. Also prevents odd result when 84 | // calling $.cookie(). 85 | var cookies = document.cookie ? document.cookie.split('; ') : []; 86 | 87 | for (var i = 0, l = cookies.length; i < l; i++) { 88 | var parts = cookies[i].split('='); 89 | var name = decode(parts.shift()); 90 | var cookie = parts.join('='); 91 | 92 | if (key && key === name) { 93 | // If second argument (value) is a function it's a converter... 94 | result = read(cookie, value); 95 | break; 96 | } 97 | 98 | // Prevent storing a cookie that we couldn't decode. 99 | if (!key && (cookie = read(cookie)) !== undefined) { 100 | result[name] = cookie; 101 | } 102 | } 103 | 104 | return result; 105 | }; 106 | 107 | config.defaults = {}; 108 | 109 | $.removeCookie = function (key, options) { 110 | if ($.cookie(key) === undefined) { 111 | return false; 112 | } 113 | 114 | // Must not alter options, thus extending a fresh object... 115 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 116 | return !$.cookie(key); 117 | }; 118 | 119 | })); 120 | -------------------------------------------------------------------------------- /src/main/resources/js/similarityConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 相似度度量方法配置页面JS 3 | */ 4 | 5 | similarityCount = 0; 6 | userSimilarityCount = 0; 7 | itemSimilarityCount = 0; 8 | 9 | $(function(){ 10 | 11 | }); 12 | 13 | /** 14 | * 添加用户间相似度度量机制 15 | * */ 16 | function addUserSimilarity(){ 17 | var userSimilarityDiv = $("#userSimilarity"); 18 | var newUserSimilarityDiv = $("
"); 19 | newUserSimilarityDiv.html(userSimilarityDiv.html()); 20 | $("#content").append(newUserSimilarityDiv); 21 | } 22 | 23 | /** 24 | * 添加项目间相似度度量机制 25 | * */ 26 | function addItemSimilarity(){ 27 | var itemSimilarityDiv = $("#itemSimilarity"); 28 | var newItemSimilarityDiv = $("
"); 29 | newItemSimilarityDiv.html(itemSimilarityDiv.html()); 30 | $("#content").append(newItemSimilarityDiv); 31 | } 32 | 33 | /** 34 | * 检查相似度度量方法的个数 35 | * */ 36 | function validateSimilarityCount(){ 37 | var flag = true; 38 | if($.cookie("preferenceDataCount") != similarityCount){ 39 | alert("用户偏好数据源的个数与相似度度量方法的个数不相等,无法一一匹配,因此无法创建协同过滤推荐器,请刷新页面并重新配置!"); 40 | return false; 41 | } 42 | } 43 | 44 | /** 45 | * 创建相似度度量方法的列表 46 | * */ 47 | function buildSimilarityList(){ 48 | var similarityList = new Array(); 49 | $("[title='similarity']").each(function(index){ 50 | //跳过前2个隐藏的div 51 | if($(this).attr("id") == "itemSimilarity" || $(this).attr("id") == "userSimilarity"){ 52 | return true; 53 | } 54 | similarityCount++; 55 | var theSimilarity = new Object(); 56 | var similarityDiv = $(this); 57 | if(similarityDiv.find("form[name='userSimilarityForm']").length > 0){ 58 | theSimilarity.similarity = "userSimilarity"; 59 | theSimilarity.similarityType = similarityDiv.find("select[name='userSimilarity']").val(); 60 | similarityList[index-2] = theSimilarity; 61 | userSimilarityCount++; 62 | } 63 | if(similarityDiv.find("form[name='itemSimilarityForm']").length > 0){ 64 | theSimilarity.similarity = "itemSimilarity"; 65 | theSimilarity.similarityType = similarityDiv.find("select[name='itemSimilarity']").val(); 66 | similarityList[index-2] = theSimilarity; 67 | itemSimilarityCount++; 68 | } 69 | }); 70 | return similarityList; 71 | } 72 | 73 | /** 74 | * 点击“下一步”按钮,完成相似度度量方法的配置 75 | * */ 76 | function finishSimilarityConfig(){ 77 | 78 | var similarityList = buildSimilarityList(); 79 | 80 | if(validateSimilarityCount() == false){ 81 | return false; 82 | } 83 | 84 | $.cookie("similarityList", JSON.stringify(similarityList)); 85 | $.cookie("similarityCount", similarityCount); 86 | $.cookie("userSimilarityCount", userSimilarityCount); 87 | $.cookie("itemSimilarityCount", itemSimilarityCount); 88 | console.log("similarityList:" + JSON.stringify(similarityList)); 89 | 90 | window.location.href = "/sr/config/algorithmconfig"; 91 | } 92 | -------------------------------------------------------------------------------- /src/main/resources/js/startConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 配置开始页面JS 3 | */ 4 | 5 | $(function(){ 6 | 7 | }); 8 | 9 | /** 10 | * 点击“下一步”按钮,完成推荐系统名称的设置 11 | * */ 12 | function startConfig(){ 13 | var recommenderName = $("input[name='recommenderName']").val(); 14 | if(recommenderName.trim() == ""){ 15 | alert("请填写推荐系统名称!"); 16 | return false; 17 | } 18 | $.cookie("recommenderName", recommenderName); 19 | window.location.href = "/sr/config/dataconfig"; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | ### set log levels ### 2 | log4j.rootLogger = debug, stdout 3 | 4 | ### 输出到控制台 ### 5 | log4j.appender.stdout = org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target = System.out 7 | log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 8 | #log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n 9 | -------------------------------------------------------------------------------- /src/main/resources/recommender-demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | content 5 | mysql 6 | 127.0.0.1 7 | root 8 | root 9 | 10 | ucareer 11 | user 12 | occupation 13 | 14 | major 15 | occupation_name 16 | MUST 17 | 18 | 19 | address 20 | address 21 | SHOULD 22 | 23 | 24 | 25 | 26 | preference 27 | file 28 | /usr/data/myPreference.csv 29 | 30 | 31 | 32 | euclideanDistanceSimilarity 33 | 34 | 35 | 36 | weighted 37 | 38 | content-based 39 | 0.5 40 | 41 | 42 | user-based-cf 43 | 1.2 44 | threshold 45 | 0.75 46 | 47 | 48 | 49 | 50 | true 51 | false 52 | false 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/resources/recommender.xsd: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 94 | 96 | 97 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/main/resources/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | BaseStation 7 | 8 | 9 | 10 | contextConfigLocation 11 | 12 | classpath:applicationContext.xml 13 | 14 | 15 | 16 | 17 | 18 | CharacterEncodingFilter 19 | org.springframework.web.filter.CharacterEncodingFilter 20 | 21 | encoding 22 | UTF-8 23 | 24 | 25 | forceEncoding 26 | true 27 | 28 | 29 | 30 | CharacterEncodingFilter 31 | * 32 | 33 | 34 | 35 | 36 | org.springframework.web.context.ContextLoaderListener 37 | 38 | 39 | 40 | 41 | dispatcherServlet 42 | org.springframework.web.servlet.DispatcherServlet 43 | 48 | 49 | contextConfigLocation 50 | classpath:dispatcherServlet-servlet.xml 51 | 52 | 1 53 | 54 | 55 | dispatcherServlet 56 | /* 57 | 58 | 59 | index.jsp 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/algorithm/ContentBasedRecommenderTest.java: -------------------------------------------------------------------------------- 1 | package test.algorithm.algorithm; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.lucene.analysis.Analyzer; 7 | import org.apache.lucene.analysis.standard.StandardAnalyzer; 8 | import org.apache.lucene.index.Term; 9 | import org.apache.lucene.queryparser.classic.ParseException; 10 | import org.apache.lucene.queryparser.classic.QueryParser; 11 | import org.apache.lucene.search.BooleanClause.Occur; 12 | import org.apache.lucene.search.BooleanQuery; 13 | import org.apache.lucene.search.Filter; 14 | import org.apache.lucene.search.Query; 15 | import org.apache.lucene.search.QueryWrapperFilter; 16 | import org.apache.lucene.search.TermQuery; 17 | import org.apache.lucene.util.Version; 18 | import org.junit.Ignore; 19 | import org.junit.Test; 20 | 21 | import edu.recm.algorithm.algorithm.ContentBasedRecommender; 22 | import edu.recm.algorithm.data.MySQLContentData; 23 | import edu.recm.algorithm.data.QueryUnit; 24 | 25 | /** 26 | * 测试基于内容的推荐器 27 | * @author niuzhixiang 28 | * 29 | */ 30 | public class ContentBasedRecommenderTest { 31 | 32 | /** 33 | * 测试基于内容的推荐 34 | * @throws ParseException 35 | */ 36 | @Test 37 | @Ignore 38 | public void testDorecommend() throws ParseException { 39 | long preTime = System.currentTimeMillis(); 40 | 41 | List queries = new ArrayList(); 42 | queries.add(new QueryUnit("DEGREE", "DEGREE", Occur.MUST)); 43 | queries.add(new QueryUnit("HOMEPLACE", "AREA", Occur.MUST)); 44 | 45 | MySQLContentData contentData = new MySQLContentData("localhost", "server", "server", "easyrecdemo", "student", "job", queries); 46 | 47 | ContentBasedRecommender recommender = new ContentBasedRecommender("job-recommender", contentData, null); 48 | try { 49 | recommender.doRecommend(1, 10); 50 | } catch (Exception e) { 51 | // TODO Auto-generated catch block 52 | e.printStackTrace(); 53 | } 54 | 55 | long afterTime = System.currentTimeMillis(); 56 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/algorithm/ItemBasedCFRecommenderTest.java: -------------------------------------------------------------------------------- 1 | package test.algorithm.algorithm; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import edu.recm.algorithm.algorithm.ItemBasedCFRecommender; 7 | import edu.recm.algorithm.algorithm.UserBasedCFRecommender; 8 | import edu.recm.algorithm.data.FilePreferenceData; 9 | import edu.recm.algorithm.data.MySQLPreferenceData; 10 | 11 | /** 12 | * 测试基于项目的协同过滤推荐器 13 | * @author niuzhixiang 14 | * 15 | */ 16 | public class ItemBasedCFRecommenderTest { 17 | 18 | /** 19 | * 测试输入数据源为MySQL、有偏好值的情况 20 | * @throws Exception 21 | */ 22 | @Test 23 | @Ignore 24 | public void testdoRecommendMySQLWithPrefValue() throws Exception { 25 | long preTime = System.currentTimeMillis(); 26 | 27 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 28 | mySQLPreferenceData.createDataModelWithPrefValue("localhost", "server", "server", "easyrecdemo", "applylog_pref", "STUDENTID", "JOBID", "PREFERENCE", "APPLYDATE"); 29 | ItemBasedCFRecommender recommender = new ItemBasedCFRecommender("job-recommender", mySQLPreferenceData, "pearsonCorrelationSimilarity"); 30 | recommender.doRecommend(21, 10); 31 | 32 | long afterTime = System.currentTimeMillis(); 33 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 34 | } 35 | 36 | /** 37 | * 测试输入数据源为MySQL、无偏好值的情况 38 | * @throws Exception 39 | */ 40 | @Test 41 | @Ignore 42 | public void testdoRecommendMySQLWithoutPrefValue() throws Exception { 43 | long preTime = System.currentTimeMillis(); 44 | 45 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 46 | mySQLPreferenceData.createDataModelWithoutPrefValue("localhost", "server", "server", "easyrecdemo", "applylog", "STUDENTID", "JOBID", "APPLYDATE"); 47 | ItemBasedCFRecommender recommender = new ItemBasedCFRecommender("job-recommender", mySQLPreferenceData, "tanimotoCoefficientSimilarity"); 48 | recommender.doRecommend(21, 10); 49 | 50 | long afterTime = System.currentTimeMillis(); 51 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 52 | } 53 | 54 | /** 55 | * 测试输入数据源为文件、有偏好值的情况 56 | * @throws Exception 57 | */ 58 | @Test 59 | @Ignore 60 | public void testdoRecommendFileWithPrefValue() throws Exception { 61 | long preTime = System.currentTimeMillis(); 62 | 63 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog_pref.csv"); 64 | ItemBasedCFRecommender recommender = new ItemBasedCFRecommender("job-recommender", filePreferenceData, "pearsonCorrelationSimilarity"); 65 | recommender.doRecommend(21, 10); 66 | 67 | long afterTime = System.currentTimeMillis(); 68 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 69 | } 70 | 71 | /** 72 | * 测试输入数据源为文件、无偏好值的情况 73 | * @throws Exception 74 | */ 75 | @Test 76 | @Ignore 77 | public void testdoRecommendFileWithoutPrefValue() throws Exception { 78 | long preTime = System.currentTimeMillis(); 79 | 80 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog.csv"); 81 | ItemBasedCFRecommender recommender = new ItemBasedCFRecommender("job-recommender", filePreferenceData, "logLikelihoodSimilarity"); 82 | recommender.doRecommend(21, 10); 83 | 84 | long afterTime = System.currentTimeMillis(); 85 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/algorithm/UserBasedCFRecommenderTest.java: -------------------------------------------------------------------------------- 1 | package test.algorithm.algorithm; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 6 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 7 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 8 | import org.apache.mahout.cf.taste.model.DataModel; 9 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 10 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 11 | import org.apache.mahout.cf.taste.recommender.Recommender; 12 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 13 | import org.junit.Ignore; 14 | import org.junit.Test; 15 | 16 | import edu.recm.algorithm.algorithm.UserBasedCFRecommender; 17 | import edu.recm.algorithm.data.FilePreferenceData; 18 | import edu.recm.algorithm.data.MySQLPreferenceData; 19 | 20 | /** 21 | * 测试基于用户的协同过滤推荐器 22 | * @author niuzhixiang 23 | * 24 | */ 25 | public class UserBasedCFRecommenderTest { 26 | 27 | /** 28 | * 测试输入数据源为MySQL、有偏好值的情况 29 | * @throws Exception 30 | */ 31 | @Test 32 | @Ignore 33 | public void testdoRecommendMySQLWithPrefValue() throws Exception { 34 | long preTime = System.currentTimeMillis(); 35 | 36 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 37 | mySQLPreferenceData.createDataModelWithPrefValue("localhost", "server", "server", "easyrecdemo", "applylog_pref", "STUDENTID", "JOBID", "PREFERENCE", "APPLYDATE"); 38 | UserBasedCFRecommender recommender = new UserBasedCFRecommender("job-recommender", mySQLPreferenceData, "euclideanDistanceSimilarity", 10, null); 39 | recommender.doRecommend(21, 10); 40 | 41 | long afterTime = System.currentTimeMillis(); 42 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 43 | } 44 | 45 | /** 46 | * 测试输入数据源为MySQL、无偏好值的情况 47 | * @throws Exception 48 | */ 49 | @Test 50 | @Ignore 51 | public void testdoRecommendMySQLWithoutPrefValue() throws Exception { 52 | long preTime = System.currentTimeMillis(); 53 | 54 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 55 | mySQLPreferenceData.createDataModelWithoutPrefValue("localhost", "server", "server", "easyrecdemo", "applylog", "STUDENTID", "JOBID", "APPLYDATE"); 56 | UserBasedCFRecommender recommender = new UserBasedCFRecommender("job-recommender", mySQLPreferenceData, "tanimotoCoefficientSimilarity", 100, null); 57 | recommender.doRecommend(21, 10); 58 | 59 | long afterTime = System.currentTimeMillis(); 60 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 61 | } 62 | 63 | /** 64 | * 测试输入数据源为文件、有偏好值的情况 65 | * @throws Exception 66 | */ 67 | @Test 68 | @Ignore 69 | public void testdoRecommendFileWithPrefValue() throws Exception { 70 | long preTime = System.currentTimeMillis(); 71 | 72 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog_pref.csv"); 73 | UserBasedCFRecommender recommender = new UserBasedCFRecommender("job-recommender", filePreferenceData, "pearsonCorrelationSimilarity", 10, null); 74 | recommender.doRecommend(21, 10); 75 | 76 | long afterTime = System.currentTimeMillis(); 77 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 78 | } 79 | 80 | /** 81 | * 测试输入数据源为文件、无偏好值的情况 82 | * @throws Exception 83 | */ 84 | @Test 85 | @Ignore 86 | public void testdoRecommendFileWithoutPrefValue() throws Exception { 87 | long preTime = System.currentTimeMillis(); 88 | 89 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog.csv"); 90 | UserBasedCFRecommender recommender = new UserBasedCFRecommender("job-recommender", filePreferenceData, "tanimotoCoefficientSimilarity", null, 0.14); 91 | recommender.doRecommend(21, 10); 92 | 93 | long afterTime = System.currentTimeMillis(); 94 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/algorithm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 测试推荐算法处理模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package test.algorithm.algorithm; -------------------------------------------------------------------------------- /src/test/java/test/algorithm/data/FilePreferenceDataTest.java: -------------------------------------------------------------------------------- 1 | package test.algorithm.data; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.mahout.cf.taste.common.TasteException; 6 | import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel; 7 | import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 8 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 9 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 10 | import org.apache.mahout.cf.taste.impl.similarity.TanimotoCoefficientSimilarity; 11 | import org.apache.mahout.cf.taste.model.DataModel; 12 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 13 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 14 | import org.apache.mahout.cf.taste.recommender.Recommender; 15 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 16 | import org.junit.Ignore; 17 | import org.junit.Test; 18 | 19 | import edu.recm.algorithm.data.FilePreferenceData; 20 | 21 | public class FilePreferenceDataTest { 22 | 23 | /** 24 | * 测试有偏好值的情况 25 | * @throws Exception 26 | */ 27 | @Test 28 | @Ignore 29 | public void testAccessFilePreferenceWithPrefValue() throws Exception { 30 | long preTime = System.currentTimeMillis(); 31 | 32 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog_pref.csv"); 33 | DataModel dataModel = filePreferenceData.getDataModel(); 34 | UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel); 35 | UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, similarity, dataModel); 36 | Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity); 37 | List recommendedItems = recommender.recommend(21, 10); 38 | for (RecommendedItem recommendedItem : recommendedItems) { 39 | System.out.println(recommendedItem); 40 | } 41 | 42 | long afterTime = System.currentTimeMillis(); 43 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 44 | } 45 | 46 | @Test 47 | @Ignore 48 | @SuppressWarnings("deprecation") 49 | public void testAccessFilePreferenceWithoutPrefValue() throws Exception { 50 | long preTime = System.currentTimeMillis(); 51 | 52 | FilePreferenceData filePreferenceData = new FilePreferenceData("D:/preferenceData/applylog.csv"); 53 | DataModel dataModel = new GenericBooleanPrefDataModel(filePreferenceData.getDataModel()); 54 | UserSimilarity similarity = new TanimotoCoefficientSimilarity(dataModel); 55 | UserNeighborhood neighborhood = new NearestNUserNeighborhood(100, similarity, dataModel); 56 | Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity); 57 | List recommendedItems = recommender.recommend(21, 10); 58 | for (RecommendedItem recommendedItem : recommendedItems) { 59 | System.out.println(recommendedItem); 60 | } 61 | 62 | long afterTime = System.currentTimeMillis(); 63 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/data/MySQLPreferenceDataTest.java: -------------------------------------------------------------------------------- 1 | package test.algorithm.data; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.mahout.cf.taste.common.TasteException; 6 | import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 7 | import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 8 | import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 9 | import org.apache.mahout.cf.taste.impl.similarity.TanimotoCoefficientSimilarity; 10 | import org.apache.mahout.cf.taste.model.DataModel; 11 | import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 12 | import org.apache.mahout.cf.taste.recommender.RecommendedItem; 13 | import org.apache.mahout.cf.taste.recommender.Recommender; 14 | import org.apache.mahout.cf.taste.similarity.UserSimilarity; 15 | import org.junit.Ignore; 16 | import org.junit.Test; 17 | import org.junit.runner.RunWith; 18 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 19 | 20 | import edu.recm.algorithm.data.MySQLPreferenceData; 21 | 22 | public class MySQLPreferenceDataTest { 23 | 24 | /** 25 | * 测试有偏好值的情况 26 | * @throws Exception 27 | */ 28 | @Test 29 | @Ignore 30 | public void testAccessMySQLPreferenceWithPrefValue() throws Exception{ 31 | long preTime = System.currentTimeMillis(); 32 | 33 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 34 | mySQLPreferenceData.createDataModelWithPrefValue("localhost", "server", "server", "easyrecdemo", "applylog_pref", "STUDENTID", "JOBID", "PREFERENCE", "APPLYDATE"); 35 | DataModel dataModel = mySQLPreferenceData.getDataModel(); 36 | UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel); 37 | UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, similarity, dataModel); 38 | Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity); 39 | List recommendedItems = recommender.recommend(21, 10); 40 | for (RecommendedItem recommendedItem : recommendedItems) { 41 | System.out.println(recommendedItem); 42 | } 43 | 44 | long afterTime = System.currentTimeMillis(); 45 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 46 | } 47 | 48 | /** 49 | * 测试无偏好值的情况 50 | * @throws Exception 51 | */ 52 | @Test 53 | @Ignore 54 | public void testAccessMySQLPreferenceWithoutPrefValue() throws Exception{ 55 | long preTime = System.currentTimeMillis(); 56 | 57 | MySQLPreferenceData mySQLPreferenceData = new MySQLPreferenceData(); 58 | mySQLPreferenceData.createDataModelWithoutPrefValue("localhost", "server", "server", "easyrecdemo", "applylog", "STUDENTID", "JOBID", null); 59 | DataModel dataModel = mySQLPreferenceData.getDataModel(); 60 | UserSimilarity similarity = new TanimotoCoefficientSimilarity(dataModel); 61 | UserNeighborhood neighborhood = new NearestNUserNeighborhood(100, similarity, dataModel); 62 | Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity); 63 | List recommendedItems = recommender.recommend(21, 10); 64 | for (RecommendedItem recommendedItem : recommendedItems) { 65 | System.out.println(recommendedItem); 66 | } 67 | 68 | long afterTime = System.currentTimeMillis(); 69 | System.out.println("last:" + (afterTime - preTime)/1000 + "s"); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/test/algorithm/data/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 测试数据抽象模块 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package test.algorithm.data; -------------------------------------------------------------------------------- /src/test/java/test/config/web/WebParamAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package test.config.web; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import edu.recm.config.model.IntegralConfigModel; 7 | import edu.recm.config.web.WebParamAnalyzer; 8 | import edu.recm.config.xml.XMLCreator; 9 | 10 | public class WebParamAnalyzerTest { 11 | 12 | /** 13 | * 测试“解析前端配置页面填写的参数并建立相应的推荐系统参数配置模型”的功能 14 | * @throws Exception 15 | */ 16 | @Test 17 | @Ignore 18 | public void testBuildConfigModel() throws Exception { 19 | String inputString = "{'recommenderName':'c','dataList':[{'dataType':'content','sourceType':'mysql','data':{'dbServerName':'c','dbUser':'c','dbPassword':'c','dbDatabaseName':'c','userTable':'c','itemTable':'c','queryList':[{'userColumn':'c','itemColumn':'c','occur':'MUST_NOT'},{'userColumn':'c','itemColumn':'c','occur':'SHOULD'}]}},{'dataType':'preference','sourceType':'mysql','data':{'dbServerName':'c','dbUser':'c','dbPassword':'c','dbDatabaseName':'c','preferenceTable':'c','userIDColumn':'c','itemIDColumn':'c','preferenceColumn':'c','timestampColumn':'c'}},{'dataType':'preference','sourceType':'file','data':{'filePath':'C:/fakepath/applylog.csv'}}],'similarityList':[{'similarity':'userSimilarity','similarityType':'euclideanDistanceSimilarity'},{'similarity':'itemSimilarity','similarityType':'logLikelihoodSimilarity'}],'algorithm':{'algorithmType':'weighted','list':[{'name':'contentBased','weight':'2'},{'name':'userBasedCF','weight':'3','userNeighborhoodType':'nearestN','nearestN':'2'},{'name':'itemBasedCF','weight':'4'}]},'evaluator':{'deviation':'false','precision':'false','recall':'false','runningTime':'false'}}"; 20 | String inputString2 = "{'recommenderName':'c-single','dataList':[{'dataType':'content','sourceType':'mysql','data':{'dbServerName':'c','dbUser':'c','dbPassword':'c','dbDatabaseName':'c','userTable':'c','itemTable':'c','queryList':[{'userColumn':'c','itemColumn':'c','occur':'MUST'},{'userColumn':'c','itemColumn':'c','occur':'MUST_NOT'}]}}],'similarityList':[],'algorithm':{'algorithmType':'single','list':[{'name':'contentBased'}]},'evaluator':{'deviation':'false','precision':'false','recall':'false','runningTime':'false'}}"; 21 | 22 | String dataListString = "[{'dataType':'content','sourceType':'mysql','data':{'dbServerName':'c','dbUser':'c','dbPassword':'c','dbDatabaseName':'c','userTable':'c','itemTable':'c','queryList':[{'userColumn':'c','itemColumn':'c','occur':'MUST_NOT'},{'userColumn':'c','itemColumn':'c','occur':'SHOULD'}]}},{'dataType':'preference','sourceType':'mysql','data':{'dbServerName':'c','dbUser':'c','dbPassword':'c','dbDatabaseName':'c','preferenceTable':'c','userIDColumn':'c','itemIDColumn':'c','preferenceColumn':'c','timestampColumn':'c'}},{'dataType':'preference','sourceType':'file','data':{'filePath':'C:\fakepathapplylog.csv'}}]"; 23 | String similarityString = "[{'similarity':'userSimilarity','similarityType':'euclideanDistanceSimilarity'},{'similarity':'itemSimilarity','similarityType':'logLikelihoodSimilarity'}]"; 24 | String algorithmString = "{'algorithmType':'weighted','list':[{'name':'contentBased','weight':'2'},{'name':'userBasedCF','weight':'3','userNeighborhoodType':'nearestN','nearestN':'2'},{'name':'itemBasedCF','weight':'4'}]}"; 25 | String evaluatorString = "{'deviation':'false','precision':'false','recall':'false','runningTime':'false'}"; 26 | 27 | WebParamAnalyzer webParamAnalyzer = new WebParamAnalyzer(); 28 | IntegralConfigModel config = webParamAnalyzer.buildConfigModel(inputString); 29 | 30 | XMLCreator xmlCreator = new XMLCreator(); 31 | xmlCreator.createXMLConfigFile(config); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/test/config/web/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package test.config.web; -------------------------------------------------------------------------------- /src/test/java/test/config/xml/XMLAnalyzerTest.java: -------------------------------------------------------------------------------- 1 | package test.config.xml; 2 | 3 | import org.dom4j.DocumentException; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import edu.recm.config.model.IntegralConfigModel; 8 | import edu.recm.config.xml.XMLAnalyzer; 9 | import edu.recm.config.xml.XMLCreator; 10 | 11 | public class XMLAnalyzerTest { 12 | 13 | /** 14 | * 测试XML配置文件的解析功能 15 | * @throws Exception 16 | */ 17 | @Test 18 | @Ignore 19 | public void testAnalyzeXMLConfigFile() throws Exception { 20 | XMLAnalyzer xmlAnalyzer = new XMLAnalyzer(); 21 | IntegralConfigModel configModel = xmlAnalyzer.analyzeXMLConfigFile("myrecommender"); 22 | 23 | configModel.setRecommenderName(configModel.getRecommenderName() + "-copy"); 24 | XMLCreator xmlCreator = new XMLCreator(); 25 | xmlCreator.createXMLConfigFile(configModel); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/test/config/xml/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package test.config.xml; -------------------------------------------------------------------------------- /src/test/java/test/service/RecommenderBuilderTest.java: -------------------------------------------------------------------------------- 1 | package test.service; 2 | 3 | import org.dom4j.DocumentException; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import edu.recm.algorithm.algorithm.MyRecommender; 8 | import edu.recm.config.xml.XMLAnalyzer; 9 | import edu.recm.service.common.RecommenderBuilder; 10 | 11 | public class RecommenderBuilderTest { 12 | 13 | /** 14 | * 测试推荐器的创建功能 15 | */ 16 | @Test 17 | @Ignore 18 | public void testBuildRecommender() { 19 | RecommenderBuilder recommenderBuilder = new RecommenderBuilder(); 20 | try { 21 | MyRecommender recommender = recommenderBuilder.buildRecommender(new XMLAnalyzer().analyzeXMLConfigFile("myrecommender-weighted")); 22 | recommender.doRecommend(1, 10); 23 | } catch (DocumentException e) { 24 | // TODO Auto-generated catch block 25 | e.printStackTrace(); 26 | } catch (Exception e) { 27 | // TODO Auto-generated catch block 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/test/service/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author niuzhixiang 6 | * 7 | */ 8 | package test.service; --------------------------------------------------------------------------------