Linguistic Landscapes

Language in Culture and Community

Spoken language has consistently proven a difficult entity to research because it——like a cultural value——is highly untangible.

This intangible component of society is referred to as a ‘mentifact.’

Mentifact (noun): the intangible, ideological components of a culture such as its shared ideas, values, beliefs, attitudes, preferences, and knowledge. A mentifact is one of three subcategories that can be combined to sum up the traits of a culture (Three Components of Culutre). These three components of culture include mentifacts, sociofacts, and artifacts.

Methods have been developed to study spoken language, but all of these methods involve quantifying the concrete, physical component of spoken language, which is sound, but sound is transient and bound completely to the construct of time. There is, however, a more persistent manifestation of language: the written word.

Writing, unlike spoken language, is an artifact of society. It is tangible. It can stay static across time, and it can quite literally be held, etched, and erased.

The sum of the writing in an environment is referred to as a linguistic landscape.

Linguistic landscapes are often studied because——with the proper analysis——they are reflections of the diversity, culture, practices, perceptions, and values of a society. Linguistic landscapes are defined as “‘The language of public road signs, advertising billboards, street names, place names, commercial shop signs, and public signs on government buildings combines to form the linguistic landscape of a given territory, region, or urban agglomeration’” (Landry & Bourhis,1997, p. 25, qtd. in SemiotiX, 2020).

Much reseach has been done into linguistic landscapes, and much research has been done into humanistic geography and the distribution of spoken language, but less research has been done into geosemiotics and geographical distributions of written language. Although linguistic landscapes likely function differently from spoken language, there are many parallels to be drawn. This paper proceeds with the hopefully not too optimistic assumption that linguistic theories that have been applied exclusively to spoken language are at least somewhat applicable to the patterns and behaviors of linguistic landscapes.

LLBert: Linguistic Landscape Coordinate Regressor

LLBert is an experiment in using natural language processing to estimate the geographic coordinates associated with text found on signs. The project README documents its data, model, workflow, and interactive predictor.

LLBert: Linguistic Landscape Coordinate Regressor

This project fine-tunes a sentence-transformer model to predict a latitude and longitude pair from text observed on signs at an intersection.

The name LLBert is shorthand for Linguistic Landscape BERT (and, conveniently, Latitude Longitude BERT), a playful reference to the inputs and outputs of the sentence-transformer encoder at the center of the project.

The model is an experiment in predicting geographic coordinates from linguistic Landscape data, or the language people encounter in public space.

What is a Linguistic Landscape?

In simple terms, a linguistic landscape is the sum of all of the written language in an environment.

Writing, unlike spoken language, is an artifact of society. It extends across time.

The sum of the writing in an environment (especially a public environment) is referred to as a linguistic landscape.

Linguistic landscapes are often studied because—with the proper analysis—they are reflections of the diversity, culture, practices, perceptions, and values of a society.

Linguistic landscapes can be further defined as:

“‘The language of public road signs, advertising billboards, street names, place names, commercial shop signs, and public signs on government buildings combines to form the linguistic landscape of a given territory, region, or urban agglomeration’” (Landry & Bourhis,1997, p. 25, qtd. in SemiotiX, 2020).

As an example, let’s look at an image of this sign from the University of Colorado Anschutz:

a photo of signage for the University of Colorado Anschutz Health Sciences Building outside of the building entryway with a large building int he back

There is a lot of data, or information, in this photo. Here, we can see the sign itself, pavement, a mulched garden bed, a road, buildings in the back, and more.

But if we were to ask: “what linguistic landscape data is in this image?” we could likely transcribe it as:

CU University of Colorado ANSCHUTZ MEDICAL CAMPUS ANSCHUTZ HEALTH SCIENCES BUILDING 1890 NORTH REVER COURT

So, the “linguistic landscape” data of this view of this region contains that information.

For further clarification, let’s look at another sign on the building:

image of a sign on the University of Colorado Anschutz Health Sciences Building above the entryway

Here, we can read two pieces of linguistic data. First, there is the sign itself, which reads:

ANSCHUTZ HEALTH SCIENCES BUILDING

Then, although they are flipped in orientation, there are the two exit signs, which read:

