Sep 03, 2026 | 1014 words | 10 min read
16.3.2. Task 2#
Learning Objectives#
Reuse previously written functions to analyze new data.
Load and interpret saved model data from CSV files.
Compare frequency models using a quantitative distance metric.
Visualize analysis results using plots.
Introduction#
In Section 16.3.1 you built normalized n-gram frequency models for known
languages and saved them to CSV files using the n,ngram,frequency format. These
models describe how frequently different character patterns appear in each language.
In this task, you will apply those models to analyze a text file in an unknown language. The user will select one unknown language text and one n-gram size to use for the analysis. You will compare that unknown text model to each known language model for the selected n-gram size and identify the closest language match.
Task Instructions#
Make sure you have successfully completed Section 16.3.1 and have the CSV
files containing the n-gram models for each known language. You will need to place
these files in a folder named models within the same folder as your
Python script. The CSV files should use the n,ngram,frequency format from
Section 16.3.1.
Before creating the program, create a flowchart of the algorithm you will use and save
it as py4_ind_2_username.pdf. Then
start your program from a copy of the
ENGR133_Python_Template.py
Python template. Your program should be named
py4_ind_2_username.py. You will also
need to create a folder named unknown_texts within the same folder as your
Python script. Then, download each of the unknown texts in
Table 16.10 and place them into your
unknown_texts folder. Develop a Python program that does the
following:
Display the unknown text files and ask the user to select one file to analyze.
Ask the user to select an n-gram size from \(1\) to \(5\).
Load the selected n-gram models from the CSV files created in Section 16.3.1.
Create a relative frequency n-gram for the selected unknown text file.
For the selected unknown text, compute the distance between its n-gram model and each known language n-gram model.
Find the known language with the smallest distance score and report it as the best language model match.
Generate a plot for the selected unknown text showing the total difference score for each known language.
Unknown Text |
Download Link |
|---|---|
Unknown Text 1 |
|
Unknown Text 2 |
|
Unknown Text 3 |
Note
Make sure you saved the samples into your unknown_texts folder, and that your
folder is located in the same directory as your Python script.
Reusing N-Gram Functions#
In Section 16.3.1, you created functions to clean text, count n-grams, and normalize n-gram counts. Reuse those functions in this task instead of writing new versions of the same logic.
After the user selects an unknown text and an n-gram size, use your previous
clean_text function to clean the unknown text before creating the n-gram.
Then create the unknown text’s n-gram counts for the selected value of n using
your previous create_n_gram function. Then use your previous
normalize_n_gram function to convert those counts to relative frequencies.
Note
Remember to submit py4_ind_1_username.py in addition to this task’s deliverables if you import functions from it.
Load From CSV Function#
Create a function named load_from_csv that takes in the selected n-gram size
n and returns a dictionary where the keys are the known languages (e.g.,
“english”, “french”) and the values are only the relative frequency n-gram dictionary
for the selected n-gram size.
For example, if the user selects n = 2, the returned dictionary should have
the following structure:
models["english"] = {"th": 0.0254, "he": 0.0221, ...}
models["french"] = {"le": 0.0183, "es": 0.0175, ...}
When reading the CSV files, ensure that you correctly parse the n-grams and their
relative frequencies for the selected n-gram size from the CSV files. You can use the
csv module from the Python standard library to help with this task.
N-Gram Distance Function#
Create a function named n_gram_dist that takes in two n-gram dictionaries (one
for the unknown text and one for a known language) and returns the total distance
between the two n-gram models using a distance metric.
The distance metric you will implement is the absolute difference between the relative frequencies of the n-grams in the two models. To calculate this, you will need to iterate through all n-grams that appear in either model and use the following formula:
Where \(L\) is the relative frequency of the n-gram in the known language model and \(U\) is the relative frequency of the n-gram in the unknown language model.
By summing the distances for all n-grams, you will get a total distance score that quantifies how different the two models are. A smaller distance indicates that the unknown text is more similar to the known language, while a larger distance indicates that it is less similar.
Score Language Function#
Create a function named score_language that takes a dictionary of known
language n-gram models (as returned by the load_from_csv function), and the
selected unknown text normalized n-gram dictionary. This function will return a
dictionary whose keys are the known language names and values are the total distance
scores for each known language model compared to the unknown text model.
Use the n_gram_dist function to calculate the distance between the selected
unknown text model and each known language model.
Plotting Function#
Use the provided plot_language_scores function. It takes in a dictionary of
total difference scores for each known language, the name of the unknown text, and the
selected n-gram size. This function generates a bar plot showing the total difference
score for each known language. The language with the lowest score is the best match.
import matplotlib.pyplot as plt
def plot_language_scores(scores, name, n):
languages = list(scores.keys())
distances = list(scores.values())
fig, ax = plt.subplots()
ax.bar(languages, distances)
ax.set_title(f"{name} {n}-gram Language Scores")
ax.set_xlabel("Language")
ax.set_ylabel("Total Difference")
ax.tick_params(axis='x', rotation=45)
fig.tight_layout()
plt.show()
Main Function#
In your main function, you will need to do the following:
Display the unknown texts in the
unknown_textsfolder and have the user select a text to analyze.Ask the user to select an n-gram size from \(1\) to \(5\).
Load the selected n-gram size from the known language models using the
load_from_csvfunction.Reuse functions from Section 16.3.1 to clean the selected unknown text and create a normalized n-gram model.
Use
score_languageto get the language distance scores for the selected n-gram size.Print the best n-gram language model match for the unknown text. The best match is the language with the smallest total difference score.
Plot the language total difference scores for the selected n-gram size.
Sample Output#
Test cases for language identification and visualization. Use the values in Table 16.11 below to test your program.
Case |
Unknown File Option |
n-gram size |
|---|---|---|
1 |
1 |
1 |
2 |
2 |
3 |
3 |
3 |
5 |
Ensure your program’s output matches the provided samples exactly. This includes all characters, white space, and punctuation. In the samples, user input is highlighted like this for clarity, but your program should not highlight user input in this way.
Case 1 Sample Output
$ python3 py4_ind_2_username.py Unknown Language File Options 1. unknown_1 2. unknown_2 3. unknown_3 Select a file to analyze: 1 Select an n-gram size (1-5): 1 The best language match for unknown_1 using 1-grams is the english model.
Fig. 16.5 Case_1_sample_output.png#
Case 2 Sample Output
$ python3 py4_ind_2_username.py Unknown Language File Options 1. unknown_1 2. unknown_2 3. unknown_3 Select a file to analyze: 2 Select an n-gram size (1-5): 3 The best language match for unknown_2 using 3-grams is the french model.
Fig. 16.6 Case_2_sample_output.png#
Case 3 Sample Output
$ python3 py4_ind_2_username.py Unknown Language File Options 1. unknown_1 2. unknown_2 3. unknown_3 Select a file to analyze: 3 Select an n-gram size (1-5): 5 The best language match for unknown_3 using 5-grams is the italian model.
Fig. 16.7 Case_3_sample_output.png#
Deliverables |
Description |
|---|---|
py4_ind_2_username.pdf |
Flowchart(s) for this task. |
py4_ind_2_username.py |
Your completed Python code. |