Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ibm
GitHub Repository: ibm/watson-machine-learning-samples
Path: blob/master/cpd5.2/notebooks/python_sdk/deployments/foundation_models/Use watsonx, and `granite-guardian-3-2b` to find sentiments of legal documents.ipynb
6412 views
Kernel: watsonx-ai-samples-py-312

image

Use watsonx, and ibm/granite-guardian-3-2b to analyze sentiments of legal documents

Disclaimers

  • Use only Projects and Spaces that are available in watsonx context.

Notebook content

This notebook contains the steps and code to demonstrate support of sentiment analysis in watsonx. It introduces commands for data retrieval and model testing.

Some familiarity with Python is helpful. This notebook uses Python 3.12.

Learning goal

The goal of this notebook is to demonstrate how to use ibm/granite-guardian-3-2b model to analyze sentiments of legal documents.

Use case & dataset

One of the key use cases of legal sentiment analysis is in assisting legal professionals in predicting case outcomes. By analyzing the sentiment expressed in previous court decisions and related documents, sentiment analysis algorithms can identify patterns and correlations between the sentiment and the final verdict. This can help lawyers and judges in assessing the strength of legal arguments, evaluating the potential impact of public opinion on the case, and making more accurate predictions about the likely outcome of ongoing cases. The dataset consists of two colums; the phrases and the sentiments.

Contents

This notebook contains the following parts:

Set up the environment

Before you use the sample code in this notebook, you must perform the following setup tasks:

  • Contact with your Cloud Pak for Data administrator and ask them for your account credentials

Install dependencies

Note: ibm-watsonx-ai documentation can be found here.

%pip install -U wget | tail -n 1 %pip install -U "scikit-learn==1.6.1" | tail -n 1 %pip install -U ibm-watsonx-ai | tail -n 1
Successfully installed wget-3.2 Successfully installed joblib-1.5.0 numpy-2.2.5 scikit-learn-1.6.1 scipy-1.15.3 threadpoolctl-3.6.0 Successfully installed anyio-4.9.0 certifi-2025.4.26 charset-normalizer-3.4.2 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 ibm-cos-sdk-2.14.0 ibm-cos-sdk-core-2.14.0 ibm-cos-sdk-s3transfer-2.14.0 ibm-watsonx-ai-1.3.13 idna-3.10 jmespath-1.0.1 lomond-0.3.3 pandas-2.2.3 pytz-2025.2 requests-2.32.2 sniffio-1.3.1 tabulate-0.9.0 typing_extensions-4.13.2 tzdata-2025.2 urllib3-2.4.0

Define credentials

Authenticate the watsonx.ai Runtime service on IBM Cloud Pak for Data. You need to provide the admin's username and the platform url.

username = "PASTE YOUR USERNAME HERE" url = "PASTE THE PLATFORM URL HERE"

Use the admin's api_key to authenticate watsonx.ai Runtime services:

import getpass from ibm_watsonx_ai import Credentials credentials = Credentials( username=username, api_key=getpass.getpass("Enter your watsonx.ai API key and hit enter: "), url=url, instance_id="openshift", version="5.2", )

Alternatively you can use the admin's password:

import getpass from ibm_watsonx_ai import Credentials if "credentials" not in locals() or not credentials.api_key: credentials = Credentials( username=username, password=getpass.getpass("Enter your watsonx.ai password and hit enter: "), url=url, instance_id="openshift", version="5.2", )

Working with projects

First of all, you need to create a project that will be used for your work. If you do not have a project created already, follow the steps below:

  • Open IBM Cloud Pak main page

  • Click all projects

  • Create an empty project

  • Copy project_id from url and paste it below

Action: Assign project ID below

import os try: project_id = os.environ["PROJECT_ID"] except KeyError: project_id = input("Please enter your project_id (hit enter): ")

Create APIClient instance

from ibm_watsonx_ai import APIClient client = APIClient(credentials, project_id)

Data loading

Download the legal documents dataset

import wget filename = "Legal_Sentences.csv" url = "https://raw.githubusercontent.com/kmokht1/Datasets/main/Legal_Sentences.csv" if not os.path.isfile(filename): wget.download(url, out=filename)

Read the data

import pandas as pd data = pd.read_csv("Legal_Sentences.csv", index_col=0) data = data[["Phrase", "Sentiment"]] data.head()

Replace numeric sentiment values with text labels

label_map = {-1: "negative", 0: "neutral", 1: "positive"} data["Sentiment"] = data["Sentiment"].replace(label_map)

Inspect data sample

data.value_counts(["Sentiment"])
Sentiment negative 282 positive 172 neutral 122 Name: count, dtype: int64

Split the data into training and test sets.

from sklearn.model_selection import train_test_split data_train, data_test, y_train, y_test = train_test_split( data["Phrase"], data["Sentiment"], test_size=0.3, random_state=33, stratify=data["Sentiment"], ) data_train = pd.DataFrame(data_train) data_test = pd.DataFrame(data_test)

Foundation Models on watsonx.ai

List available models

for model in client.foundation_models.TextModels: print(f"- {model}")
- ibm/granite-guardian-3-2b - ibm/granite-guardian-3-8b - meta-llama/llama-3-3-70b-instruct - mistralai/ministral-8b-instruct

