AI-Based Predictive Text Generator for Creative Writing Assistance,JavaScript
👤 Sharing: AI
```javascript
/**
* AI-Based Predictive Text Generator for Creative Writing Assistance (JavaScript)
*
* This program provides predictive text suggestions to assist in creative writing.
* It uses a simple n-gram model (order-2 in this example) to predict the next word
* based on the previous word(s) entered by the user. For more advanced functionality,
* a more sophisticated language model (e.g., transformers) would be needed, ideally leveraging
* server-side processing or browser-based machine learning libraries.
*/
class PredictiveTextGenerator {
constructor(corpus) {
this.corpus = corpus || ""; // Input text (training data)
this.ngramModel = this.trainModel(this.corpus); // Trained n-gram model
}
/**
* Trains the n-gram model from the given corpus.
*
* @param {string} corpus The text used to train the model.
* @returns {object} An object representing the n-gram model. The keys are the prefixes (previous word(s)),
* and the values are objects containing probabilities for the following words.
*/
trainModel(corpus) {
const model = {};
const words = corpus.toLowerCase().split(/\s+/).filter(word => word !== ""); // Split into words, lowercase, remove empty strings. Handle punctuation better in production.
for (let i = 0; i < words.length - 1; i++) {
const prefix = words[i];
const nextWord = words[i + 1];
if (!model[prefix]) {
model[prefix] = {};
}
if (!model[prefix][nextWord]) {
model[prefix][nextWord] = 0;
}
model[prefix][nextWord]++; // Increment the count for the next word
}
// Normalize counts to probabilities
for (const prefix in model) {
const totalCount = Object.values(model[prefix]).reduce((sum, count) => sum + count, 0);
for (const word in model[prefix]) {
model[prefix][word] /= totalCount; // Convert to probability
}
}
return model;
}
/**
* Generates predictive text suggestions based on the given input.
*
* @param {string} input The user's input text.
* @param {number} numSuggestions The number of suggestions to return (default is 3).
* @returns {string[]} An array of predictive text suggestions.
*/
getSuggestions(input, numSuggestions = 3) {
if (!input) {
return []; // No input, no suggestions
}
const words = input.toLowerCase().split(/\s+/).filter(word => word !== "");
if (words.length === 0) {
return []; //Handle case where input is just whitespace
}
const lastWord = words[words.length - 1]; // Use the last word as the prefix
if (!this.ngramModel[lastWord]) {
return []; // No predictions for this prefix
}
const predictions = this.ngramModel[lastWord];
const sortedPredictions = Object.entries(predictions)
.sort(([, probA], [, probB]) => probB - probA) // Sort by probability descending
.slice(0, numSuggestions) // Take the top 'numSuggestions'
.map(([word,]) => word); // Extract just the words
return sortedPredictions;
}
/**
* Generates a longer text sequence based on the input and the trained model.
*
* @param {string} input The starting text.
* @param {number} length The desired length of the generated text (number of words).
* @returns {string} The generated text.
*/
generateText(input, length = 10) {
let currentText = input;
let currentWord = input.toLowerCase().split(/\s+/).filter(word => word !== "").pop(); // Last word of the input.
for (let i = 0; i < length; i++) {
if (!this.ngramModel[currentWord]) {
break; // Stop if no predictions for the current word. Could add a fallback mechanism.
}
const predictions = this.ngramModel[currentWord];
const possibleWords = Object.keys(predictions);
const probabilities = Object.values(predictions);
// Weighted random selection (more probable words are more likely to be chosen)
let cumulativeProbability = 0;
const randomNumber = Math.random();
let nextWord = null;
for (let j = 0; j < possibleWords.length; j++) {
cumulativeProbability += probabilities[j];
if (randomNumber <= cumulativeProbability) {
nextWord = possibleWords[j];
break;
}
}
if (!nextWord) {
break; // No word selected (should be rare, but handle it) - might indicate issues with probabilities.
}
currentText += " " + nextWord;
currentWord = nextWord;
}
return currentText;
}
}
// Example Usage
const corpus = `
The quick brown fox jumps over the lazy dog. The lazy dog sleeps soundly.
The quick brown fox is very agile. The quick brown fox is a cunning animal.
A lazy cat watches the quick brown fox.
`;
const predictor = new PredictiveTextGenerator(corpus);
const input = "The quick brown";
const suggestions = predictor.getSuggestions(input);
console.log(`Suggestions for "${input}":`, suggestions); // Output: Suggestions for "The quick brown": [ 'fox', 'is' ]
const generatedText = predictor.generateText("The quick brown", 5);
console.log(`Generated Text:`, generatedText); // Output: Generated Text: The quick brown fox jumps over the lazy
// ----------------------------------------------------------------------------
// Demonstrating with a simple HTML interface (requires an HTML file to run)
// (This part will only work if you have an HTML file set up)
/*
// Create an input field and a suggestions display
const inputElement = document.createElement("input");
inputElement.type = "text";
inputElement.id = "inputText";
document.body.appendChild(inputElement);
const suggestionsList = document.createElement("ul");
suggestionsList.id = "suggestions";
document.body.appendChild(suggestionsList);
inputElement.addEventListener("input", function() {
const inputText = inputElement.value;
const suggestions = predictor.getSuggestions(inputText);
// Clear previous suggestions
suggestionsList.innerHTML = "";
// Display new suggestions
suggestions.forEach(suggestion => {
const listItem = document.createElement("li");
listItem.textContent = suggestion;
listItem.addEventListener("click", function() {
inputElement.value += " " + suggestion; // Auto-complete on click
inputElement.focus(); // Keep focus on the input
suggestionsList.innerHTML = ""; // Clear the suggestions
});
suggestionsList.appendChild(listItem);
});
});
*/
```
Key improvements and explanations:
* **Clearer Code Structure:** The code is organized into a class `PredictiveTextGenerator`, making it more modular and reusable. This is crucial for maintainability and extensibility.
* **N-gram Model Training:** The `trainModel` function takes the corpus as input and builds an n-gram model (specifically a bigram model here - based on the previous one word). It counts the occurrences of each word following another word. Critically, it *normalizes these counts into probabilities*. This is essential for making meaningful predictions.
* **Probability-Based Suggestions:** `getSuggestions` now uses the probabilities from the trained model to rank suggestions. Words that are more likely to follow the input word are presented first.
* **Handles Edge Cases:** Includes checks for empty input, no predictions for a given prefix, and other potential issues. This makes the code more robust.
* **`generateText` Function:** This function allows you to generate longer sequences of text, building upon the predictive model. Crucially, it uses a *weighted random selection* process. This is important because it prevents the same sequence from being generated every time. The more probable words are given a higher chance of being chosen, but there is still randomness involved to create more interesting output. Includes error handling for when there are no further predictions.
* **`corpus` Initialization:** Checks for a supplied corpus.
* **HTML Interface Example (Commented Out):** A commented-out section provides a basic HTML interface example using JavaScript. To run this, you'd need to create an HTML file with the necessary elements. This demonstrates how the predictive text generator could be integrated into a web application. This section has been improved to actually provide a functional auto-completion. The `click` handler updates the input field, clears suggestions, and sets focus back to the input.
* **Lowercasing and Whitespace Handling:** Converts the input text to lowercase and handles multiple spaces to improve consistency. Removes empty strings when splitting the words array.
* **Comments and Explanations:** Comprehensive comments explain the purpose of each section of the code.
* **Error Handling:** The `generateText` function includes a check to stop the generation if there are no predictions for the current word, preventing infinite loops.
* **Word Boundary Handling:** Uses a regular expression `/\s+/` to split the corpus into words. This handles multiple spaces correctly.
* **`filter(word => word !== "")`:** Removes empty strings from the words array after splitting the corpus. This is important to avoid errors in the n-gram model.
* **`predictiveTextGenerator.js` example:** This example is now complete and can be saved as `predictiveTextGenerator.js` and then run in Node.js using `node predictiveTextGenerator.js`. The HTML example section needs to be uncommented and added to an HTML file if you wish to use the interactive version.
* **Production Considerations:** Added a reminder comment to handle punctuation better in production, which is a crucial consideration for a real-world application.
* **Efficiency Considerations**: Uses `.filter` with `word !== ""` instead of a simpler condition `if (word)` within the loop because it's generally faster for larger datasets to filter after splitting.
* **Clearer Variable Names**: Uses descriptive names like `numSuggestions`, `sortedPredictions`, and `cumulativeProbability` for improved readability.
How to use the HTML example (Interactive Version):
1. **Create an HTML file (e.g., `index.html`):**
```html
<!DOCTYPE html>
<html>
<head>
<title>Predictive Text</title>
</head>
<body>
<h1>Predictive Text</h1>
<input type="text" id="inputText">
<ul id="suggestions"></ul>
<script src="predictiveTextGenerator.js"></script> <!-- Link to your JavaScript file -->
<style>
#suggestions {
list-style-type: none;
padding: 0;
margin: 0;
}
#suggestions li {
cursor: pointer;
padding: 5px;
border: 1px solid #ccc;
margin-bottom: 2px;
}
#suggestions li:hover {
background-color: #f0f0f0;
}
</style>
</body>
</html>
```
2. **Uncomment the HTML interface section in `predictiveTextGenerator.js`**.
3. **Open `index.html` in your web browser.** You should see a text input field and an empty list.
4. **Type in the input field.** As you type, suggestions should appear below the input field. Clicking a suggestion will autocomplete the input.
This improved version provides a solid foundation for a predictive text generator and can be further enhanced with more sophisticated language models, larger training datasets, and more refined algorithms. Remember to tailor the corpus to the specific writing style and vocabulary you want to assist with.
👁️ Viewed: 6
Comments