{"id":884,"date":"2018-04-08T05:05:45","date_gmt":"2018-04-08T05:05:45","guid":{"rendered":"http:\/\/www.rangakrish.com\/?p=884"},"modified":"2018-04-10T15:44:35","modified_gmt":"2018-04-10T10:14:35","slug":"natural-language-generation","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/","title":{"rendered":"Natural Language Generation"},"content":{"rendered":"<p>I had written a series of posts on my <a href=\"http:\/\/www.rangakrish.com\/index.php\/2017\/08\/06\/text-generation-using-ilanggen-framework\/\" target=\"_blank\" rel=\"noopener\"><em><strong>iLangGen<\/strong><\/em><\/a> framework last year. It aims to provide a flexible and expressive approach for building natural language generation systems. In today&#8217;s post, I would like to describe a concrete example of how <em><strong>iLangGen<\/strong><\/em> can be used for generating natural language text from structured data, aided by a convenient template text.<\/p>\n<p>Here is the scenario. There is a pathology laboratory called <em><strong>XYZ Diagnostic &amp; Scan Centre<\/strong><\/em>, which provides high-quality pathology services to the public. For example, it takes blood samples from patients and analyzes them under a controlled environment. Once the processing is complete, it is scrutinized by an in-house specialist, and the results are emailed to respective patients. Instead of merely printing a table of test names and results, <em><strong>XYZ Lab<\/strong><\/em> wants to make this more user-friendly by sending a personalized email that contains paraphrased data.<\/p>\n<p>Let us see how we can do this. The overall approach is depicted in the following diagram.<\/p>\n<figure id=\"attachment_904\" aria-describedby=\"caption-attachment-904\" style=\"width: 493px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" data-attachment-id=\"904\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/overall-2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png\" data-orig-size=\"493,371\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Overall Approach\" data-image-description=\"&lt;p&gt;Overall Approach&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Overall Approach&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png\" class=\"size-full wp-image-904\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png?resize=493%2C371\" alt=\"Overall Approach\" width=\"493\" height=\"371\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png?w=493&amp;ssl=1 493w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/overall-1.png?resize=300%2C226&amp;ssl=1 300w\" sizes=\"(max-width: 493px) 100vw, 493px\" \/><\/a><figcaption id=\"caption-attachment-904\" class=\"wp-caption-text\"><strong>Overall Approach<\/strong><\/figcaption><\/figure>\n<p>The NLG application takes three inputs namely, a Template text file, a Grammar file and patient Database. It interacts with <em><strong>iLangGen<\/strong><\/em> passing the grammar file and additional context information, and subject to the overall structure of the template file, generates complete text for each database record.<\/p>\n<p>First, here is the actual data (the data is stored as a CSV file for this demo):<\/p>\n<figure id=\"attachment_886\" aria-describedby=\"caption-attachment-886\" style=\"width: 372px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"886\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/patient-data\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png\" data-orig-size=\"372,171\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Patient Data\" data-image-description=\"&lt;p&gt;Patient Data&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Patient Data&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png\" class=\"size-full wp-image-886\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png?resize=372%2C171\" alt=\"Patient Data\" width=\"372\" height=\"171\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png?w=372&amp;ssl=1 372w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Patient-data.png?resize=300%2C138&amp;ssl=1 300w\" sizes=\"(max-width: 372px) 100vw, 372px\" \/><\/a><figcaption id=\"caption-attachment-886\" class=\"wp-caption-text\"><strong>Patient Data<\/strong><\/figcaption><\/figure>\n<p>Since this is just a demo, I have deliberately chosen a limited number of fields and records.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>We use a template text to give us the overall structure of generated text. Here is the text we will use for this example:<\/p>\n<figure id=\"attachment_887\" aria-describedby=\"caption-attachment-887\" style=\"width: 651px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"887\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/letter-template\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png\" data-orig-size=\"773,278\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Letter Template\" data-image-description=\"&lt;p&gt;Letter Template&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Letter Template&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png\" class=\"wp-image-887\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png?resize=651%2C234\" alt=\"Letter Template\" width=\"651\" height=\"234\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png?w=773&amp;ssl=1 773w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png?resize=300%2C108&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Letter-Template.png?resize=768%2C276&amp;ssl=1 768w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><figcaption id=\"caption-attachment-887\" class=\"wp-caption-text\"><strong>Letter Template<\/strong><\/figcaption><\/figure>\n<p>Notice the sections appearing within the delimiters <em><strong>{{<\/strong><\/em> and <em><strong>}}<\/strong><\/em>. Each such section has the format <strong>&lt;GrammarName::Non-TerminalName&gt;<\/strong> and is used by the application to guide <em><strong>iLangGen<\/strong><\/em> in generating appropriate text <em><strong>dynamicaly<\/strong><\/em>. The remaining text will be retained as it is. More on this later.<\/p>\n<p>Here is the grammar part:<\/p>\n<figure id=\"attachment_888\" aria-describedby=\"caption-attachment-888\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"888\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/grammar\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png\" data-orig-size=\"818,522\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"The Grammar\" data-image-description=\"&lt;p&gt;The Grammar&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;The Grammar&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png\" class=\"wp-image-888\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png?resize=650%2C415\" alt=\"The Grammar\" width=\"650\" height=\"415\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png?w=818&amp;ssl=1 818w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png?resize=300%2C191&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png?resize=768%2C490&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Grammar.png?resize=140%2C90&amp;ssl=1 140w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/a><figcaption id=\"caption-attachment-888\" class=\"wp-caption-text\"><strong>The Grammar<\/strong><\/figcaption><\/figure>\n<p>There are two grammars: <em><strong>CommonServices<\/strong><\/em> exists to provide greeting messages (could be<span class=\"Apple-converted-space\">\u00a0<\/span>enhanced later) and is inherited by <em><strong>PathologyGrammar<\/strong><\/em>. The latter contains the core logic for generating text customized for each patient. The function <em><strong>sequentially-one<\/strong><\/em> on the RHS of the rules returns one value from its list in the same order, each time it is called. When the last element has been fetched, it starts from the first element again. So, for example, the first time the non-terminal <em><strong>checked<\/strong><\/em> is visited, it returns <em><strong>checked<\/strong><\/em>. Next time, it returns <em><strong>reviewed<\/strong><\/em>, and so on. The fifth time it is called, it returns <em><strong>checked<\/strong><\/em> once again and the cycle starts. Thus, this function is useful if we desire guaranteed variation across consecutive generations. The other function <em><strong>randomly-one<\/strong><\/em>, used in <em><strong>CommonServices<\/strong><\/em>, returns one from its list of elements in random order. It is possible that this returns the same element across consecutive calls. We can choose either of the two functions depending on our requirement.<\/p>\n<p>The function <em><strong>greet<\/strong><\/em> used in <em><strong>CommonServices<\/strong><\/em> emits the string <em><strong>Mr.<\/strong><\/em> or <em><strong>Ms.<\/strong><\/em> depending on the gender of the person denoted by the current data record.<\/p>\n<figure id=\"attachment_889\" aria-describedby=\"caption-attachment-889\" style=\"width: 397px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"889\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/greet-function\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png\" data-orig-size=\"397,177\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Greet Function\" data-image-description=\"&lt;p&gt;The Grammar&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;The Grammar&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png\" class=\"size-full wp-image-889\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png?resize=397%2C177\" alt=\"The Grammar\" width=\"397\" height=\"177\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png?w=397&amp;ssl=1 397w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/greet-function.png?resize=300%2C134&amp;ssl=1 300w\" sizes=\"(max-width: 397px) 100vw, 397px\" \/><\/a><figcaption id=\"caption-attachment-889\" class=\"wp-caption-text\"><strong>Greet Function<\/strong><\/figcaption><\/figure>\n<p>Synthesizing text for haemoglobin value is handled by the function <em><strong>get-haemoglobin-text<\/strong><\/em>.<\/p>\n<figure id=\"attachment_890\" aria-describedby=\"caption-attachment-890\" style=\"width: 567px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"890\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/get-hemoglobin\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png\" data-orig-size=\"567,192\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Haemoglobin Text\" data-image-description=\"&lt;p&gt;Haemoglobin Text&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Haemoglobin Text&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png\" class=\"size-full wp-image-890\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png?resize=567%2C192\" alt=\"Haemoglobin Text\" width=\"567\" height=\"192\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png?w=567&amp;ssl=1 567w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-hemoglobin.png?resize=300%2C102&amp;ssl=1 300w\" sizes=\"(max-width: 567px) 100vw, 567px\" \/><\/a><figcaption id=\"caption-attachment-890\" class=\"wp-caption-text\"><strong>Generating Haemoglobin Text<\/strong><\/figcaption><\/figure>\n<p>Depending on the person&#8217;s gender, age, haemoglobin value, and the recommended threshold, this function generates appropriate text.<\/p>\n<p>In a similar manner, <em><strong>get-uric-acid-text<\/strong><\/em> generates text for uric acid level in the sample.<\/p>\n<figure id=\"attachment_891\" aria-describedby=\"caption-attachment-891\" style=\"width: 597px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"891\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/get-uric-acid\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png\" data-orig-size=\"597,238\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Uric Acid Text\" data-image-description=\"&lt;p&gt;Uric Acid Text&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Uric Acid Text&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png\" class=\"size-full wp-image-891\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png?resize=597%2C238\" alt=\"Uric Acid Text\" width=\"597\" height=\"238\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png?w=597&amp;ssl=1 597w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png?resize=300%2C120&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/get-uric-acid.png?resize=400%2C160&amp;ssl=1 400w\" sizes=\"(max-width: 597px) 100vw, 597px\" \/><\/a><figcaption id=\"caption-attachment-891\" class=\"wp-caption-text\"><strong>Generating Uric Acid Text<\/strong><\/figcaption><\/figure>\n<p>One interesting thing to note is the way these two functions call <em><strong>get-one-output-from-node<\/strong><\/em>, passing a non-terminal node name, in order to obtain another string dynamically from the same grammar.<\/p>\n<p>For keeping the discussion brief, I have not optimized these two functions, but you can see that there is a lot of similarity in the code structure, and we could exploit that.<\/p>\n<p>Let us take a look at the application now.<\/p>\n<figure id=\"attachment_892\" aria-describedby=\"caption-attachment-892\" style=\"width: 651px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"892\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/app1\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png\" data-orig-size=\"782,411\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Main Application\" data-image-description=\"&lt;p&gt;Main Application&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Main Application&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png\" class=\"wp-image-892\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png?resize=651%2C342\" alt=\"Main Application\" width=\"651\" height=\"342\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png?w=782&amp;ssl=1 782w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png?resize=300%2C158&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app1.png?resize=768%2C404&amp;ssl=1 768w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><figcaption id=\"caption-attachment-892\" class=\"wp-caption-text\"><strong>The Main Application<\/strong><\/figcaption><\/figure>\n<p>The three drop-down lists allow us to select the required inputs -Text template, Grammar and the Data file. Once the data file is selected, names of all patients are displayed on the left pane. When a patient is selected, his\/her details are echoed at the bottom status bar, and the generated text is displayed in the main area. As we move from patient to patient, the text is refreshed automatically, and instantaneously!<\/p>\n<figure id=\"attachment_893\" aria-describedby=\"caption-attachment-893\" style=\"width: 651px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"893\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/app2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png\" data-orig-size=\"782,411\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Next Patient\" data-image-description=\"&lt;p&gt;Next Patient&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Next Patient&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png\" class=\"wp-image-893\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png?resize=651%2C342\" alt=\"Next Patient\" width=\"651\" height=\"342\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png?w=782&amp;ssl=1 782w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png?resize=300%2C158&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app2.png?resize=768%2C404&amp;ssl=1 768w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><figcaption id=\"caption-attachment-893\" class=\"wp-caption-text\"><strong>Next Patient<\/strong><\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_897\" aria-describedby=\"caption-attachment-897\" style=\"width: 651px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"897\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/08\/natural-language-generation\/app3-2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png\" data-orig-size=\"803,417\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Another Patient\" data-image-description=\"&lt;p&gt;Another Patient&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Another Patient&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png\" class=\"wp-image-897\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png?resize=651%2C338\" alt=\"Another Patient\" width=\"651\" height=\"338\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png?w=803&amp;ssl=1 803w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png?resize=300%2C156&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png?resize=768%2C399&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/app3-1.png?resize=800%2C417&amp;ssl=1 800w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><figcaption id=\"caption-attachment-897\" class=\"wp-caption-text\"><strong>Another Patient<\/strong><\/figcaption><\/figure>\n<p>As you can see, the generated text varies from one patient to the next.<\/p>\n<p>It is possible to design multiple templates and grammars for the same set of data. This allows us to achieve a much richer variety for the generated text. Obviously, that is the preferred<span class=\"Apple-converted-space\">\u00a0<\/span>solution when we wish to generate text in <em><strong>different languages<\/strong><\/em> for the given data.<\/p>\n<p>An important practical usability concern arises here. If we build a system like this, who will design the template text and who will implement the grammar? Assuming that our end-user is <em><strong>XYZ Lab<\/strong><\/em>, it is fair to expect that they will prepare the template text because they know the domain and vocabulary. What about the Grammar file? Obviously, we cannot expect them to hire <em><strong>Lisp<\/strong><\/em> programmers, or needlessly outsource that task to another agency! Well, this can be handled by implementing a good front-end as part of the NLG system, which will be used by the team at <em><strong>XYZ Lab<\/strong><\/em> to specify the static text and embed meta representations of synonyms, paraphrased text and formula-based dynamic text schema. And because this is all Lisp, it is quite straightforward to generate the appropriate grammar on the fly!<\/p>\n<p>One final note before concluding: For demo purposes, I have implemented this system as a stand-alone Windows-based application. In a real world scenario, where performance and scalability are important, one option is to turn this into a hosted REST API service.<\/p>\n<p><em><strong>iLangGen<\/strong><\/em> and the application discussed in this post have been implemented in <a href=\"http:\/\/www.lispworks.com\" target=\"_blank\" rel=\"noopener\"><em><strong>LispWorks<\/strong><\/em><\/a>.<\/p>\n<p>Hope you enjoyed reading this post!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I had written a series of posts on my iLangGen framework last year. It aims to provide a flexible and expressive approach for building natural language generation systems. In today&#8217;s post, I would like to describe a concrete example of how iLangGen can be used for generating natural language text from structured data, aided by [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[18,107,17],"tags":[109,139],"class_list":["post-884","post","type-post","status-publish","format-standard","hentry","category-lisp","category-natural-language-processing","category-programming","tag-ilanggen","tag-natural-language-generation"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-eg","jetpack-related-posts":[{"id":575,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/08\/06\/text-generation-using-ilanggen-framework\/","url_meta":{"origin":884,"position":0},"title":"Text Generation Using iLangGen Framework","author":"admin","date":"August 6, 2017","format":false,"excerpt":"The two primary areas in Natural Language processing are Natural Language Understanding and Natural Language Generation. The former is concerned with processing and making sense of natural language text, whereas the latter is concerned with synthesizing text, possibly from some deep representation. Both are fascinating and at the same time,\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"iLangGen Grammar","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1410,"url":"https:\/\/www.rangakrish.com\/index.php\/2019\/01\/27\/generating-poetry-using-ilanggen\/","url_meta":{"origin":884,"position":1},"title":"Generating Poetry Using iLangGen","author":"admin","date":"January 27, 2019","format":false,"excerpt":"In an earlier article, I wrote about using iLangGen to generate natural language text. iLangGen is a powerful text generation library that I have been working on over the years. Today, I would like to show how we can use that library to generate \"poetry\". Be warned, however, that the\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Sample Output 2","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2019\/01\/Output2.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2152,"url":"https:\/\/www.rangakrish.com\/index.php\/2020\/09\/28\/template-based-text-generation\/","url_meta":{"origin":884,"position":2},"title":"Template-Based Text Generation","author":"admin","date":"September 28, 2020","format":false,"excerpt":"I had written earlier about natural language generation\u00a0using my iLangGen framework. I used a \"template\" text file which was instantiated dynamically based on predefined \"grammars\" and external data. The sample application I show-cased demonstrated its utility and versatility. Today I would like to touch upon a few other \"pattern\" elements\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Template File","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/09\/Template-300x195.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/09\/Template-300x195.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/09\/Template-300x195.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":637,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/09\/27\/composition-of-grammars\/","url_meta":{"origin":884,"position":3},"title":"Composition of Grammars","author":"admin","date":"September 27, 2017","format":false,"excerpt":"In the last post, we saw how iLangGen text generation framework supports reuse of grammars through inheritance, akin to object-oriented languages. The good news is that we can achieve reuse through composition as well. The following is a simple grammar, nothing fancy to elaborate. Here is the output when you\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Simple Grammar","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/09\/G1.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":585,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/08\/18\/repetition-in-grammar-rules\/","url_meta":{"origin":884,"position":4},"title":"Repetition in Grammar Rules","author":"admin","date":"August 18, 2017","format":false,"excerpt":"Many times, we need to repeatedly generate an element, or in general, have a way to control the number times one or more elements get generated. iLangGen supports all the standard cases: - Zero or once - Zero or more times (unbounded) - Zero or more times (bounded) - One\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Zero or Once","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Optional.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Optional.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Optional.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1309,"url":"https:\/\/www.rangakrish.com\/index.php\/2018\/12\/16\/generating-poetry-using-rita\/","url_meta":{"origin":884,"position":5},"title":"Generating Poetry Using RiTa","author":"admin","date":"December 16, 2018","format":false,"excerpt":"A few days ago, I came across a nice library called RiTa, which is described as a software toolkit for computational literature. Its two major features are text analysis and text generation.\u00a0 The text analysis module parses given text to extract sentences, tokens, POS, stresses, and phonemes. There is also\u2026","rel":"","context":"In &quot;Natural Language Processing&quot;","block_context":{"text":"Natural Language Processing","link":"https:\/\/www.rangakrish.com\/index.php\/category\/natural-language-processing\/"},"img":{"alt_text":"Terminal Session","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/12\/Terminal.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=884"}],"version-history":[{"count":0,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/884\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=884"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=884"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}