EXIT EXIT

There is also a subtle reflection of text that appears to read

ANSCHUTZ HEALTH SCIENCES VATORS

Which presumably mentions something about the elevators.

So, if we were to hypothetically say this was all of the linguistic landscape text outside this building (it’s not, but for example), we could say the sum of the linguistic landscape outside of this building was:

CU University of Colorado ANSCHUTZ MEDICAL CAMPUS ANSCHUTZ HEALTH SCIENCES BUILDING 1890 NORTH REVER COURT ANSCHUTZ HEALTH SCIENCES BUILDING EXIT EXIT ANSCHUTZ HEALTH SCIENCES VATORS

Notice that there is repetition, and that is good information. Repetition is very common in languauage.

Much reseach has been done into linguistic landscapes, and much research has been done into humanistic geography and the distribution of spoken language, but less research has been done into geosemiotics and geographical distributions of written language.

This project aims to better understand whether a Machine Learning method of Natural Language Processing (NLP) can accurately predict a geographical coordinate set (latitude, longitude) based on the linguistic landscape data surrounding an intesrsection.

For the time being, the project will focus on the greater Denver Metro Area.

Inspiration for Project

In high school, I loved playing a game called Hostage. The game began with two teams, with one designated home base.

Each team would have two sets of people: drivers/navigators, and hostages.

At the beginning of the game, you would set a timer for generally 10-20 minutes. Each team would have that much time to take the other team’s players to an unfamiliar location and drop them off.

The dropped-off hostages then had to work together to figure out where they were and, without using their GPS apps, call their drivers/navigators and explain to them ahd to get to them to pick them up.

Whichever team made it back to home base with their full team first won.

The game turned navigation into a kind of collaborative investigation. Street names, businesses, and public signs were some of the most useful clues because they gave us concrete information about our surroundings. A road sign could tell us the name of a place, a business could identify a neighborhood or intersection, and a cluster of signs could suggest the language, culture, or commercial character of an area. I was relying on the linguistic landscape around me to orient myself, even though I did not have that vocabulary for the process at the time.

More recently, while playing the GeoGuessr app, I realized that one of my primary methods for predicting my location was also based on linguistic landscape data. I would look at street names, storefronts, advertisements, public notices, and other written signs, then combine those observations with the visual character of the surrounding area. Recognizing this pattern made me reflect on my own cognitive processes: how was I turning fragments of written language into a geographic intuition?

These experiences led me to wonder whether linguistic data alone could be enough to predict geographical location.

LLBert is an attempt to investigate that question computationally. Rather than treating the model only as a geolocation system, I see it as a model of cognitive analysis: a way to examine whether the kinds of linguistic clues people use to orient themselves can be represented, learned, and used to estimate where a scene might be located.

Model Training Data

The raw dataset is expected at training_data_raw.csv. It may include the pandas-exported index column; the preprocessing script only uses:

  • intersection
  • text_on_sign_exact
  • latitude
  • longitude

The project can also build this raw dataset directly from the source spreadsheets. Put the exported workbooks in ll_sheets/ and place the intersection coordinate lookup at coordinate_dict10.xlsx. The lookup’s DMS coordinate strings are converted to decimal latitude and longitude during aggregation.

Workflow

From source spreadsheets

Run the complete data-preparation flow from the project root:

source .venv/bin/activate
python prepare_training_data.py \
  --from-ll-sheets \
  --sheet-dir ll_sheets \
  --coord-file coordinate_dict10.xlsx \
  --input-file training_data_raw.csv \
  --output-file training.csv

This command reads every .xlsx file in ll_sheets/, cleans and combines the sign records, joins each intersection to coordinate_dict10.xlsx, and writes the two training stages:

  • training_data_raw.csv: cleaned sign-level records with coordinates.
  • training.csv: deterministic bootstrap bags used by the model trainer.

The default command creates 100 samples per intersection, with 8 sign texts in each sample. Use --bag-size, --samples-per-intersection, and --seed to change those settings. To reuse an existing raw CSV instead, omit --from-ll-sheets and run the preparation command below.

Prepare bootstrapped training rows:

source .venv/bin/activate
python prepare_training_data.py --seed 1992 --bag-size 5 --samples-per-intersection 50

