File size: 4,228 Bytes
7a79e04
 
 
 
10eac7e
7a79e04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90dc507
7a79e04
 
 
 
 
 
 
 
1532ad8
7a79e04
 
90dc507
7a79e04
 
 
 
 
9cf65c6
 
 
 
 
 
 
 
7a79e04
 
 
 
 
 
1532ad8
7a79e04
 
 
 
 
 
 
1532ad8
7a79e04
 
 
 
 
 
 
9cf65c6
7a79e04
 
 
 
 
 
 
1532ad8
7a79e04
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
defmodule MedicalTranscription.CodingTest do
  use MedicalTranscription.DataCase

  alias MedicalTranscription.Coding
  alias MedicalTranscription.Coding.CodeVector
  alias MedicalTranscription.Feedback.CodeFeedback

  def create_code_vector!(code, description) do
    description_vector = Coding.compute_vector_as_list(description)

    changeset =
      CodeVector.changeset(%CodeVector{}, %{
        code: code,
        description: description,
        description_vector: description_vector
      })

    Repo.insert!(changeset)
  end

  def create_code_feedback!(text, response, for_code) do
    code_vector = Repo.one(from v in CodeVector, where: v.code == ^for_code)
    text_vector = Coding.compute_vector_as_list(text)

    changeset =
      CodeFeedback.changeset(%CodeFeedback{}, %{
        text: text,
        text_vector: text_vector,
        response: response,
        code_vector_id: code_vector.id
      })

    Repo.insert!(changeset)
  end

  describe "process_chunk/2" do
    setup do
      create_code_vector!("74685", "Coronary artery anomaly")
      create_code_vector!("41412", "Dissection of coronary artery")
      create_code_vector!("V717", "Observation for suspected cardiovascular disease")
      create_code_vector!("V812", "Screening for other and unspecified cardiovascular conditions")
      create_code_vector!("V4589", "Other postprocedural status")

      :ok
    end

    @input_text "This 55-year-old man with known coronary artery disease comes for a follow-up visit today."
    @feedback_text "A 42-year-old man arrived for a return check-up who had a past history of coronary artery disease."

    test "Codes can be weighted multiple times when multiple prior feedback items exist for a single code" do
      # One negative feedback item moves the code from 1st to 4th (x0.9).
      # The net result of 2 negative and 1 positive (x0.891) is to remove the code from the results.
      create_code_feedback!(@feedback_text, false, "74685")
      create_code_feedback!(@feedback_text, true, "74685")
      create_code_feedback!(@feedback_text, false, "74685")
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["41412", "V717", "V812"]
      assert Enum.all?(results, &(&1.weighting == [:none]))
    end

    test "Weighting can cause codes to appear in results that wouldn't have been included from the initial similarity query" do
      # E.g. weighting up a code that isn't in the initial results
      create_code_feedback!(@feedback_text, true, "V4589")
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812", "V4589"]

      assert Enum.map(results, & &1.weighting) == [
               [:none],
               [:none],
               [:none],
               [:none],
               [:positive]
             ]
    end

    test "Codes are unweighted when no prior feedback" do
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["74685", "41412", "V717", "V812"]
      assert Enum.all?(results, &(&1.weighting == [:none]))
    end

    test "Code is ranked higher when prior positive feedback" do
      create_code_feedback!(@feedback_text, true, "V717")
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["V717", "74685", "41412", "V812"]
      assert Enum.map(results, & &1.weighting) == [[:positive], [:none], [:none], [:none]]
    end

    test "Code is ranked lower when prior negative feedback" do
      create_code_feedback!(@feedback_text, false, "74685")
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["41412", "V717", "V812", "74685"]
      assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none], [:negative]]
    end

    test "Code with low similarity score is removed from result when prior negative feedback" do
      create_code_feedback!(@feedback_text, false, "V717")
      results = Coding.process_chunk(@input_text)

      assert Enum.map(results, & &1.code) == ["74685", "41412", "V812"]
      assert Enum.map(results, & &1.weighting) == [[:none], [:none], [:none]]
    end
  end
end