diff --git a/.rvmrc b/.rvmrc index 7eabdcc..975a479 100644 --- a/.rvmrc +++ b/.rvmrc @@ -1 +1,2 @@ -rvm use jruby-1.6.6 \ No newline at end of file +rvm use jruby-1.6.7 +export JRUBY_OPTS=--1.9 \ No newline at end of file diff --git a/Gemfile b/Gemfile index 293cb17..873af94 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ source 'https://rubygems.org' -gem 'rails', '3.2.1' +gem 'rails', '3.2.0' # Bundle edge Rails instead: # gem 'rails', :git => 'git://github.com/rails/rails.git' -gem 'sqlite3' +# gem 'sqlite3' +# gem 'mysql2' # Gems used only for assets and not required diff --git a/Gemfile.lock b/Gemfile.lock index 6f5da20..ef57838 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,31 +1,31 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.1) - actionpack (= 3.2.1) + actionmailer (3.2.0) + actionpack (= 3.2.0) mail (~> 2.4.0) - actionpack (3.2.1) - activemodel (= 3.2.1) - activesupport (= 3.2.1) + actionpack (3.2.0) + activemodel (= 3.2.0) + activesupport (= 3.2.0) builder (~> 3.0.0) erubis (~> 2.7.0) - journey (~> 1.0.1) + journey (~> 1.0.0) rack (~> 1.4.0) rack-cache (~> 1.1) rack-test (~> 0.6.1) sprockets (~> 2.1.2) - activemodel (3.2.1) - activesupport (= 3.2.1) + activemodel (3.2.0) + activesupport (= 3.2.0) builder (~> 3.0.0) - activerecord (3.2.1) - activemodel (= 3.2.1) - activesupport (= 3.2.1) + activerecord (3.2.0) + activemodel (= 3.2.0) + activesupport (= 3.2.0) arel (~> 3.0.0) tzinfo (~> 0.3.29) - activeresource (3.2.1) - activemodel (= 3.2.1) - activesupport (= 3.2.1) - activesupport (3.2.1) + activeresource (3.2.0) + activemodel (= 3.2.0) + activesupport (= 3.2.0) + activesupport (3.2.0) i18n (~> 0.6) multi_json (~> 1.0) arel (3.0.2) @@ -36,7 +36,7 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.2.0) + coffee-script-source (1.3.1) erubis (2.7.0) execjs (1.3.0) multi_json (~> 1.0) @@ -47,6 +47,7 @@ GEM railties (>= 3.2.0, < 5.0) thor (~> 0.14) json (1.6.6) + json (1.6.6-java) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) @@ -61,17 +62,17 @@ GEM rack rack-test (0.6.1) rack (>= 1.0) - rails (3.2.1) - actionmailer (= 3.2.1) - actionpack (= 3.2.1) - activerecord (= 3.2.1) - activeresource (= 3.2.1) - activesupport (= 3.2.1) + rails (3.2.0) + actionmailer (= 3.2.0) + actionpack (= 3.2.0) + activerecord (= 3.2.0) + activeresource (= 3.2.0) + activesupport (= 3.2.0) bundler (~> 1.0) - railties (= 3.2.1) - railties (3.2.1) - actionpack (= 3.2.1) - activesupport (= 3.2.1) + railties (= 3.2.0) + railties (3.2.0) + actionpack (= 3.2.0) + activesupport (= 3.2.0) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -88,7 +89,6 @@ GEM hike (~> 1.2) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.5) thor (0.14.6) tilt (1.3.3) treetop (1.4.10) @@ -100,12 +100,12 @@ GEM multi_json (>= 1.0.2) PLATFORMS + java ruby DEPENDENCIES coffee-rails (~> 3.2.1) jquery-rails - rails (= 3.2.1) + rails (= 3.2.0) sass-rails (~> 3.2.3) - sqlite3 uglifier (>= 1.0.3) diff --git a/app/assets/javascripts/sentiment_predictor.js.coffee b/app/assets/javascripts/sentiment_predictor.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/sentiment_predictor.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/sentiment_predictor.css.scss b/app/assets/stylesheets/sentiment_predictor.css.scss new file mode 100644 index 0000000..5290197 --- /dev/null +++ b/app/assets/stylesheets/sentiment_predictor.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the SentimentPredictor controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/sentiment_predictor_controller.rb b/app/controllers/sentiment_predictor_controller.rb new file mode 100644 index 0000000..c312187 --- /dev/null +++ b/app/controllers/sentiment_predictor_controller.rb @@ -0,0 +1,46 @@ +require 'java' + +# Set the weka home +ENV['WEKA_HOME'] = File.join(Rails.root, '/lib/weka-3-7-5/packages') +require Rails.root + 'lib/weka-3-7-5/packages/packages/LibSVM/LibSVM.jar' +require Rails.root + 'lib/weka-3-7-5/packages/packages/LibSVM/lib/libsvm.jar' +require Rails.root + 'lib/weka-3-7-5/packages/packages/LibLINEAR/LibLINEAR.jar' +require Rails.root + 'lib/weka-3-7-5/packages/packages/LibSVM/lib/libsvm.jar' +require Rails.root + 'lib/weka-3-7-5/packages/packages/LibLINEAR/lib/liblinear-1.8.jar' +require Rails.root + 'lib/weka-3-7-5/weka.jar' + +include_class "weka.core.Instances" +include_class "weka.core.Instance" +include_class "java.io.FileReader" +include_class "weka.core.Utils" +include_class "weka.core.SerializationHelper" +include_class "weka.core.DenseInstance" +include_class "weka.core.SparseInstance" + + + + +class SentimentPredictorController < ApplicationController + def index + + @arff ||= FileReader.new(Rails.root.join("data/sentiment.arff").to_s) + @classifier ||= SerializationHelper.read(Rails.root.join("models/sentiment.model").to_s) + + @data ||= begin + Instances.new(@arff,1).tap do |data| + data.setClassIndex data.num_attributes - 1 if data.class_index == -1 + end + end + + instance = SparseInstance.new(@data.num_attributes) + instance.set_dataset(@data) + instance.set_value(@data.attribute(0), params[:text]) + + result = @classifier.distribution_for_instance(instance).first + + render :text => result + end + + def create + end +end diff --git a/app/helpers/sentiment_predictor_helper.rb b/app/helpers/sentiment_predictor_helper.rb new file mode 100644 index 0000000..7a98c1c --- /dev/null +++ b/app/helpers/sentiment_predictor_helper.rb @@ -0,0 +1,2 @@ +module SentimentPredictorHelper +end diff --git a/app/views/sentiment_predictor/index.html.erb b/app/views/sentiment_predictor/index.html.erb new file mode 100644 index 0000000..028081e --- /dev/null +++ b/app/views/sentiment_predictor/index.html.erb @@ -0,0 +1,3 @@ +

Sentiment Predictor

+ +<%= form_for %> \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index a55b2c8..51c0a1e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,12 @@ require File.expand_path('../boot', __FILE__) -require 'rails/all' +# Pick the frameworks you want: +# require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "active_resource/railtie" +require "sprockets/railtie" +require "rails/test_unit/railtie" if defined?(Bundler) # If you precompile assets before deploying to production, use this line diff --git a/config/database.yml b/config/database.yml deleted file mode 100644 index 51a4dd4..0000000 --- a/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite version 3.x -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' -development: - adapter: sqlite3 - database: db/development.sqlite3 - pool: 5 - timeout: 5000 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - adapter: sqlite3 - database: db/test.sqlite3 - pool: 5 - timeout: 5000 - -production: - adapter: sqlite3 - database: db/production.sqlite3 - pool: 5 - timeout: 5000 diff --git a/config/environments/development.rb b/config/environments/development.rb index 414d425..0fe82d0 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -22,12 +22,6 @@ # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - config.active_record.auto_explain_threshold_in_seconds = 0.5 # Do not compress assets config.assets.compress = false diff --git a/config/environments/production.rb b/config/environments/production.rb index 5b6d029..de98333 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -61,7 +61,4 @@ # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 end diff --git a/config/routes.rb b/config/routes.rb index f389cdb..1ff2096 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,6 @@ Mlexample::Application.routes.draw do + resources :sentiment_predictor + # The priority is based upon order of creation: # first created -> highest priority. diff --git a/lib/sentiment/train.rb b/lib/sentiment/train.rb index a0c3d19..783c93d 100644 --- a/lib/sentiment/train.rb +++ b/lib/sentiment/train.rb @@ -26,8 +26,8 @@ arff_file = File.dirname(__FILE__) + "/../../data/sentiment.arff" -# options = "weka.classifiers.meta.FilteredClassifier -F \"weka.filters.unsupervised.attribute.StringToWordVector -R first-last -P wv- -W 50000 -prune-rate -1.0 -T -N 0 -L -stemmer weka.core.stemmers.NullStemmer -M 1 -tokenizer \\\"weka.core.tokenizers.NGramTokenizer -delimiters \\\\\\\" \\\\\\\\\\r\\\\\\\\\\n\\\\\\\\\\t.,;:\\\\\\\\\\'\\\\\\\\\\\\\\\"()?!\\\\\\\" -max 2 -min 1\\\"\" -W weka.classifiers.functions.LibLINEAR -- -S 0 -C 1.0 -E 0.01 -B 1.0 -P" -options = "weka.classifiers.meta.FilteredClassifier -F \"weka.filters.unsupervised.attribute.StringToWordVector -R first-last -P wv- -W 1000 -prune-rate -1.0 -T -N 0 -L -stemmer weka.core.stemmers.NullStemmer -M 1 \" -W weka.classifiers.functions.LibLINEAR -- -S 0 -C 1.0 -E 0.01 -B 1.0 -P" +options = "weka.classifiers.meta.FilteredClassifier -F \"weka.filters.unsupervised.attribute.StringToWordVector -R first-last -P wv- -W 50000 -prune-rate -1.0 -T -N 0 -L -stemmer weka.core.stemmers.NullStemmer -M 1 -tokenizer \\\"weka.core.tokenizers.NGramTokenizer -delimiters \\\\\\\" \\\\\\\\\\r\\\\\\\\\\n\\\\\\\\\\t.,;:\\\\\\\\\\'\\\\\\\\\\\\\\\"()?!\\\\\\\" -max 2 -min 1\\\"\" -W weka.classifiers.functions.LibLINEAR -- -S 0 -C 1.0 -E 0.01 -B 1.0 -P" +# options = "weka.classifiers.meta.FilteredClassifier -F \"weka.filters.unsupervised.attribute.StringToWordVector -R first-last -P wv- -W 1000 -prune-rate -1.0 -T -N 0 -L -stemmer weka.core.stemmers.NullStemmer -M 1 \" -W weka.classifiers.functions.LibLINEAR -- -S 0 -C 1.0 -E 0.01 -B 1.0 -P" arff = FileReader.new(arff_file) data = Instances.new(arff) diff --git a/lib/weka-3-7-5/packages/weka.log b/lib/weka-3-7-5/packages/weka.log index 526f0e3..7ce3e8c 100644 --- a/lib/weka-3-7-5/packages/weka.log +++ b/lib/weka-3-7-5/packages/weka.log @@ -1,4 +1,4 @@ -2012-04-05 14:07:26 weka.gui.GUIChooser main +2012-04-10 14:44:22 weka.gui.GUIChooser main INFO: Logging started Refreshing GOE props... ---Registering Weka Editors--- @@ -9,35 +9,47 @@ Trying to add database driver (JDBC): com.mckoi.JDBCDriver - Warning, not in CLA Trying to add database driver (JDBC): org.hsqldb.jdbcDriver - Warning, not in CLASSPATH? [KnowledgeFlow] Loading properties and plugins... [KnowledgeFlow] Initializing KF... -2012-04-05 14:07:29 weka.gui.explorer.Explorer +2012-04-10 14:44:26 weka.gui.explorer.Explorer INFO: Weka Explorer -2012-04-05 14:07:29 weka.gui.explorer.Explorer +2012-04-10 14:44:26 weka.gui.explorer.Explorer INFO: (c) 1999-2011 The University of Waikato, Hamilton, New Zealand -2012-04-05 14:07:29 weka.gui.explorer.Explorer +2012-04-10 14:44:26 weka.gui.explorer.Explorer INFO: web: http://www.cs.waikato.ac.nz/~ml/weka/ -2012-04-05 14:07:29 weka.gui.explorer.Explorer -INFO: Started on Thursday, 5 April 2012 -2012-04-05 14:07:49 weka.gui.explorer.PreprocessPanel$14 run -INFO: Base relation is now Relationships (15570 instances) -2012-04-05 14:07:59 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:44:26 weka.gui.explorer.Explorer +INFO: Started on Tuesday, 10 April 2012 +2012-04-10 14:44:37 weka.gui.explorer.PreprocessPanel$14 run +INFO: Base relation is now Tweets (19999 instances) +2012-04-10 14:44:54 weka.gui.explorer.PreprocessPanel$15 run +INFO: Command: weka.filters.unsupervised.attribute.StringToWordVector -R first-last -P w- -W 1000 -prune-rate -1.0 -N 0 -L -stemmer weka.core.stemmers.NullStemmer -M 1 -tokenizer "weka.core.tokenizers.WordTokenizer -delimiters \" \\r\\n\\t.,;:\\\'\\\"()?!\"" +2012-04-10 14:44:55 weka.gui.explorer.PreprocessPanel$14 run +INFO: Base relation is now Tweets-weka.filters.unsupervised.attribute.StringToWordVector-R1-Pw--W1000-prune-rate-1.0-N0-L-stemmerweka.core.stemmers.NullStemmer-M1-tokenizerweka.core.tokenizers.WordTokenizer -delimiters " \r\n\t.,;:\'\"()?!" (19999 instances) +2012-04-10 14:45:07 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Started weka.attributeSelection.CfsSubsetEval -2012-04-05 14:07:59 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:45:07 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Command: weka.attributeSelection.CfsSubsetEval -s "weka.attributeSelection.BestFirst -D 1 -N 5" -2012-04-05 14:07:59 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:45:07 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Filter command: weka.filters.supervised.attribute.AttributeSelection -E "weka.attributeSelection.CfsSubsetEval " -S "weka.attributeSelection.BestFirst -D 1 -N 5" -2012-04-05 14:07:59 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:45:07 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Meta-classifier command: weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.CfsSubsetEval " -S "weka.attributeSelection.BestFirst -D 1 -N 5" -W weka.classifiers.trees.J48 -- -C 0.25 -M 2 -2012-04-05 14:08:58 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:46:45 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Finished weka.attributeSelection.CfsSubsetEval weka.attributeSelection.BestFirst -2012-04-05 14:10:16 weka.gui.explorer.PreprocessPanel$14 run -INFO: Base relation is now Relationships (15579 instances) -2012-04-05 14:10:28 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:47:13 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Started weka.attributeSelection.InfoGainAttributeEval -2012-04-05 14:10:28 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:47:13 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Command: weka.attributeSelection.InfoGainAttributeEval -s "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" -2012-04-05 14:10:28 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:47:13 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Filter command: weka.filters.supervised.attribute.AttributeSelection -E "weka.attributeSelection.InfoGainAttributeEval " -S "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" -2012-04-05 14:10:28 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:47:13 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Meta-classifier command: weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.InfoGainAttributeEval " -S "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" -W weka.classifiers.trees.J48 -- -C 0.25 -M 2 -2012-04-05 14:10:35 weka.gui.explorer.AttributeSelectionPanel$10 run +2012-04-10 14:47:57 weka.gui.explorer.AttributeSelectionPanel$10 run +INFO: Finished weka.attributeSelection.InfoGainAttributeEval weka.attributeSelection.Ranker +2012-04-10 15:07:31 weka.gui.explorer.AttributeSelectionPanel$10 run +INFO: Started weka.attributeSelection.InfoGainAttributeEval +2012-04-10 15:07:31 weka.gui.explorer.AttributeSelectionPanel$10 run +INFO: Command: weka.attributeSelection.InfoGainAttributeEval -s "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" +2012-04-10 15:07:31 weka.gui.explorer.AttributeSelectionPanel$10 run +INFO: Filter command: weka.filters.supervised.attribute.AttributeSelection -E "weka.attributeSelection.InfoGainAttributeEval " -S "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" +2012-04-10 15:07:31 weka.gui.explorer.AttributeSelectionPanel$10 run +INFO: Meta-classifier command: weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.InfoGainAttributeEval " -S "weka.attributeSelection.Ranker -T -1.7976931348623157E308 -N -1" -W weka.classifiers.trees.J48 -- -C 0.25 -M 2 +2012-04-10 15:12:51 weka.gui.explorer.AttributeSelectionPanel$10 run INFO: Finished weka.attributeSelection.InfoGainAttributeEval weka.attributeSelection.Ranker diff --git a/models/sentiment.model b/models/sentiment.model index cb0b246..4035bf9 100644 Binary files a/models/sentiment.model and b/models/sentiment.model differ diff --git a/test/functional/sentiment_predictor_controller_test.rb b/test/functional/sentiment_predictor_controller_test.rb new file mode 100644 index 0000000..05351f9 --- /dev/null +++ b/test/functional/sentiment_predictor_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class SentimentPredictorControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/helpers/sentiment_predictor_helper_test.rb b/test/unit/helpers/sentiment_predictor_helper_test.rb new file mode 100644 index 0000000..b92ee3a --- /dev/null +++ b/test/unit/helpers/sentiment_predictor_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class SentimentPredictorHelperTest < ActionView::TestCase +end