This writes training.csv with rows shaped like:

intersection,sample_id,text,latitude,longitude,unique_sign_count,raw_sign_count

Each row is a deterministic bootstrap sample of sign texts from one intersection, joined into a single text field. This trains on “some signs seen at this coordinate” instead of one sign or every sign at that coordinate.

Train the model:

python train.py

Evaluate and write predictions:

python eval.py

This writes predictions.csv and a map-style diagnostic plot:

Prediction map

It also writes a coordinate calibration plot:

Predicted vs actual coordinates

Or run the full pipeline:

make

Try the model in a web app

Once output/ contains a trained model, launch the interactive predictor:

make serve

Open prediction lets you enter a bundle of sign text, provide your own latitude and longitude estimate, and compare it with LLBert’s prediction. The Random round mode selects a held-out-style row from training.csv, hides its coordinates, and scores both your guess and the model. The frontend is plain HTML and JavaScript, served by FastAPI, so it can be embedded directly in Hugo or deployed as a small app on its own.

Hosting and Hugo embedding

The recommended architecture is a static Hugo site plus this small FastAPI service. You have two deployment options:

  • Direct Hugo integration: copy web/index.html into a Hugo page or shortcode, and set window.LLBERT_API_URL before the app script to the API’s HTTPS URL.
  • Subdomain: deploy the whole app and API together at something like llbert.example.com, then embed that URL in Hugo with an iframe.

For a first deployment, Render or Fly.io are a better fit than a static host because the model needs Python, PyTorch, and a long-lived process:

  1. Push this repository to GitHub, including app.py, web/, requirements.txt, and the trained output/ directory.
  2. Configure the service command as uvicorn app:app --host 0.0.0.0 --port $PORT.
  3. Set LLBERT_ALLOWED_ORIGINS to the Hugo site’s origin when the frontend is hosted separately. runtime.txt selects Python 3.10.

For a Hugo page, the smallest embed is:

<iframe
  src="https://llbert.example.com"
  title="LLBert linguistic landscape coordinate predictor"
  loading="lazy"
  style="width:100%; min-height:900px; border:0;"
></iframe>

The app reads LLBERT_MODEL_PATH, LLBERT_DATA_PATH, and LLBERT_ALLOWED_ORIGINS when set, which is useful for a container or another host. Keep the model service separate from Hugo: Hugo is static, while prediction requires Python, PyTorch, and the sentence-transformer model. The model’s predictions are approximate and should not be treated as precise geolocation.

Command-line options and defaults

All of the project scripts accept command-line flags, and each one has a default value that is used when you do not pass an override. The defaults are intentionally documented here so it is clear which behavior can be customized.

prepare_training_data.py

Creates the bootstrapped training CSV from the raw sign data.

ArgumentDefaultDescription
-i, --input-filetraining_data_raw.csvRaw pandas-exported CSV to read.
-o, --output-filetraining.csvPrepared training dataset written by the script.
--from-ll-sheetsFalseBuild the raw input from all .xlsx files in --sheet-dir and the coordinate workbook.
--sheet-dirll_sheetsDirectory containing source spreadsheet exports.
--coord-filecoordinate_dict10.xlsxIntersection-to-coordinate lookup workbook.
--seed1992Random seed used for deterministic bootstrapping.
--bag-size8Number of sign texts to combine into each training row.
--samples-per-intersection100Number of bootstrap bags generated for each intersection.
--separator`"“`

Example:

python prepare_training_data.py \
  --input-file training_data_raw.csv \
  --output-file training.csv \
  --seed 1992 \
  --bag-size 5 \
  --samples-per-intersection 50 \
  --separator " | "

To rebuild both files from the source spreadsheets, use:

python prepare_training_data.py \
  --from-ll-sheets \
  --sheet-dir ll_sheets \
  --coord-file coordinate_dict10.xlsx

train.py

Trains the sentence-transformer encoder and coordinate regression head.

