Toggle navigation
Toggle navigation
This project
Loading...
Sign in
grogv3
/
grog-cubi
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jean-Francois Leveque
2017-04-13 11:55:12 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
3781ca33a42d0cc698b24cc239ae8ce3e613fd81
3781ca33
1 parent
d367817e
Preview release processing
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
279 additions
and
20 deletions
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/CosineRecommender.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/FunkSVDRecommender.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/PearsonRecommender.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingApplication.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingExpert.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingRecommendations.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingRunner.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/RecommendationElement.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/Recommender.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/RecommenderFactory.java
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/SlopeOneRecommender.java
grog-recommendation/grog-recommendation-process/src/main/resources/logback.xml
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/CosineRecommender.java
View file @
3781ca3
...
...
@@ -37,8 +37,7 @@ public class CosineRecommender implements Recommender {
ItemRecommender
irec
;
@Override
public
void
Recommender
(
String
filePath
)
{
public
CosineRecommender
(
String
filePath
)
{
config
=
new
LenskitConfiguration
();
config
.
bind
(
ItemScorer
.
class
).
to
(
ItemItemScorer
.
class
);
...
...
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/FunkSVDRecommender.java
View file @
3781ca3
...
...
@@ -33,8 +33,7 @@ public class FunkSVDRecommender implements Recommender {
ItemRecommender
irec
;
@Override
public
void
Recommender
(
String
filePath
)
{
public
FunkSVDRecommender
(
String
filePath
)
{
config
=
new
LenskitConfiguration
();
config
.
bind
(
ItemScorer
.
class
).
to
(
FunkSVDItemScorer
.
class
);
...
...
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/PearsonRecommender.java
View file @
3781ca3
...
...
@@ -37,8 +37,7 @@ public class PearsonRecommender implements Recommender {
ItemRecommender
irec
;
@Override
public
void
Recommender
(
String
filePath
)
{
public
PearsonRecommender
(
String
filePath
)
{
config
=
new
LenskitConfiguration
();
config
.
bind
(
ItemScorer
.
class
).
to
(
ItemItemScorer
.
class
);
...
...
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingApplication.java
View file @
3781ca3
...
...
@@ -10,18 +10,8 @@ import org.springframework.context.annotation.Bean;
@SpringBootApplication
public
class
ProcessingApplication
{
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
ProcessingApplication
.
class
,
args
);
}
@Bean
public
CommandLineRunner
process
()
{
return
(
args
)
->
this
.
run
();
}
public
void
run
()
{
}
}
...
...
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingExpert.java
0 → 100644
View file @
3781ca3
package
org
.
legrog
.
recommendation
.
process
;
import
org.grouplens.lenskit.scored.ScoredId
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.List
;
import
java.util.Set
;
public
class
ProcessingExpert
{
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
Recommender
recommender
;
int
topSize
;
public
ProcessingExpert
(
Recommender
recommender
,
int
topSize
)
{
this
.
recommender
=
recommender
;
this
.
topSize
=
topSize
;
}
public
ProcessingRecommendations
getRecommendations
(
Set
<
Long
>
userIds
)
{
ProcessingRecommendations
processingRecommendations
=
new
ProcessingRecommendations
();
List
<
ScoredId
>
recommendations
;
for
(
Long
userId
:
userIds
)
{
recommendations
=
recommender
.
recommend
(
userId
,
topSize
);
for
(
ScoredId
recommendation
:
recommendations
)
{
processingRecommendations
.
addRecommentation
(
new
RecommendationElement
(
userId
,
recommendation
.
getId
()));
logger
.
trace
(
"Recommending {} for {}"
,
recommendation
.
getId
(),
userId
);
}
}
return
processingRecommendations
;
}
}
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingRecommendations.java
0 → 100644
View file @
3781ca3
package
org
.
legrog
.
recommendation
.
process
;
import
java.util.HashSet
;
import
java.util.Set
;
public
class
ProcessingRecommendations
{
Set
<
RecommendationElement
>
recommendations
;
public
ProcessingRecommendations
()
{
recommendations
=
new
HashSet
<>();
}
public
void
addRecommentation
(
RecommendationElement
recommendationElement
)
{
recommendations
.
add
(
recommendationElement
);
}
public
Set
<
RecommendationElement
>
getRecommendations
()
{
return
recommendations
;
}
}
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/ProcessingRunner.java
0 → 100644
View file @
3781ca3
package
org
.
legrog
.
recommendation
.
process
;
import
org.apache.commons.csv.CSVFormat
;
import
org.apache.commons.csv.CSVPrinter
;
import
org.apache.commons.csv.CSVRecord
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.ApplicationArguments
;
import
org.springframework.boot.ApplicationRunner
;
import
org.springframework.stereotype.Component
;
import
java.io.*
;
import
java.util.HashSet
;
import
java.util.Properties
;
import
java.util.Set
;
@Component
public
class
ProcessingRunner
implements
ApplicationRunner
{
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
@Value
(
"${parameters.filename}"
)
private
String
parametersFilename
;
@Value
(
"${data.dir}"
)
private
String
dataDir
;
@Value
(
"${collectionSample.filename}"
)
private
String
collectionSampleFilename
;
@Value
(
"${ratingSample.filename}"
)
private
String
ratingSampleFilename
;
@Value
(
"${recommandations.filename}"
)
private
String
recommandationsFilename
;
private
String
sampleFilename
;
private
String
algorithm
;
private
Recommender
recommender
;
private
int
topSize
;
@Override
public
void
run
(
ApplicationArguments
args
)
throws
Exception
{
loadParameters
();
logger
.
trace
(
"Parameters loaded"
);
Set
<
Long
>
userIds
=
loadUserIdsFromSample
();
RecommenderFactory
recommenderFactory
=
new
RecommenderFactory
();
recommender
=
recommenderFactory
.
build
(
algorithm
,
dataDir
+
sampleFilename
);
logger
.
trace
(
"Recommender built"
);
ProcessingExpert
processingExpert
=
new
ProcessingExpert
(
recommender
,
topSize
);
ProcessingRecommendations
processingRecommendations
=
processingExpert
.
getRecommendations
(
userIds
);
logger
.
trace
(
"Recommendations done"
);
writeRecommendationsToFile
(
processingRecommendations
);
logger
.
trace
(
"Recommendations written"
);
}
private
Set
<
Long
>
loadUserIdsFromSample
()
throws
ProcessingException
{
Set
<
Long
>
userIds
=
new
HashSet
<>();
Reader
in
=
null
;
try
{
in
=
new
FileReader
(
dataDir
+
sampleFilename
);
Iterable
<
CSVRecord
>
records
=
CSVFormat
.
TDF
.
withFirstRecordAsHeader
().
parse
(
in
);
for
(
CSVRecord
record
:
records
)
{
userIds
.
add
(
Long
.
parseLong
(
record
.
get
(
"userId"
)));
}
}
catch
(
FileNotFoundException
e
)
{
throw
new
ProcessingException
(
"sample file not found "
+
dataDir
+
sampleFilename
,
e
);
}
catch
(
IOException
e
)
{
throw
new
ProcessingException
(
"Can't read user ids from sample file "
+
dataDir
+
sampleFilename
,
e
);
}
return
userIds
;
}
private
void
writeRecommendationsToFile
(
ProcessingRecommendations
processingRecommendations
)
throws
ProcessingException
{
try
{
CSVPrinter
csvPrinter
=
new
CSVPrinter
(
new
FileWriter
(
new
File
(
dataDir
,
recommandationsFilename
)),
CSVFormat
.
TDF
.
withHeader
(
"itemId"
,
"userId"
));
// TODO : finish
Set
<
RecommendationElement
>
recommendations
=
processingRecommendations
.
getRecommendations
();
if
(
recommendations
.
isEmpty
())
{
logger
.
trace
(
"No recommendations at all"
);
}
else
{
logger
.
trace
(
"{} recommendations"
,
recommendations
.
size
());
}
// forEach incompatible avec IOException
for
(
RecommendationElement
recommendation
:
recommendations
)
{
csvPrinter
.
printRecord
(
recommendation
.
getItemId
(),
recommendation
.
getUserId
());
}
csvPrinter
.
close
();
}
catch
(
IOException
e
)
{
throw
new
ProcessingException
(
"Can't write recommendations file "
+
dataDir
+
recommandationsFilename
,
e
);
}
}
/**
* read properties file from application.properties' parameter.fileName then search for parameters inside
* for ratings, select rating or collection file as the sample file for sample ; using others directly
*
* todo replace this by a command line switch ?
*
* @throws ProcessingException
*/
private
void
loadParameters
()
throws
ProcessingException
{
try
(
InputStream
in
=
new
FileInputStream
(
new
File
(
dataDir
,
parametersFilename
)))
{
Properties
properties
=
new
Properties
();
properties
.
load
(
in
);
if
(
properties
.
containsKey
(
"ratings"
))
{
logger
.
trace
(
"ratings {}"
,
properties
.
getProperty
(
"ratings"
));
if
(
Boolean
.
parseBoolean
(
properties
.
getProperty
(
"ratings"
)))
{
sampleFilename
=
ratingSampleFilename
;
}
else
{
sampleFilename
=
collectionSampleFilename
;
}
}
else
{
// by default, takes collection
sampleFilename
=
collectionSampleFilename
;
}
if
(
properties
.
containsKey
(
"algorithm"
))
{
algorithm
=
properties
.
getProperty
(
"algorithm"
);
}
else
{
// default algorithm is Cosine
algorithm
=
"cosine"
;
}
if
(
properties
.
containsKey
(
"topSize"
))
{
topSize
=
Integer
.
parseInt
(
properties
.
getProperty
(
"topSize"
));
}
else
{
// default top size is 10
topSize
=
10
;
}
}
catch
(
IOException
e
)
{
throw
new
ProcessingException
(
"Can't read parameters properties file "
+
parametersFilename
,
e
);
}
}
private
class
ProcessingException
extends
Exception
{
public
ProcessingException
()
{
super
();
}
public
ProcessingException
(
String
message
)
{
super
(
message
);
}
public
ProcessingException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
ProcessingException
(
Throwable
cause
)
{
super
(
cause
);
}
protected
ProcessingException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
}
}
}
\ No newline at end of file
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/RecommendationElement.java
0 → 100644
View file @
3781ca3
package
org
.
legrog
.
recommendation
.
process
;
public
class
RecommendationElement
{
private
Long
userId
;
private
Long
itemId
;
public
RecommendationElement
(
Long
userId
,
Long
itemId
)
{
this
.
userId
=
userId
;
this
.
itemId
=
itemId
;
}
public
Long
getUserId
()
{
return
userId
;
}
public
Long
getItemId
()
{
return
itemId
;
}
}
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/Recommender.java
View file @
3781ca3
...
...
@@ -5,7 +5,5 @@ import org.grouplens.lenskit.scored.ScoredId;
import
java.util.List
;
public
interface
Recommender
{
void
Recommender
(
String
filePath
);
List
<
ScoredId
>
recommend
(
long
user
,
int
n
);
}
...
...
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/RecommenderFactory.java
0 → 100644
View file @
3781ca3
package
org
.
legrog
.
recommendation
.
process
;
import
org.springframework.stereotype.Component
;
@Component
public
class
RecommenderFactory
{
public
Recommender
build
(
String
recommenderName
,
String
filePath
)
{
Recommender
recommender
;
if
(
recommenderName
.
equals
(
"cosine"
))
{
recommender
=
new
CosineRecommender
(
filePath
);
}
else
if
(
recommenderName
.
equals
(
"funkSVD"
))
{
recommender
=
new
FunkSVDRecommender
(
filePath
);
}
else
if
(
recommenderName
.
equals
(
"pearson"
))
{
recommender
=
new
PearsonRecommender
(
filePath
);
}
else
{
recommender
=
new
SlopeOneRecommender
(
filePath
);
}
return
recommender
;
}
}
grog-recommendation/grog-recommendation-process/src/main/java/org/legrog/recommendation/process/SlopeOneRecommender.java
View file @
3781ca3
...
...
@@ -30,8 +30,7 @@ public class SlopeOneRecommender implements Recommender {
ItemRecommender
irec
;
@Override
public
void
Recommender
(
String
filePath
)
{
public
SlopeOneRecommender
(
String
filePath
)
{
config
=
new
LenskitConfiguration
();
config
.
bind
(
ItemScorer
.
class
).
to
(
SlopeOneItemScorer
.
class
);
...
...
grog-recommendation/grog-recommendation-process/src/main/resources/logback.xml
0 → 100644
View file @
3781ca3
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender
name=
"STDOUT"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger
name=
"org.legrog"
level=
"DEBUG"
/>
<logger
name=
"org.legrog.recommendation.process"
level=
"TRACE"
/>
<root
level=
"warn"
>
<appender-ref
ref=
"STDOUT"
/>
</root>
</configuration>
\ No newline at end of file
Please
register
or
login
to post a comment