Commit 57e5c8a5 authored by Adrien Dorsaz's avatar Adrien Dorsaz

Second review code

parent 033e70a7
......@@ -8,93 +8,98 @@ Emotions::Emotions()
_saveJoy=false;
_saveSad=false;
_saveFear=false;
_nbInitDone=0;
_sizeSet=0;
_arousalSet = new QMap<double,double>();
_valenceSet = new QMap<double,double>();
_totalArousalOccurrences = new QMap<double, double>();
_totalValenceOccurrences = new QMap<double, double>();
_trainedArousalClasses = new QMap<QString, QMap<double, double>*>();
_trainedValenceClasses = new QMap<QString, QMap<double, double>*>();
getClassifiers();
}
void Emotions::arousalValence(double arousal, double valence){
arousal=int(arousal)%10;
valence=int(valence)%10;
insertValueAndTotal(_arousalSet, _totalArousalOccurrences, arousal);
insertValueAndTotal(_valenceSet, _totalValenceOccurrences, valence);
_sizeSet++;
if(_saveCalm){
if(_sizeSet >= NB_AROUSAL_VALENCE_BEFORE_CLASS){
updateTrainedClass("calm", "positive");
_saveCalm=false;
_nbInitDone++;
qDebug()<<"initCalm done";
}
updateTrainedClass("calm", "positive");
}
if(_saveJoy){
if(_sizeSet >= NB_AROUSAL_VALENCE_BEFORE_CLASS){
updateTrainedClass("exited", "positive");
_saveJoy=false;
_nbInitDone++;
qDebug()<<"initJoy done";
}
updateTrainedClass("exited", "positive");
}
if(_saveSad){
if(_sizeSet >= NB_AROUSAL_VALENCE_BEFORE_CLASS){
updateTrainedClass("calm", "negative");
_saveSad=false;
_nbInitDone++;
qDebug()<<"initSad done";
}
updateTrainedClass("calm", "negative");
}
if(_saveFear){
if(_sizeSet >= NB_AROUSAL_VALENCE_BEFORE_CLASS){
updateTrainedClass("exited", "negative");
_saveFear=false;
_nbInitDone++;
qDebug()<<"initFear done";
}
updateTrainedClass("exited", "negative");
}
if(_nbInitDone==4 && _sizeSet>=NB_AROUSAL_VALENCE_BEFORE_CLASS){
if(_guess){
foreach(QString klass, _trainedArousalClasses->keys()){
qDebug()<<"Emo : klass "<<klass<<" has "<<_trainedArousalClasses->value(klass)->size()<<" values";
}
if(_arousalClassifier==NULL){
_arousalClassifier = new NaiveBaiseClassifier(_trainedArousalClasses, _totalArousalOccurrences);
}
foreach(QString klass, _trainedValenceClasses->keys()){
qDebug()<<"Emo : klass "<<klass<<" has "<<_trainedValenceClasses->value(klass)->size()<<" values";
}
if(_valenceClassifier==NULL){
_valenceClassifier = new NaiveBaiseClassifier(_trainedValenceClasses, _totalValenceOccurrences);
}
curArousal = _arousalClassifier->classify(_arousalSet);
curValence = _valenceClassifier->classify(_valenceSet);
emit giveEmotion(QVariant(curArousal+" "+curValence));
_sizeSet=0;
_arousalSet->clear();
_valenceSet->clear();
}else{
insertValue(_arousalSet, arousal);
insertValue(_valenceSet, valence);
QString emotion;
if(curArousal.contains("calm") && curValence.contains("positive")){
emotion="calm";
}else if(curArousal.contains("calm") && curValence.contains("negative")){
emotion="sad";
}else if(curArousal.contains("exited") && curValence.contains("positive")){
emotion="joy";
}else if(curArousal.contains("exited") && curValence.contains("negative")){
emotion="fear";
}else{
emotion="impossible to know...";
}
emit giveEmotion(QVariant(emotion));
_guess=false;
}
}
void Emotions::initCalm(){
qDebug()<<"initCalm begin";
_saveCalm = true;
void Emotions::toggleSaveCalm(bool save){
_saveCalm = save;
_arousalSet->clear();
_valenceSet->clear();
}
void Emotions::initJoy(){
qDebug()<<"initJoy begin";
_saveJoy = true;
void Emotions::toggleSaveJoy(bool save){
_saveJoy = save;
_arousalSet->clear();
_valenceSet->clear();
}
void Emotions::toggleSaveSad(bool save){
_saveSad=save;
_arousalSet->clear();
_valenceSet->clear();
}
void Emotions::initSad(){
qDebug()<<"initSad begin";
_saveSad=true;
void Emotions::toggleSaveFear(bool save){
_saveFear=save;
_arousalSet->clear();
_valenceSet->clear();
}
void Emotions::initFear(){
qDebug()<<"initFear begin";
_saveFear=true;
void Emotions::guessEmotion(){
_guess=true;
}
void Emotions::insertValueAndTotal(QMap<double, double> *valueSet, QMap<double, double> *totalSet, double val){
......@@ -123,7 +128,7 @@ void Emotions::updateTrainedClass(QString arousal, QString valence){
double curVal = arousalIt.value();
if(_trainedArousalClasses->value(arousal)->contains(curKey)){
_trainedArousalClasses->value(arousal)->insert(curKey,
_trainedArousalClasses->value(arousal)->value(curKey)+curVal);
_trainedArousalClasses->value(arousal)->value(curKey)+curVal);
}else{
_trainedArousalClasses->value(arousal)->insert(curKey,curVal);
}
......@@ -140,7 +145,7 @@ void Emotions::updateTrainedClass(QString arousal, QString valence){
double curVal = valenceIt.value();
if(_trainedValenceClasses->value(valence)->contains(curKey)){
_trainedValenceClasses->value(valence)->insert(curKey,
_trainedValenceClasses->value(valence)->value(curKey)+curVal);
_trainedValenceClasses->value(valence)->value(curKey)+curVal);
}else{
_trainedValenceClasses->value(valence)->insert(curKey,curVal);
}
......@@ -149,7 +154,31 @@ void Emotions::updateTrainedClass(QString arousal, QString valence){
}else{
_trainedValenceClasses->insert(valence, _valenceSet);
}
_arousalSet->clear();
_valenceSet->clear();
_sizeSet = 0;
}
void Emotions::storeClassifiers(){
QFile file(Sbs2Common::getRootAppPath()+"emotionClasses.dat");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Emotions : cannot open file emotionClasses.dat : "
<< qPrintable(file.errorString()) << file.fileName()<< endl;
return;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_8);
out<<*_arousalClassifier;
out<<*_valenceClassifier;
}
void Emotions::getClassifiers(){
QFile file(Sbs2Common::getRootAppPath()+"emotionClasses.dat");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Emotions : cannot open file emotionClasses.dat : "
<< qPrintable(file.errorString()) << file.fileName() << endl;
return;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_8);
in>>*_arousalClassifier;
in>>*_valenceClassifier;
}
......@@ -6,10 +6,9 @@
#include <QDebug>
#include <QMapIterator>
#include <QVariant>
#include "sbs2common.h"
#include "naivebaiseclassifier.h"
#define NB_AROUSAL_VALENCE_BEFORE_CLASS 1000
class Emotions : public QObject{
Q_OBJECT
......@@ -27,9 +26,7 @@ private:
bool _saveJoy;
bool _saveSad;
bool _saveFear;
double _sizeSet;
int _nbInitDone;
bool _guess;
QMap<double, double>* _arousalSet;
QMap<double, double>* _valenceSet;
......@@ -39,19 +36,24 @@ private:
void insertValueAndTotal(QMap<double, double>* valueSet, QMap<double, double>* totalSet, double val);
void insertValue(QMap<double, double> *valueSet, double val);
void updateTrainedClass(QString arousal, QString valence);
void getClassifiers();
public:
Emotions();
public slots:
void arousalValence(double arousal, double valence);
void initCalm();
void initJoy();
void initSad();
void initFear();
void toggleSaveCalm(bool save);
void toggleSaveFear(bool save);
void toggleSaveSad(bool save);
void toggleSaveJoy(bool save);
void guessEmotion();
void storeClassifiers();
signals:
void giveEmotion(QVariant emotion);
};
Q_DECLARE_METATYPE(NaiveBaiseClassifier);
#endif // EMOTIONS_H
......@@ -6,6 +6,7 @@
#include <mycallback.h>
#include <QVariant>
#include <QDir>
#include "emotions.h"
......@@ -17,6 +18,9 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qDebug() << "catalogPath: "<<Sbs2Common::setDefaultCatalogPath();
//set path where application data is stored
qDebug() << "rootAppPath: "<<Sbs2Common::setDefaultRootAppPath();
QDir* dir = new QDir();
dir->mkpath(Sbs2Common::getCatalogPath());
dir->mkpath(Sbs2Common::getRootAppPath());
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
......@@ -31,10 +35,12 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
Emotions *emotions = new Emotions();
QObject::connect(myCallback, SIGNAL(arousalValence(double, double)), emotions, SLOT(arousalValence(double,double)));
QObject::connect(rootObject, SIGNAL(initSad()), emotions, SLOT(initSad()));
QObject::connect(rootObject, SIGNAL(initCalm()), emotions, SLOT(initCalm()));
QObject::connect(rootObject, SIGNAL(initFear()), emotions, SLOT(initFear()));
QObject::connect(rootObject, SIGNAL(initJoy()), emotions, SLOT(initJoy()));
QObject::connect(rootObject, SIGNAL(toggleSaveSad(bool)), emotions, SLOT(toggleSaveSad(bool)));
QObject::connect(rootObject, SIGNAL(toggleSaveCalm(bool)), emotions, SLOT(toggleSaveCalm(bool)));
QObject::connect(rootObject, SIGNAL(toggleSaveFear(bool)), emotions, SLOT(toggleSaveFear(bool)));
QObject::connect(rootObject, SIGNAL(toggleSaveJoy(bool)), emotions, SLOT(toggleSaveJoy(bool)));
QObject::connect(rootObject, SIGNAL(storeClassifiers()), emotions, SLOT(storeClassifiers()));
QObject::connect(rootObject, SIGNAL(guessEmotion()), emotions, SLOT(guessEmotion()));
QObject::connect(emotions, SIGNAL(giveEmotion(QVariant)), rootObject, SLOT(updateEmotion(QVariant)));
QObject::connect(myCallback,SIGNAL(timeTick8()),rootObject,SLOT(timeTick()));
......
......@@ -39,9 +39,9 @@ void MyCallback::getData(Sbs2Packet *packet)
// So we'll apply same idea than colorOfMind but we use sensors otherwise
// colorOfMind : (front beta power)/(front alpha power)
double arousal = (f3_alpha/f3_beta + f4_alpha/f4_beta)/2;
double arousal = (af3_alpha/af3_beta + af4_alpha/af4_beta)/2;
// colorOfMind : Valence = (left beta power)/(left alpha power) – (right beta power)/(right alpha power)
double valence = (f4_alpha/f4_beta - f3_alpha/f3_beta);
double valence = (af4_alpha/af4_beta - af3_alpha/af3_beta);
//arousal = af3_alpha;
//valence=thisPacket->values["AF3"];
......
#include "naivebaiseclassifier.h"
NaiveBaiseClassifier::NaiveBaiseClassifier(const NaiveBaiseClassifier& naiveBaise){
qDebug()<<"will copy nbc by constructor";
_trainedClasses = new QMap<QString, QMap<double, double>*>(naiveBaise.getTrainedClasses());
_totalFeatureOccurrences = new QMap<double,double>(naiveBaise.getTotalFeatureOccurences());
}
NaiveBaiseClassifier& NaiveBaiseClassifier::operator=(const NaiveBaiseClassifier& naiveBaise) {
if ( this == &naiveBaise ) {
return *this; //Self assignment : nothing to do
}
QMap<double,double>* tmpOcc = new QMap<double,double>(naiveBaise.getTotalFeatureOccurences());
foreach(double feature, tmpOcc->keys()){
qDebug()<<feature;
//_totalFeatureOccurrences->insert(feature, tmpOcc->value(feature));
}
qDebug()<<"Done !";
QMapIterator<QString, QMap<double,double>*> trainedCl(naiveBaise.getTrainedClasses());
while(trainedCl.hasNext()){
_trainedClasses->insert(trainedCl.key(),trainedCl.value());
trainedCl.next();
}
return *this;
}
NaiveBaiseClassifier::NaiveBaiseClassifier(){
_trainedClasses=new QMap<QString,QMap<double, double>*>();
_totalFeatureOccurrences = new QMap<double,double>();
}
NaiveBaiseClassifier::NaiveBaiseClassifier(QMap<QString, QMap<double, double> *> *trainedClasses,
QMap<double, double> *totalFeatureOccurrences){
_trainedClasses=trainedClasses;
_totalFeatureOccurrences=totalFeatureOccurrences;
_trainedClasses = new QMap<QString, QMap<double,double>*>(*trainedClasses);
foreach(QString klass, _trainedClasses->keys()){
_trainedClasses->insert(klass,new QMap<double,double>(*_trainedClasses->value(klass)));
}
_totalFeatureOccurrences=new QMap<double,double>(*totalFeatureOccurrences);
}
NaiveBaiseClassifier::NaiveBaiseClassifier(QMap<QString, QMap<double, double> *> &trainedClasses,
QMap<double, double> &totalFeatureOccurrences){
_trainedClasses = new QMap<QString, QMap<double,double>*>(trainedClasses);
foreach(QString klass, _trainedClasses->keys()){
_trainedClasses->insert(klass,new QMap<double,double>(*_trainedClasses->value(klass)));
}
_totalFeatureOccurrences=new QMap<double,double>(totalFeatureOccurrences);
}
QString NaiveBaiseClassifier::classify(QMap<double, double> *featureSet){
......@@ -16,6 +61,7 @@ QString NaiveBaiseClassifier::classify(QMap<double, double> *featureSet){
QMapIterator<double, double> featureIt(*featureSet);
while (featureIt.hasNext()) {
foreach(QString klass, _trainedClasses->keys()){
if(classProbability->value(klass)!=0)
classProbability->insert(klass,
classProbability->value(klass)
+ (featureIt.value() * log(probability(featureIt.key(), klass))));
......@@ -23,6 +69,10 @@ QString NaiveBaiseClassifier::classify(QMap<double, double> *featureSet){
featureIt.next();
}
foreach(QString klass, classProbability->keys()){
qDebug()<<klass<<" has prob. "<<classProbability->value(klass)<< " and size "<<_trainedClasses->value(klass)->size();
}
QString resultClass="";
foreach(QString klass, classProbability->keys()){
......@@ -43,3 +93,45 @@ double NaiveBaiseClassifier::probability(double feature, QString klass){
double den = _totalFeatureOccurrences->value(feature)+_trainedClasses->size();
return num/den;
}
QMap<QString,QMap<double, double>*>& NaiveBaiseClassifier::getTrainedClasses() const{
return *_trainedClasses;
}
QMap<double, double>& NaiveBaiseClassifier::getTotalFeatureOccurences() const{
return *_totalFeatureOccurrences;
}
QDataStream &operator<<(QDataStream &out, const NaiveBaiseClassifier &naiveBaise){
QMap<QString, QMap<double,double>*>* trainedClasses =
new QMap<QString, QMap<double,double>*>(naiveBaise.getTrainedClasses());
qDebug()<<"size : "<<naiveBaise.getTrainedClasses().size();
out<<naiveBaise.getTrainedClasses().size();
foreach(QString klass, trainedClasses->keys()){
out<<klass;
out<<*(trainedClasses->value(klass));
}
out << naiveBaise.getTotalFeatureOccurences();
return out;
}
QDataStream &operator>>(QDataStream &in, NaiveBaiseClassifier &naiveBaise){
int sizeMap;
QMap<QString,QMap<double, double>*> trainedClasses;
QMap<double, double> totalFeatureOccurences;
in >> sizeMap;
for(int i=0;i<sizeMap;++i){
QMap<double, double> trainedValue;
QString trainedKey;
in >> trainedKey >> trainedValue;
trainedClasses.insert(trainedKey, &trainedValue);
}
in >> totalFeatureOccurences;
qDebug()<<"Ready to read";
naiveBaise = *(new NaiveBaiseClassifier(trainedClasses, totalFeatureOccurences));
qDebug()<<"...read";
return in;
}
......@@ -10,9 +10,10 @@ http://www.nils-haldenwang.de/computer-science/machine-learning/how-to-apply-nai
#include <QString>
#include <math.h>
#include <QObject>
#include <QDataStream>
#include <QDebug>
class NaiveBaiseClassifier: public QObject
{
class NaiveBaiseClassifier: public QObject{
Q_OBJECT
private:
QMap<QString,QMap<double, double>*> * _trainedClasses;
......@@ -21,9 +22,20 @@ private:
double probability(double feature, QString klass);
public:
NaiveBaiseClassifier();
NaiveBaiseClassifier(QMap<QString,QMap<double, double>*>* trainedClasses, // key : class name, value : value found during training and their number of occurences
QMap<double, double>* totalFeatureOccurrences); // key : found feature, value : total of occurences sum of every class
NaiveBaiseClassifier(QMap<QString,QMap<double, double>*>& trainedClasses,
QMap<double, double>& totalFeatureOccurrences);
NaiveBaiseClassifier(const NaiveBaiseClassifier& naiveBaise);
NaiveBaiseClassifier& operator=(const NaiveBaiseClassifier& naiveBaise);
QString classify(QMap<double, double>* featureSet); // featureSet : set of values to classify with number of occurence
QMap<QString,QMap<double, double>*> &getTrainedClasses() const;
QMap<double, double> &getTotalFeatureOccurences() const;
};
QDataStream &operator<<(QDataStream &out, const NaiveBaiseClassifier &naiveBaise);
QDataStream &operator>>(QDataStream &in, NaiveBaiseClassifier &naiveBaise);
#endif // NAIVEBAISECLASSIFIER_H
This diff is collapsed.
Subproject commit f0b65c9a435076cc21f932ee6c3d77974ce9c141
Subproject commit 1c61d196a18420d99c0bbf8efbb717523359b4f3
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment