From e6ae201cca59d206475e85d55f96923b8f8132ff Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 5 Nov 2025 12:19:04 +0900 Subject: [PATCH 01/17] feat: add JMRD datasets --- lib/datasets/jmrd.rb | 178 +++++++++++++++++++++++++++++++++++++++++++ test/test-jmrd.rb | 104 +++++++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 lib/datasets/jmrd.rb create mode 100644 test/test-jmrd.rb diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb new file mode 100644 index 00000000..d1eb38ed --- /dev/null +++ b/lib/datasets/jmrd.rb @@ -0,0 +1,178 @@ +require "json" + +require_relative "dataset" + +module Datasets + class JMRD < Dataset + Dialogue = Struct.new( + :dialog_id, + :movie_title, + :first_speaker, + :questionnaire, + :knowledge, + :utterances + ) + + Questionnaire = Struct.new( + :recommender, + :seeker + ) + + QuestionnaireAnswers = Struct.new( + :q1, + :q2, + :q3, + :q4, + :q5 + ) + + Knowledge = Struct.new( + :title, + :year, + :director_name, + :director_description, + :cast_names, + :cast_descriptions, + :genres, + :reviews, + :synopsis + ) + + Utterance = Struct.new( + :utterance_id, + :speaker, + :text, + :checked_knowledge + ) + + CheckedKnowledge = Struct.new( + :type, + :content + ) + + def initialize(type: :train) + super() + @metadata.id = "jmrd" + @metadata.name = "Japanese Movie Recommendation Dialogue Dataset (JMRD)" + @metadata.url = "https://github.com/ku-nlp/JMRD" + @metadata.licenses = ["CC-BY-SA-4.0"] + @metadata.description = <<~DESCRIPTION + JMRD (Japanese Movie Recommendation Dialogue Dataset) is a Japanese + knowledge-grounded dialogue dataset consisting of annotated movie + recommendation dialogues between humans. Every recommender's utterance + is associated with movie information as external knowledge. + + The dataset consists of about 5,000 dialogues between crowdworkers, + each of which consists of 23 utterances on average. All dialogues in + this dataset are divided into the train (4,575 dialogues), valid + (200 dialogues), and test sets (300 dialogues). + + Published in the 2nd DialDoc Workshop on Document-grounded Dialogue + and Conversational Question Answering, 2022. + + Reference: + Takashi Kodama, Ribeka Tanaka, and Sadao Kurohashi. + "Construction of Hierarchical Structured Knowledge-based Recommendation + Dialogue Dataset and Dialogue System." + DESCRIPTION + + unless [:train, :valid, :test].include?(type) + raise ArgumentError, "Type must be :train, :valid, or :test: #{type.inspect}" + end + @type = type + end + + def each + return to_enum(__method__) unless block_given? + + open_data do |json_data| + json_data.each do |dialogue_data| + yield parse_dialogue(dialogue_data) + end + end + end + + private + + def open_data + data_path = cache_dir_path + "#{@type}.json" + data_url = "https://raw.githubusercontent.com/ku-nlp/JMRD/main/data/#{@type}.json" + download(data_path, data_url) + + json_data = JSON.parse(File.read(data_path)) + yield json_data + end + + def parse_dialogue(data) + Dialogue.new( + data["dialog_id"], + data["movie_title"], + data["first_speaker"], + parse_questionnaire(data["questionnaire"]), + parse_knowledge(data["knowledge"]), + parse_utterances(data["dialog"]) + ) + end + + def parse_questionnaire(data) + return nil if data.nil? + + Questionnaire.new( + parse_questionnaire_answers(data["recommender"]), + parse_questionnaire_answers(data["seeker"]) + ) + end + + def parse_questionnaire_answers(data) + return nil if data.nil? + + QuestionnaireAnswers.new( + data["Q1"], + data["Q2"], + data["Q3"], + data["Q4"], + data["Q5"] + ) + end + + def parse_knowledge(data) + return nil if data.nil? + + Knowledge.new( + data["タイトル"], + data["製作年度"], + data["監督名"], + data["監督説明"], + data["キャスト名"], + data["キャスト説明"], + data["ジャンル"], + data["レビュー"], + data["あらすじ"] + ) + end + + def parse_utterances(data) + return [] if data.nil? + + data.map do |utterance_data| + parse_utterance(utterance_data) + end + end + + def parse_utterance(data) + checked_knowledge = nil + if data["checked_knowledge"] + checked_knowledge = data["checked_knowledge"].map do |ck| + CheckedKnowledge.new(ck["type"], ck["content"]) + end + end + + Utterance.new( + data["utterance_id"], + data["speaker"], + data["text"], + checked_knowledge + ) + end + end +end diff --git a/test/test-jmrd.rb b/test/test-jmrd.rb new file mode 100644 index 00000000..0ddb8a18 --- /dev/null +++ b/test/test-jmrd.rb @@ -0,0 +1,104 @@ +class JMRDTest < Test::Unit::TestCase + sub_test_case("type") do + test("train") do + dataset = Datasets::JMRD.new(type: :train) + dialogues = dataset.to_a + + assert_equal(4575, dialogues.size) + + first_dialogue = dialogues[0] + assert_equal("01884", first_dialogue.dialog_id) + assert_equal("時をかける少女", first_dialogue.movie_title) + assert_equal("recommender", first_dialogue.first_speaker) + + # Check questionnaire + assert_not_nil(first_dialogue.questionnaire) + assert_equal(5, first_dialogue.questionnaire.recommender.q1) + assert_equal(4, first_dialogue.questionnaire.seeker.q1) + + # Check knowledge + assert_not_nil(first_dialogue.knowledge) + assert_equal("時をかける少女", first_dialogue.knowledge.title) + assert_equal("2006年", first_dialogue.knowledge.year) + assert_equal("細田守", first_dialogue.knowledge.director_name) + + # Check utterances + assert_equal(26, first_dialogue.utterances.size) + assert_equal("01884_00", first_dialogue.utterances[0].utterance_id) + assert_equal("recommender", first_dialogue.utterances[0].speaker) + assert_equal("こんにちは", first_dialogue.utterances[0].text) + assert_not_nil(first_dialogue.utterances[0].checked_knowledge) + assert_equal(1, first_dialogue.utterances[0].checked_knowledge.size) + assert_equal("[知識なし]", first_dialogue.utterances[0].checked_knowledge[0].type) + end + + test("valid") do + dataset = Datasets::JMRD.new(type: :valid) + dialogues = dataset.to_a + + assert_equal(200, dialogues.size) + + first_dialogue = dialogues[0] + assert_not_nil(first_dialogue.dialog_id) + assert_not_nil(first_dialogue.movie_title) + assert(["recommender", "seeker"].include?(first_dialogue.first_speaker)) + end + + test("test") do + dataset = Datasets::JMRD.new(type: :test) + dialogues = dataset.to_a + + assert_equal(300, dialogues.size) + + first_dialogue = dialogues[0] + assert_not_nil(first_dialogue.dialog_id) + assert_not_nil(first_dialogue.movie_title) + assert(["recommender", "seeker"].include?(first_dialogue.first_speaker)) + end + + test("invalid") do + message = "Type must be :train, :valid, or :test: :invalid" + assert_raise(ArgumentError.new(message)) do + Datasets::JMRD.new(type: :invalid) + end + end + end + + sub_test_case("#metadata") do + test("#id") do + dataset = Datasets::JMRD.new(type: :train) + assert_equal("jmrd", dataset.metadata.id) + end + + test("#name") do + dataset = Datasets::JMRD.new(type: :train) + assert_equal("Japanese Movie Recommendation Dialogue Dataset (JMRD)", + dataset.metadata.name) + end + + test("#url") do + dataset = Datasets::JMRD.new(type: :train) + assert_equal("https://github.com/ku-nlp/JMRD", dataset.metadata.url) + end + + test("#licenses") do + dataset = Datasets::JMRD.new(type: :train) + assert_equal([Datasets::License.new("CC-BY-SA-4.0")], + dataset.metadata.licenses) + end + + test("#description") do + dataset = Datasets::JMRD.new(type: :train) + description = dataset.metadata.description + assert do + description.include?("Japanese Movie Recommendation Dialogue Dataset") + end + assert do + description.include?("5,000 dialogues") + end + assert do + description.include?("knowledge-grounded") + end + end + end +end From 27913d3012561b9575e38ef25cf9d2b8182d7541 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 5 Nov 2025 12:20:07 +0900 Subject: [PATCH 02/17] feat: add new JMRD datasets to references --- README.md | 1 + example/jmrd.rb | 36 ++++++++++++++++++++++++++++++++++++ lib/datasets/lazy.rb | 1 + 3 files changed, 38 insertions(+) create mode 100755 example/jmrd.rb diff --git a/README.md b/README.md index a6120bb2..6788a1f0 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ You can use datasets easily because you can access each dataset with multiple wa * House of Councillors of Japan * House of Representatives of Japan * Iris Dataset +* JMRD (Japanese Movie Recommendation Dialogue Dataset) * Libsvm * MNIST database * Mushroom diff --git a/example/jmrd.rb b/example/jmrd.rb new file mode 100755 index 00000000..daf63a7f --- /dev/null +++ b/example/jmrd.rb @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby + +require 'datasets' + +jmrd = Datasets::JMRD.new(type: :train) + +jmrd.each do |dialogue| + puts "=" * 80 + puts "Dialogue ID: #{dialogue.dialog_id}" + puts "Movie: #{dialogue.movie_title}" + puts "First Speaker: #{dialogue.first_speaker}" + puts + + if dialogue.knowledge + puts "Knowledge:" + puts " Title: #{dialogue.knowledge.title}" + puts " Year: #{dialogue.knowledge.year}" + puts " Director: #{dialogue.knowledge.director_name}" + puts " Genres: #{dialogue.knowledge.genres.join(', ')}" if dialogue.knowledge.genres + puts + end + + puts "Dialogue:" + dialogue.utterances.each do |utterance| + speaker_label = utterance.speaker == "recommender" ? "[R]" : "[S]" + puts " #{speaker_label} #{utterance.text}" + + if utterance.checked_knowledge && !utterance.checked_knowledge.empty? + knowledge_types = utterance.checked_knowledge.map { |ck| ck.type }.join(", ") + puts " (knowledge: #{knowledge_types})" + end + end + + # Show only first dialogue as example + break +end diff --git a/lib/datasets/lazy.rb b/lib/datasets/lazy.rb index 204a240b..27351b96 100644 --- a/lib/datasets/lazy.rb +++ b/lib/datasets/lazy.rb @@ -61,6 +61,7 @@ def const_missing(name) LAZY_LOADER.register(:HouseOfRepresentative, "datasets/house-of-representative") LAZY_LOADER.register(:Iris, "datasets/iris") LAZY_LOADER.register(:ITACorpus, "datasets/ita-corpus") + LAZY_LOADER.register(:JMRD, "datasets/jmrd") LAZY_LOADER.register(:KuzushijiMNIST, "datasets/kuzushiji-mnist") LAZY_LOADER.register(:LIBSVM, "datasets/libsvm") LAZY_LOADER.register(:LIBSVMDatasetList, "datasets/libsvm-dataset-list") From a4f72fa8c7358fc9bd9a1316332d45a08fea2bc2 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Fri, 9 Jan 2026 13:41:45 +0900 Subject: [PATCH 03/17] feat: add RBS type definitions for JMRD dataset Add type signatures for JMRD class and its nested Struct types (Dialogue, Questionnaire, QuestionnaireAnswers, Knowledge, Utterance, CheckedKnowledge) --- sig/datasets/jmrd.rbs | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 sig/datasets/jmrd.rbs diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs new file mode 100644 index 00000000..7e652467 --- /dev/null +++ b/sig/datasets/jmrd.rbs @@ -0,0 +1,116 @@ +module Datasets + class JMRD < Dataset + class CheckedKnowledge < Struct[untyped] + attr_accessor type(): String? + attr_accessor content(): String? + + def initialize: (?String? type, ?String? content) -> void + end + + class Utterance < Struct[untyped] + attr_accessor utterance_id(): Integer? + attr_accessor speaker(): String? + attr_accessor text(): String? + attr_accessor checked_knowledge(): Array[CheckedKnowledge]? + + def initialize: ( + ?Integer? utterance_id, + ?String? speaker, + ?String? text, + ?Array[CheckedKnowledge]? checked_knowledge + ) -> void + end + + class Knowledge < Struct[untyped] + attr_accessor title(): String? + attr_accessor year(): Integer? + attr_accessor director_name(): String? + attr_accessor director_description(): String? + attr_accessor cast_names(): Array[String]? + attr_accessor cast_descriptions(): Array[String]? + attr_accessor genres(): Array[String]? + attr_accessor reviews(): Array[String]? + attr_accessor synopsis(): String? + + def initialize: ( + ?String? title, + ?Integer? year, + ?String? director_name, + ?String? director_description, + ?Array[String]? cast_names, + ?Array[String]? cast_descriptions, + ?Array[String]? genres, + ?Array[String]? reviews, + ?String? synopsis + ) -> void + end + + class QuestionnaireAnswers < Struct[untyped] + attr_accessor q1(): Integer? + attr_accessor q2(): Integer? + attr_accessor q3(): Integer? + attr_accessor q4(): Integer? + attr_accessor q5(): Integer? + + def initialize: ( + ?Integer? q1, + ?Integer? q2, + ?Integer? q3, + ?Integer? q4, + ?Integer? q5 + ) -> void + end + + class Questionnaire < Struct[untyped] + attr_accessor recommender(): QuestionnaireAnswers? + attr_accessor seeker(): QuestionnaireAnswers? + + def initialize: ( + ?QuestionnaireAnswers? recommender, + ?QuestionnaireAnswers? seeker + ) -> void + end + + class Dialogue < Struct[untyped] + attr_accessor dialog_id(): String? + attr_accessor movie_title(): String? + attr_accessor first_speaker(): String? + attr_accessor questionnaire(): Questionnaire? + attr_accessor knowledge(): Knowledge? + attr_accessor utterances(): Array[Utterance] + + def initialize: ( + ?String? dialog_id, + ?String? movie_title, + ?String? first_speaker, + ?Questionnaire? questionnaire, + ?Knowledge? knowledge, + ?Array[Utterance] utterances + ) -> void + end + + @type: Symbol + @metadata: Metadata + + def initialize: (?type: Symbol) -> void + + def each: () { (Dialogue) -> void } -> void + | () -> Enumerator[Dialogue, void] + + private + + def open_data: () { (Array[Hash[String, untyped]]) -> void } -> void + + def parse_dialogue: (Hash[String, untyped] data) -> Dialogue + + def parse_questionnaire: (Hash[String, untyped]? data) -> Questionnaire? + + def parse_questionnaire_answers: (Hash[String, untyped]? data) -> QuestionnaireAnswers? + + def parse_knowledge: (Hash[String, untyped]? data) -> Knowledge? + + def parse_utterances: (Array[Hash[String, untyped]]? data) -> Array[Utterance] + + def parse_utterance: (Hash[String, untyped] data) -> Utterance + end +end From 762411f4547e27487071bf068e52b695fd469644 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Mon, 30 Mar 2026 15:38:32 +0900 Subject: [PATCH 04/17] fix: change some type to appropriate --- sig/datasets/jmrd.rbs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index 7e652467..22fb64b3 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -8,13 +8,13 @@ module Datasets end class Utterance < Struct[untyped] - attr_accessor utterance_id(): Integer? + attr_accessor utterance_id(): String? attr_accessor speaker(): String? attr_accessor text(): String? attr_accessor checked_knowledge(): Array[CheckedKnowledge]? def initialize: ( - ?Integer? utterance_id, + ?String? utterance_id, ?String? speaker, ?String? text, ?Array[CheckedKnowledge]? checked_knowledge @@ -23,25 +23,25 @@ module Datasets class Knowledge < Struct[untyped] attr_accessor title(): String? - attr_accessor year(): Integer? + attr_accessor year(): String? attr_accessor director_name(): String? attr_accessor director_description(): String? attr_accessor cast_names(): Array[String]? attr_accessor cast_descriptions(): Array[String]? attr_accessor genres(): Array[String]? attr_accessor reviews(): Array[String]? - attr_accessor synopsis(): String? + attr_accessor synopsis(): Array[String]? def initialize: ( ?String? title, - ?Integer? year, + ?String? year, ?String? director_name, ?String? director_description, ?Array[String]? cast_names, ?Array[String]? cast_descriptions, ?Array[String]? genres, ?Array[String]? reviews, - ?String? synopsis + ?Array[String]? synopsis ) -> void end From a0742a613ae73dd2f2b28ac9c0091d933404e810 Mon Sep 17 00:00:00 2001 From: Eriko Sugiyama <40660382+ericgpks@users.noreply.github.com> Date: Wed, 1 Apr 2026 18:41:04 +0900 Subject: [PATCH 05/17] fix: change error message to align with others --- lib/datasets/jmrd.rb | 2 +- test/test-jmrd.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index d1eb38ed..cae2822b 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -77,7 +77,7 @@ def initialize(type: :train) DESCRIPTION unless [:train, :valid, :test].include?(type) - raise ArgumentError, "Type must be :train, :valid, or :test: #{type.inspect}" + raise ArgumentError, ":type must be one of [:train, :valid, :test]: #{type.inspect}" end @type = type end diff --git a/test/test-jmrd.rb b/test/test-jmrd.rb index 0ddb8a18..0023636b 100644 --- a/test/test-jmrd.rb +++ b/test/test-jmrd.rb @@ -57,7 +57,7 @@ class JMRDTest < Test::Unit::TestCase end test("invalid") do - message = "Type must be :train, :valid, or :test: :invalid" + message = ":type must be one of [:train, :valid, :test]: :invalid" assert_raise(ArgumentError.new(message)) do Datasets::JMRD.new(type: :invalid) end From e7b52d4fcfacee70fa3456ca5160dfda49401de2 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 20 May 2026 23:21:35 +0900 Subject: [PATCH 06/17] fix: change some grammar for readable --- example/jmrd.rb | 2 +- lib/datasets/jmrd.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/jmrd.rb b/example/jmrd.rb index daf63a7f..ccdfcebe 100755 --- a/example/jmrd.rb +++ b/example/jmrd.rb @@ -25,7 +25,7 @@ speaker_label = utterance.speaker == "recommender" ? "[R]" : "[S]" puts " #{speaker_label} #{utterance.text}" - if utterance.checked_knowledge && !utterance.checked_knowledge.empty? + if utterance.checked_knowledge.any? knowledge_types = utterance.checked_knowledge.map { |ck| ck.type }.join(", ") puts " (knowledge: #{knowledge_types})" end diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index cae2822b..549c6871 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -115,7 +115,7 @@ def parse_dialogue(data) end def parse_questionnaire(data) - return nil if data.nil? + return if data.nil? Questionnaire.new( parse_questionnaire_answers(data["recommender"]), From aa031dbabf01d9d4faa8d2dd1940f8bba1778240 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 20 May 2026 23:28:49 +0900 Subject: [PATCH 07/17] fix: change some grammar for readable --- example/jmrd.rb | 2 +- lib/datasets/jmrd.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/jmrd.rb b/example/jmrd.rb index daf63a7f..7ed94321 100755 --- a/example/jmrd.rb +++ b/example/jmrd.rb @@ -25,7 +25,7 @@ speaker_label = utterance.speaker == "recommender" ? "[R]" : "[S]" puts " #{speaker_label} #{utterance.text}" - if utterance.checked_knowledge && !utterance.checked_knowledge.empty? + if utterance.checked_knowledge&.any? knowledge_types = utterance.checked_knowledge.map { |ck| ck.type }.join(", ") puts " (knowledge: #{knowledge_types})" end diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index cae2822b..549c6871 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -115,7 +115,7 @@ def parse_dialogue(data) end def parse_questionnaire(data) - return nil if data.nil? + return if data.nil? Questionnaire.new( parse_questionnaire_answers(data["recommender"]), From d2ee335625a4eb151aada3edcd7412a463791738 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Thu, 4 Jun 2026 20:31:16 +0900 Subject: [PATCH 08/17] fix: update method name to appropriate behavior --- lib/datasets/jmrd.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index 549c6871..ea1dca8c 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -87,7 +87,7 @@ def each open_data do |json_data| json_data.each do |dialogue_data| - yield parse_dialogue(dialogue_data) + yield build_dialogue(dialogue_data) end end end @@ -103,7 +103,7 @@ def open_data yield json_data end - def parse_dialogue(data) + def build_dialogue(data) Dialogue.new( data["dialog_id"], data["movie_title"], From f41e9183059a53f310942f87e681cb92bedae2fe Mon Sep 17 00:00:00 2001 From: ericgpks Date: Sat, 20 Jun 2026 22:49:49 +0900 Subject: [PATCH 09/17] fix: change to use parse_checked_knowledge like other dataset related to j,rd this is good for readable --- lib/datasets/jmrd.rb | 9 ++++++++- sig/datasets/jmrd.rbs | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index ea1dca8c..3d921623 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -159,11 +159,18 @@ def parse_utterances(data) end end + def parse_checked_knowledge(data) + CheckedKnowledge.new( + data["type"], + data["content"] + ) + end + def parse_utterance(data) checked_knowledge = nil if data["checked_knowledge"] checked_knowledge = data["checked_knowledge"].map do |ck| - CheckedKnowledge.new(ck["type"], ck["content"]) + parse_checked_knowledge(ck) end end diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index 22fb64b3..466fc154 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -111,6 +111,8 @@ module Datasets def parse_utterances: (Array[Hash[String, untyped]]? data) -> Array[Utterance] + def parse_checked_knowledge: (Hash[String, untyped] data) -> CheckedKnowledge + def parse_utterance: (Hash[String, untyped] data) -> Utterance end end From 18f3269cfc424594e6c961e92a97c308279b9213 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Sun, 21 Jun 2026 23:43:06 +0900 Subject: [PATCH 10/17] fix: change to use one assertion to align with other test classes --- test/test-jmrd.rb | 174 ++++++++++++++++++++++++++++------------------ 1 file changed, 108 insertions(+), 66 deletions(-) diff --git a/test/test-jmrd.rb b/test/test-jmrd.rb index 0023636b..bf55dcea 100644 --- a/test/test-jmrd.rb +++ b/test/test-jmrd.rb @@ -1,62 +1,65 @@ class JMRDTest < Test::Unit::TestCase - sub_test_case("type") do - test("train") do - dataset = Datasets::JMRD.new(type: :train) - dialogues = dataset.to_a - - assert_equal(4575, dialogues.size) - - first_dialogue = dialogues[0] - assert_equal("01884", first_dialogue.dialog_id) - assert_equal("時をかける少女", first_dialogue.movie_title) - assert_equal("recommender", first_dialogue.first_speaker) - - # Check questionnaire - assert_not_nil(first_dialogue.questionnaire) - assert_equal(5, first_dialogue.questionnaire.recommender.q1) - assert_equal(4, first_dialogue.questionnaire.seeker.q1) - - # Check knowledge - assert_not_nil(first_dialogue.knowledge) - assert_equal("時をかける少女", first_dialogue.knowledge.title) - assert_equal("2006年", first_dialogue.knowledge.year) - assert_equal("細田守", first_dialogue.knowledge.director_name) - - # Check utterances - assert_equal(26, first_dialogue.utterances.size) - assert_equal("01884_00", first_dialogue.utterances[0].utterance_id) - assert_equal("recommender", first_dialogue.utterances[0].speaker) - assert_equal("こんにちは", first_dialogue.utterances[0].text) - assert_not_nil(first_dialogue.utterances[0].checked_knowledge) - assert_equal(1, first_dialogue.utterances[0].checked_knowledge.size) - assert_equal("[知識なし]", first_dialogue.utterances[0].checked_knowledge[0].type) + sub_test_case("train") do + def setup + @dataset = Datasets::JMRD.new(type: :train) end - test("valid") do - dataset = Datasets::JMRD.new(type: :valid) - dialogues = dataset.to_a - - assert_equal(200, dialogues.size) + test("#each") do + assert_equal({ + :dialogue_size => 4575, + :dialog_id => "01884", + :movie_title => "時をかける少女", + :first_speaker => "recommender", + :recommender_q1 => 5, + :seeker_q1 => 4, + :knowledge_title => "時をかける少女", + :knowledge_year => "2006年", + :director_name => "細田守", + :utterance_size => 26, + :utterance_id => "01884_00", + :utterance_speaker => "recommender", + :utterance_text => "こんにちは", + :checked_knowledge_size => 1, + :checked_knowledge_type => "[知識なし]", + }, + first_dialogue_summary(@dataset.to_a)) + end + end - first_dialogue = dialogues[0] - assert_not_nil(first_dialogue.dialog_id) - assert_not_nil(first_dialogue.movie_title) - assert(["recommender", "seeker"].include?(first_dialogue.first_speaker)) + sub_test_case("valid") do + def setup + @dataset = Datasets::JMRD.new(type: :valid) end - test("test") do - dataset = Datasets::JMRD.new(type: :test) - dialogues = dataset.to_a + test("#each") do + assert_equal({ + :dialogue_size => 200, + :has_dialog_id => true, + :has_movie_title => true, + :valid_first_speaker => true, + }, + dialogue_summary(@dataset.to_a)) + end + end - assert_equal(300, dialogues.size) + sub_test_case("test") do + def setup + @dataset = Datasets::JMRD.new(type: :test) + end - first_dialogue = dialogues[0] - assert_not_nil(first_dialogue.dialog_id) - assert_not_nil(first_dialogue.movie_title) - assert(["recommender", "seeker"].include?(first_dialogue.first_speaker)) + test("#each") do + assert_equal({ + :dialogue_size => 300, + :has_dialog_id => true, + :has_movie_title => true, + :valid_first_speaker => true, + }, + dialogue_summary(@dataset.to_a)) end + end - test("invalid") do + sub_test_case("invalid type") do + test("raises error") do message = ":type must be one of [:train, :valid, :test]: :invalid" assert_raise(ArgumentError.new(message)) do Datasets::JMRD.new(type: :invalid) @@ -65,40 +68,79 @@ class JMRDTest < Test::Unit::TestCase end sub_test_case("#metadata") do + def setup + @dataset = Datasets::JMRD.new(type: :train) + end + test("#id") do - dataset = Datasets::JMRD.new(type: :train) - assert_equal("jmrd", dataset.metadata.id) + assert_equal("jmrd", @dataset.metadata.id) end test("#name") do - dataset = Datasets::JMRD.new(type: :train) assert_equal("Japanese Movie Recommendation Dialogue Dataset (JMRD)", - dataset.metadata.name) + @dataset.metadata.name) end test("#url") do - dataset = Datasets::JMRD.new(type: :train) - assert_equal("https://github.com/ku-nlp/JMRD", dataset.metadata.url) + assert_equal("https://github.com/ku-nlp/JMRD", @dataset.metadata.url) end test("#licenses") do - dataset = Datasets::JMRD.new(type: :train) assert_equal([Datasets::License.new("CC-BY-SA-4.0")], - dataset.metadata.licenses) + @dataset.metadata.licenses) end test("#description") do - dataset = Datasets::JMRD.new(type: :train) - description = dataset.metadata.description - assert do - description.include?("Japanese Movie Recommendation Dialogue Dataset") - end - assert do - description.include?("5,000 dialogues") - end + description = @dataset.metadata.description assert do - description.include?("knowledge-grounded") + [ + "Japanese Movie Recommendation Dialogue Dataset", + "5,000 dialogues", + "knowledge-grounded", + ].all? do |phrase| + description.include?(phrase) + end end end end + + private + + def dialogue_summary(dialogues) + first_dialogue = dialogues[0] + { + :dialogue_size => dialogues.size, + :has_dialog_id => !first_dialogue.dialog_id.nil?, + :has_movie_title => !first_dialogue.movie_title.nil?, + :valid_first_speaker => valid_speaker?(first_dialogue.first_speaker), + } + end + + def valid_speaker?(speaker) + ["recommender", "seeker"].include?(speaker) + end + + def first_dialogue_summary(dialogues) + first_dialogue = dialogues[0] + first_utterance = first_dialogue.utterances[0] + first_checked_knowledge = first_utterance.checked_knowledge[0] + + { + :dialogue_size => dialogues.size, + :dialog_id => first_dialogue.dialog_id, + :movie_title => first_dialogue.movie_title, + :first_speaker => first_dialogue.first_speaker, + :recommender_q1 => first_dialogue.questionnaire.recommender.q1, + :seeker_q1 => first_dialogue.questionnaire.seeker.q1, + :knowledge_title => first_dialogue.knowledge.title, + :knowledge_year => first_dialogue.knowledge.year, + :director_name => first_dialogue.knowledge.director_name, + :utterance_size => first_dialogue.utterances.size, + :utterance_id => first_utterance.utterance_id, + :utterance_speaker => first_utterance.speaker, + :utterance_text => first_utterance.text, + :checked_knowledge_size => first_utterance.checked_knowledge.size, + :checked_knowledge_type => first_checked_knowledge.type, + } + end end From c449a0c05e83a9e41839e9329bfdcb3546affd9a Mon Sep 17 00:00:00 2001 From: ericgpks Date: Tue, 23 Jun 2026 22:35:51 +0900 Subject: [PATCH 11/17] fix: change order to raise error earlier --- lib/datasets/jmrd.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index 3d921623..ecc05f28 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -51,6 +51,10 @@ class JMRD < Dataset ) def initialize(type: :train) + unless [:train, :valid, :test].include?(type) + raise ArgumentError, ":type must be one of [:train, :valid, :test]: #{type.inspect}" + end + super() @metadata.id = "jmrd" @metadata.name = "Japanese Movie Recommendation Dialogue Dataset (JMRD)" @@ -76,9 +80,6 @@ def initialize(type: :train) Dialogue Dataset and Dialogue System." DESCRIPTION - unless [:train, :valid, :test].include?(type) - raise ArgumentError, ":type must be one of [:train, :valid, :test]: #{type.inspect}" - end @type = type end From 2c7fd70f57c38ff99db55537d3f4d3ca0b9c5b35 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Sun, 5 Jul 2026 22:48:55 +0900 Subject: [PATCH 12/17] =?UTF-8?q?fix:=20change=20to=20include=20=E7=9F=A5?= =?UTF-8?q?=E8=AD=98=E3=81=AA=E3=81=97=20as=20a=20part=20of=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/datasets/jmrd.rb | 17 +++++++++++++++-- sig/datasets/jmrd.rbs | 1 + test/test-jmrd.rb | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index ecc05f28..63d0164e 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -36,7 +36,18 @@ class JMRD < Dataset :genres, :reviews, :synopsis - ) + ) do + attr_accessor :no_knowledge + + define_method("[知識なし]") { no_knowledge } + define_method("タイトル") { title } + define_method("製作年度") { year } + define_method("監督") { [director_name, director_description] } + define_method("キャスト") { [cast_names, cast_descriptions] } + define_method("ジャンル") { genres } + define_method("レビュー") { reviews } + define_method("あらすじ") { synopsis } + end Utterance = Struct.new( :utterance_id, @@ -139,7 +150,7 @@ def parse_questionnaire_answers(data) def parse_knowledge(data) return nil if data.nil? - Knowledge.new( + knowledge = Knowledge.new( data["タイトル"], data["製作年度"], data["監督名"], @@ -150,6 +161,8 @@ def parse_knowledge(data) data["レビュー"], data["あらすじ"] ) + knowledge.no_knowledge = data["[知識なし]"] + knowledge end def parse_utterances(data) diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index 466fc154..3e826f88 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -22,6 +22,7 @@ module Datasets end class Knowledge < Struct[untyped] + attr_accessor no_knowledge(): String? attr_accessor title(): String? attr_accessor year(): String? attr_accessor director_name(): String? diff --git a/test/test-jmrd.rb b/test/test-jmrd.rb index bf55dcea..80eff32b 100644 --- a/test/test-jmrd.rb +++ b/test/test-jmrd.rb @@ -24,6 +24,23 @@ def setup }, first_dialogue_summary(@dataset.to_a)) end + + test("knowledge has checked knowledge types") do + assert do + @dataset.all? do |dialogue| + dialogue.utterances.all? do |utterance| + Array(utterance.checked_knowledge).all? do |checked_knowledge| + dialogue.knowledge.respond_to?(checked_knowledge.type) + end + end + end + end + end + + test("knowledge keeps no knowledge option") do + dialogue = @dataset.first + assert_equal("[知識なし]", dialogue.knowledge.no_knowledge) + end end sub_test_case("valid") do From a23924c325f853e0075c20e13a0b314efdee9114 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Mon, 6 Jul 2026 22:28:43 +0900 Subject: [PATCH 13/17] fix: remove trailing whitespace --- example/jmrd.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/jmrd.rb b/example/jmrd.rb index 8faf90be..7ed94321 100755 --- a/example/jmrd.rb +++ b/example/jmrd.rb @@ -24,7 +24,7 @@ dialogue.utterances.each do |utterance| speaker_label = utterance.speaker == "recommender" ? "[R]" : "[S]" puts " #{speaker_label} #{utterance.text}" - + if utterance.checked_knowledge&.any? knowledge_types = utterance.checked_knowledge.map { |ck| ck.type }.join(", ") puts " (knowledge: #{knowledge_types})" From 15d71b9abbabc061995789ac438aca757204a8e6 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Tue, 7 Jul 2026 22:53:59 +0900 Subject: [PATCH 14/17] fix: rename method from parse_* to build_* as a appropriate name --- lib/datasets/jmrd.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index 63d0164e..a0b873d2 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -120,22 +120,22 @@ def build_dialogue(data) data["dialog_id"], data["movie_title"], data["first_speaker"], - parse_questionnaire(data["questionnaire"]), - parse_knowledge(data["knowledge"]), - parse_utterances(data["dialog"]) + build_questionnaire(data["questionnaire"]), + build_knowledge(data["knowledge"]), + build_utterances(data["dialog"]) ) end - def parse_questionnaire(data) + def build_questionnaire(data) return if data.nil? Questionnaire.new( - parse_questionnaire_answers(data["recommender"]), - parse_questionnaire_answers(data["seeker"]) + build_questionnaire_answers(data["recommender"]), + build_questionnaire_answers(data["seeker"]) ) end - def parse_questionnaire_answers(data) + def build_questionnaire_answers(data) return nil if data.nil? QuestionnaireAnswers.new( @@ -147,7 +147,7 @@ def parse_questionnaire_answers(data) ) end - def parse_knowledge(data) + def build_knowledge(data) return nil if data.nil? knowledge = Knowledge.new( @@ -165,26 +165,26 @@ def parse_knowledge(data) knowledge end - def parse_utterances(data) + def build_utterances(data) return [] if data.nil? data.map do |utterance_data| - parse_utterance(utterance_data) + build_utterance(utterance_data) end end - def parse_checked_knowledge(data) + def build_checked_knowledge(data) CheckedKnowledge.new( data["type"], data["content"] ) end - def parse_utterance(data) + def build_utterance(data) checked_knowledge = nil if data["checked_knowledge"] checked_knowledge = data["checked_knowledge"].map do |ck| - parse_checked_knowledge(ck) + build_checked_knowledge(ck) end end From 845abeb0ce05c7832451bad4847c6ca8d9e92035 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 8 Jul 2026 22:30:42 +0900 Subject: [PATCH 15/17] fix: change to no_knowledge as an item as others --- lib/datasets/jmrd.rb | 19 ++++--------------- sig/datasets/jmrd.rbs | 1 + test/test-jmrd.rb | 12 ------------ 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/lib/datasets/jmrd.rb b/lib/datasets/jmrd.rb index a0b873d2..bc9a5314 100644 --- a/lib/datasets/jmrd.rb +++ b/lib/datasets/jmrd.rb @@ -27,6 +27,7 @@ class JMRD < Dataset ) Knowledge = Struct.new( + :no_knowledge, :title, :year, :director_name, @@ -36,18 +37,7 @@ class JMRD < Dataset :genres, :reviews, :synopsis - ) do - attr_accessor :no_knowledge - - define_method("[知識なし]") { no_knowledge } - define_method("タイトル") { title } - define_method("製作年度") { year } - define_method("監督") { [director_name, director_description] } - define_method("キャスト") { [cast_names, cast_descriptions] } - define_method("ジャンル") { genres } - define_method("レビュー") { reviews } - define_method("あらすじ") { synopsis } - end + ) Utterance = Struct.new( :utterance_id, @@ -150,7 +140,8 @@ def build_questionnaire_answers(data) def build_knowledge(data) return nil if data.nil? - knowledge = Knowledge.new( + Knowledge.new( + data["[知識なし]"], data["タイトル"], data["製作年度"], data["監督名"], @@ -161,8 +152,6 @@ def build_knowledge(data) data["レビュー"], data["あらすじ"] ) - knowledge.no_knowledge = data["[知識なし]"] - knowledge end def build_utterances(data) diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index 3e826f88..17bab74a 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -34,6 +34,7 @@ module Datasets attr_accessor synopsis(): Array[String]? def initialize: ( + ?String? no_knowledge, ?String? title, ?String? year, ?String? director_name, diff --git a/test/test-jmrd.rb b/test/test-jmrd.rb index 80eff32b..82d1c45b 100644 --- a/test/test-jmrd.rb +++ b/test/test-jmrd.rb @@ -25,18 +25,6 @@ def setup first_dialogue_summary(@dataset.to_a)) end - test("knowledge has checked knowledge types") do - assert do - @dataset.all? do |dialogue| - dialogue.utterances.all? do |utterance| - Array(utterance.checked_knowledge).all? do |checked_knowledge| - dialogue.knowledge.respond_to?(checked_knowledge.type) - end - end - end - end - end - test("knowledge keeps no knowledge option") do dialogue = @dataset.first assert_equal("[知識なし]", dialogue.knowledge.no_knowledge) From d6f37ff9b10ba3399871c171d40783952275be27 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 8 Jul 2026 22:56:36 +0900 Subject: [PATCH 16/17] fix: change rbs file to align with actual method name --- sig/datasets/jmrd.rbs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index 17bab74a..f8dc09d4 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -103,18 +103,18 @@ module Datasets def open_data: () { (Array[Hash[String, untyped]]) -> void } -> void - def parse_dialogue: (Hash[String, untyped] data) -> Dialogue + def build_dialogue: (Hash[String, untyped] data) -> Dialogue - def parse_questionnaire: (Hash[String, untyped]? data) -> Questionnaire? + def build_questionnaire: (Hash[String, untyped]? data) -> Questionnaire? - def parse_questionnaire_answers: (Hash[String, untyped]? data) -> QuestionnaireAnswers? + def build_questionnaire_answers: (Hash[String, untyped]? data) -> QuestionnaireAnswers? - def parse_knowledge: (Hash[String, untyped]? data) -> Knowledge? + def build_knowledge: (Hash[String, untyped]? data) -> Knowledge? - def parse_utterances: (Array[Hash[String, untyped]]? data) -> Array[Utterance] + def build_utterances: (Array[Hash[String, untyped]]? data) -> Array[Utterance] - def parse_checked_knowledge: (Hash[String, untyped] data) -> CheckedKnowledge + def build_checked_knowledge: (Hash[String, untyped] data) -> CheckedKnowledge - def parse_utterance: (Hash[String, untyped] data) -> Utterance + def build_utterance: (Hash[String, untyped] data) -> Utterance end end From 192759d96d738ca849b2bf8dd0aff1bf0a524df5 Mon Sep 17 00:00:00 2001 From: ericgpks Date: Wed, 8 Jul 2026 23:20:03 +0900 Subject: [PATCH 17/17] fix: change rbs definition to show the actual behavior that the value can not be nil --- sig/datasets/jmrd.rbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sig/datasets/jmrd.rbs b/sig/datasets/jmrd.rbs index f8dc09d4..96fb1b3e 100644 --- a/sig/datasets/jmrd.rbs +++ b/sig/datasets/jmrd.rbs @@ -87,7 +87,7 @@ module Datasets ?String? first_speaker, ?Questionnaire? questionnaire, ?Knowledge? knowledge, - ?Array[Utterance] utterances + Array[Utterance] utterances ) -> void end