ArgumentDefaultDescription
--data-filetraining.csvTraining dataset path.
--output-pathoutputDirectory where model artifacts are written.
--model-namesentence-transformers/all-MiniLM-L6-v2Base sentence-transformer model to fine-tune.
--deviceNoneOptional explicit device such as cpu, cuda, or mps; if omitted, CUDA is used when available and otherwise CPU is used.
--seed1992Random seed for reproducibility.
--epochs10Number of training epochs.
--batch-size64Batch size for training.
--num-workers2DataLoader worker processes.
--save-every-epochs5Save the best checkpoint every N epochs (and at final epoch).
--learning-rate1e-4Learning rate for the encoder.
--head-learning-rate5e-2Learning rate for the coordinate head.
--weight-decay0.001Weight decay for optimization.
--test-size0.2Fraction of rows used for the validation/test split.
--hidden-dim256Hidden dimension in the coordinate regressor.
--dropout0.1Dropout used inside the regression head.
--freeze-encoderFalseIf set, only the coordinate head is trained and the encoder stays fixed.
--freeze-transformer-layers0Freeze the first N transformer layers in the encoder.
--freeze-attentionFalseFreeze self-attention parameters while leaving other encoder parameters trainable.

Example:

python train.py \
  --data-file training.csv \
  --output-path output \
  --model-name sentence-transformers/all-MiniLM-L6-v2 \
  --device cuda \
  --epochs 20 \
  --batch-size 32 \
  --learning-rate 2e-5 \
  --head-learning-rate 1e-2 \
  --hidden-dim 512 \
  --dropout 0.15

eval.py

Loads a trained model and writes predictions and diagnostics.

ArgumentDefaultDescription
--data-filetraining.csvDataset to score.
--model-pathoutputDirectory containing the trained model artifacts.
--output-filepredictions.csvCSV path for predicted coordinates and error metrics.
--plot-fileplots/prediction_map.pngPath to the map-style prediction error plot.
--scatter-plot-fileplots/predicted_vs_actual.pngPath to the predicted-vs-actual scatter plot.
--deviceNoneOptional explicit device override; otherwise CUDA is used when available, else CPU.
--batch-size64Batch size used for inference.
--seed1992Must match the training seed for the same test split.
--test-size0.2Must match the training split size.

Example:

python eval.py \
  --data-file training.csv \
  --model-path output \
  --output-file predictions.csv \
  --plot-file plots/prediction_map.png \
  --scatter-plot-file plots/predicted_vs_actual.png \
  --batch-size 128

generate_data.py

Generates city-distance data used for computing distances between cities.

ArgumentDefaultDescription
-c, --countryUSCountry code to use when searching cities.
-w, --workers1Number of worker threads used for computation.
-s, --chunk-size1000Batch size for chunking distance calculations.
-o, --output-filedistances.csvOutput CSV path for generated distances.
--shuffleFalseIf set, shuffle the combinations before processing.

Example:

python generate_data.py \
  --country US \
  --workers 4 \
  --chunk-size 2000 \
  --output-file distances.csv \
  --shuffle

Outputs

  • training.csv: prepared bootstrapped dataset.
  • output/: saved sentence-transformer encoder, coordinate head, and coordinate normalization metadata.
  • predictions.csv: evaluation rows with predicted coordinates and error_km.
  • plots/prediction_map.png: actual vs predicted coordinates with line segments showing the prediction error.
  • plots/predicted_vs_actual.png: predicted vs actual latitude and longitude scatter plots.

References

Ernst, P. (1969). The tongues of Italy: prehistory and history. Greenwood Press.

Google (2020). Google Maps. Google. https://www.google.com/maps

Huisman, J. L. A., Majid, A., & van Hout, R. (2019). The geographical configuration of a language area influences linguistic diversity. Public Libary of Science. 14(6).

Metro Denver (2020). Communities. MetroDenver Economic Development Coorporation. *http://www.metrodenver.org/do-business/communities/

SemiotiX (2020). The sociolinguisics of space and semiotic landscapes: An introduction. SemiotiX: A global information magazine. https://semioticon.com/semiotix/2013/05/the-sociolinguistics-of-space-and-semiotic-landscapes-an-introduction/

Trudgill, P. (2000). “Chapter 5: Language and Context,” Sociolinguistics: An introduction to language and society. (4th ed., pp. 81-104). Penguin Books.