The Duine Framework is flexible and extensible. It can be used in many application domains, it can be extended with new prediction techniques, profile models and feedback processors, and the predictor tree itself is entirely configurable. Besides you can tweak parameters of existing predictors, and modify the learning-parameters of feedback processors.
Furthermore the persistency implementation can be replaced by other implementations. The default implementation that comes with the Duine Framework uses Hibernate . You can hook caching into various parts of the framework for performance improvement. The default caching implementation (JCS ) that comes with the framework can be replaced by another implementation if required.
Drawback of this "configuration heaven" is that configuring the system might look rather complex and challenging at a first glance. We have partly solved this by providing Duine with a default configuration that works out of the box. Furthermore we have a validation framework that can help you to determine the quality of the predictions that your configured system achieves.
In this section we will describe the out of the box configuration. The relevant configuration files are listed below. They are available in the src/main/resources directory of the demo application sources. If you are using the duine-movielens-*-binary distribution you will find the configuration files that are used at runtime in the classes directory. We use the Spring Framework to load and wire the configuration.
spring-recommender.xml | High level configuration of the recommender |
spring-predictors.xml | Configuration of the predictor tree |
spring-profiles.xml | Configuration of the profile models, the adapters and the feedback processors |
spring-datasources.properties | Configuration of the datasources |
The predictor tree was already described in the concepts section . The predictor tree image shown there is a graphical representation of the spring-predictors.xml configuration file. For a further understanding of configuration of the predictor tree refer to the file spring-predictors.xml .
The file spring-profiles.xml contains the configuration of the profile models and feedback processors. The file spring-recommender.xml shows how feedback processors are registered with the recommender. A snippet of spring-recommender.xml is shown below.
<!-- see spring-recommender.xml in demo application --> <bean id="recommender" class="org.duineframework.recommender.core.Recommender"> <description>This is the DuineRecommender implementation.</description> <property name="predictionEngine" ref="predictionEngine"/> <property name="feedbackProcessors"> <set> <ref bean="ratingModelFeedbackProcessor"/> <ref bean="mainGenreInterestModel.LMSfeedbackProcessor"/> <ref bean="mainGenreInterestModel.termFeedbackProcessor"/> <ref bean="subGenreInterestModel.LMSfeedbackProcessor"/> <ref bean="subGenreInterestModel.termFeedbackProcessor"/> <ref bean="infoFilterInterestModel.LMSfeedbackProcessor"/> </set> </property> ..... </bean>
You can find configuration examples for profile models and feedback processors in the documentation in Getting Started (2) and Concept Coherence .
Duine 4.0 offers various hooks for performance improvement. Some parts of the code are critical for performance: performance hotspots. The code design enables the declarative wiring of a cache into these hotspots. The cache is highly tweakable and can be adapted to your application and deployment needs. Duine comes with the open source java caching implementation JCS , but it also allows other (java) caching products.
Duine 4.0 defines an interface ICache, to put and get java objects based on a key, similar to a java Map.
public Object get(Object key); public void put(Object key, Object value) throws DuineException; public void invalidateObject(Object key) throws DuineException;
It also provides an implementation of this interface for the JCS open source java cache. Below we will show how this caching support is used to realize improvements at performance hotspots. The configuration of JCS is entirely out of scope of Duine, it is fully determined by the JCS product. JCS supports in-memory caching, disk caching, remote caching, has configurable invalidation strategies etc. For more information consult the JCS documentation . The configuration file is cache.ccf .
The Duine toolkit needs a lot of access to the ratings of users. Past experience has shown that caching is very helpful. The Rating Model can be hooked to a dedicated cache in which frequently used complex java objects are cached, so the database access is reduced and the complex java objects do not have to be constructed over and over again. The cache implementation also manages invalidation of cached objects. Below a part of the configuration of the Rating Model is shown. It shows how the cache is wired.
<!-- see spring-profiles.xml in demo application --> <bean id="ratingModel" class="org.duineframework.recommender.profile.rating.RatingModel"> <property name="modelId" value="org.duineframework.recommender.profile.rating.ratingModel"/> <property name="ratingModelDAO" ref="ratingModelDAO"/> <property name="ratingCache" ref="ratingCache"/> </bean> <bean id="ratingCache" class="org.duineframework.recommender.profile.rating.cache.RatingCache"> <description>This is the cache for ratings, it serves as an adapter between the rating model specific types and caching logic and the simple ICache interface.</description> <property name="cache" ref="jcsRatingCache"/> </bean> <bean id="jcsRatingCache" class="org.duineframework.support.jcs.JCSCache"> <description>This is the JCS cache implementation. It operates on a separate cache region for ratings. JCS offers configuration options per cache region. </description> <property name="cacheRegion" value="ratingCache"/> </bean>
Caching the Interest model appears to be very effective as well. The caching mechanism is similar to the rating cache. Invalidation of cached interests is managed automatically. The cache is wired into interest models as shown below. By applying a different cacheRegion for each kind of interest model it is possible to tweak the cache separately for each interest model.
<!-- see spring-profiles.xml in demo application --> <bean id="mainGenreInterestCache" class="org.duineframework.recommender.profile.interest.cache.InterestCache"> <description>This is the cache for interests, it serves as an adapter between the interest model specific types and caching logic and the simple ICache interface.</description> <property name="cache"> <bean class="org.duineframework.support.jcs.JCSCache"> <property name="cacheRegion" value="mainGenre"/> </bean> </property> </bean> <bean id="subGenreInterestCache" class="org.duineframework.recommender.profile.interest.cache.InterestCache"> <description>This is the cache for interests, it serves as an adapter between the interest model specific types and caching logic and the simple ICache interface.</description> <property name="cache"> <bean class="org.duineframework.support.jcs.JCSCache"> <property name="cacheRegion" value="subGenre"/> </bean> </property> </bean> <bean id="infoFilterInterestCache" class="org.duineframework.recommender.profile.interest.cache.InterestCache"> <description>This is the cache for interests, it serves as an adapter between the interest model specific types and caching logic and the simple ICache interface.</description> <property name="cache"> <bean class="org.duineframework.support.jcs.JCSCache"> <property name="cacheRegion" value="infoFilter"/> </bean> </property> </bean>
The Duine Framework includes validation tools . These tools need a data set consisting of ratings and other feedback by users. To collect these data a logging service can be wired into the recommender. This logging service creates a database entry every time a rating is given or other feedback is provided. The validation tools can replay this log to measure the accuracy of a recommender. The output of this validation, in particular the accuracy data, can be used to optimize the configuration towards the logged dataset if necessary.
Below is shown how the logging service can be attached to the recommender.
<!-- see spring-recommender.xml in demo application --> <bean id="recommender" class="org.duineframework.recommender.core.Recommender"> <description>This is the DuineRecommender implementation.</description> <property name="predictionEngine" ref="predictionEngine"/> ..... <property name="loggingService" ref="recommender.loggingService"> <description>You can switch of logging by uncommenting this property. WARNING: If you switch off logging you will not be able to validate the prediction results anymore.</description> </property> </bean> <bean id="recommender.loggingService" class="org.duineframework.recommender.validation.LoggingService"> <property name="loggingServiceDAO" ref="recommender.loggingServiceDAO"/> </bean>