You need to specify model_id that will be used for inferencing:

model_id = client.foundation_models.TextModels.GRANITE_GUARDIAN_3_2B

Defining the model parameters

You might need to adjust model parameters for different models or tasks, to do so please refer to documentation.

from ibm_watsonx_ai.metanames import GenTextParamsMetaNames as GenParams parameters = { GenParams.DECODING_METHOD: "greedy", GenParams.RANDOM_SEED: 33, GenParams.REPETITION_PENALTY: 1, GenParams.MIN_NEW_TOKENS: 1, GenParams.MAX_NEW_TOKENS: 1, }

Initialize the model

Initialize the ModelInference class with previous set params.

from ibm_watsonx_ai.foundation_models import ModelInference model = ModelInference( model_id=model_id, params=parameters, credentials=credentials, project_id=project_id )

Model's details

model.get_details()
{'model_id': 'ibm/granite-guardian-3-2b', 'label': 'granite-guardian-3-2b', 'provider': 'IBM', 'source': 'IBM', 'functions': [{'id': 'text_chat'}, {'id': 'text_generation'}], 'short_description': 'The Granite model series is a family of IBM-trained, dense decoder-only models, which are particularly well-suited for generative tasks.', 'long_description': 'Granite models are designed to be used for a wide range of generative and non-generative tasks with appropriate prompt engineering. They employ a GPT-style decoder-only architecture, with additional innovations from IBM Research and the open community.', 'terms_url': 'https://www.ibm.com/support/customer/csol/terms/?id=i126-6883&lc=en', 'input_tier': 'class_c1', 'output_tier': 'class_c1', 'number_params': '2b', 'min_shot_size': 1, 'task_ids': ['question_answering', 'summarization', 'classification', 'generation', 'extraction'], 'tasks': [{'id': 'question_answering'}, {'id': 'summarization'}, {'id': 'classification'}, {'id': 'generation'}, {'id': 'extraction'}], 'lifecycle': [{'id': 'available', 'since_version': '10.0.0', 'current_state': True}], 'versions': [{'version': '1.0.0', 'available_date': '0001-01-01'}]}

Define instructions for the model.

instruction = "Determine the sentiment of the sentence. Your response must contain either `positive`, `neutral`, or `negative`. Use the provided examples as a template."

Prepare model inputs for zero-shot example - use below zero_shot_inputs.

zero_shot_inputs = [{"input": text} for text in data_test["Phrase"]] for i in range(2): print(f"The sentence example {i+1} is:\n\t {zero_shot_inputs[i]['input']}\n")
The sentence example 1 is: The Court rejects the CCAs conclusion that Moore failed to make the requisite showings with respect to intellectual functioning The sentence example 2 is: He argues on appeal that had Defendants written truthful reports, or testified truthfully in deposition

Prepare model inputs for few-shot examples - use below few_shot_inputs.

data_train_and_labels = data_train.copy() data_train_and_labels["Sentiment"] = y_train
example_entries = data_train_and_labels.groupby("Sentiment").first() few_shot_examples_list = [ f"\tsentence:\t{phrase}\n\tsentiment: {sentiment}\n" for sentiment, phrase in example_entries["Phrase"].items() ] few_shot_examples = "".join(few_shot_examples_list)
few_shot_inputs = [{"input": text} for text in data_test["Phrase"]] for i in range(2): print(f"The sentence example {i+1} is:\n {few_shot_inputs[i]['input']}\n") print(f"\tSentiment: {y_test[i]}\n")
The sentence example 1 is: The Court rejects the CCAs conclusion that Moore failed to make the requisite showings with respect to intellectual functioning Sentiment: negative The sentence example 2 is: He argues on appeal that had Defendants written truthful reports, or testified truthfully in deposition Sentiment: negative

Get the docs summaries

results = [ model.generate_text( "\n".join([instruction, few_shot_examples, shot_input["input"], "Sentiment: "]) ) for shot_input in few_shot_inputs[:10] ]

Score the model

Note: To run the Score section for model scoring on the whole financial phrasebank dataset, please transform following markdown cells to code cells. Have in mind that scoring model on the whole test set can take significant amount of time.

Get the true labels

y_true = y_test.values[:10] y_true
['negative', 'neutral', 'negative', 'negative', 'negative', 'negative', 'negative', 'neutral', 'negative', 'positive']

Get the predicted labels

y_pred = [result.strip() for result in results] y_pred
['negative', 'negative', 'negative', 'negative', 'neutral', 'negative', 'negative', 'negative', 'negative', 'positive']

Calculate the accuracy score

from sklearn.metrics import accuracy_score print(accuracy_score(y_pred, y_true))
0.7

Summary and next steps

You successfully completed this notebook!

You learned how to find sentiments of legal documents with ibm/granite-guardian-3-2b on watsonx.

Check out our Online Documentation for more samples, tutorials, documentation, how-tos, and blog posts.

Authors:

Mateusz Szewczyk, Software Engineer at watsonx.ai.

Copyright © 2023-2025 IBM. This notebook and its source code are released under the terms of the MIT License.