Định luật Benford phần code – Minh họa bằng Python

13:23 26/12/2025

Định luật Benford (Benford’s Law), hay còn gọi là định luật chữ số đầu tiên, mô tả quy luật phân bố xác suất của chữ số đứng đầu trong nhiều tập dữ liệu tự nhiên. Để giúp người học dễ hình dung và kiểm chứng định luật này trong thực tế, FPT Polytechnic TP HCM sẽ hướng dẫn bạn cách sử dụng Python để phân tích dữ liệu và trực quan hóa kết quả.

Ta sẽ viết code để minh họa cho định luật

Mục tiêu của đoạn code

Đoạn chương trình được xây dựng nhằm:

  • Đọc dữ liệu từ file CSV (chứa các giá trị như doanh thu, dân số, số liệu thống kê…),
  • Trích xuất chữ số đầu tiên của mỗi giá trị,
  • So sánh phân bố thực tế với phân bố lý thuyết theo định luật Benford,
  • Trực quan hóa kết quả bằng biểu đồ cột và đường để dễ quan sát.

Code mẫu Python

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

# — Hàm xử lý công thức cho định luật Benford 

def benford_distribution():

    “””Trả về xác suất lý thuyết của các chữ số 1-9 theo định luật Benford”””

    return np.array([np.log10(1 + 1/d) for d in range(1, 10)])

# — Hàm trích chữ số đầu tiên 

def get_first_digits(series):

    “””Trích chữ số đầu tiên trong cột dữ liệu”””

    digits = []

    for value in series:

        try:

            s = str(value).strip().lstrip(‘-0.’)

            if s and s[0].isdigit():

                digits.append(int(s[0]))

        except:

            continue

    return digits

# — Hàm kiểm tra Benford từ DataFrame mẫu—

def check_benford_df(df, column_name):

    if column_name not in df.columns:

        print(f“Cột ‘{column_name}‘ không tồn tại trong DataFrame.”)

        print(“Các cột có sẵn:”, df.columns.tolist())

        return

    digits = get_first_digits(df[column_name])

    if not digits:

        print(“Không tìm thấy dữ liệu số hợp lệ.”)

        return

    # Phân bố thực tế

    observed, _ = np.histogram(digits, bins=np.arange(1, 11))

    observed = observed / len(digits)

    # Phân bố Benford kỳ vọng

    expected = benford_distribution()

    # — Vẽ biểu đồ —

    plt.figure(figsize=(8, 5))

    plt.bar(range(1, 10), observed, alpha=0.7, label=‘Thực tế‘)

    plt.plot(range(1, 10), expected, ‘ro-‘, label=‘Benford’)

    plt.xlabel(‘Chữ số đầu tiên’)

    plt.ylabel(‘Tần suất’)

    plt.title(f‘Kiểm tra định luật Benford cho cột “{column_name}“‘)

    plt.legend()

    plt.grid(True, alpha=0.3)

    plt.show()

# —————————————————–

# 1️ Sử dụng DataFrame mẫu trực tiếp

# —————————————————–

df_sample = pd.DataFrame({

    “TenCongTy”: [“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”],

    “DoanhThu”: [15432, 20149, 9812, 123000, 45821, 16789, 234501, 198765, 32190]

})

print(“=== Dữ liệu mẫu ===”)

print(df_sample)

check_benford_df(df_sample, “DoanhThu”)

# —————————————————–

# 2️.Sử dụng file CSV doanhthu.csv

# —————————————————–

# Nếu muốn dùng CSV, bỏ comment 3 dòng sau:

# csv_file = ‘doanhthu.csv’

# column_name = ‘DoanhThu’

# check_benford_df(pd.read_csv(csv_file), column_name)

Cách dùng

Chạy thử để xem một biểu đồ.

Chuẩn bị file CSV doanhthu_binhthuong.csv và doanhthu_gianlan.csv có cột chứa các số bạn muốn kiểm tra (hoặc lấy file tôi đã chuẩn bị sẵn). Sau đó sửa lệnh ở 3 dòng cuối.
Ví dụ:

TenCongTy DoanhThu
A 15432
B 20149
C 9812
D 123000

Kết quả

Biểu đồ hiển thị gồm:

  • Cột màu xanh: phân bố chữ số đầu tiên của dữ liệu thực tế,
  • Đường màu đỏ: phân bố lý thuyết theo định luật Benford.

Nếu hai đường gần trùng nhau, dữ liệu có khả năng là tự nhiên và không bị can thiệp. Ngược lại, nếu có sự lệch lớn, dữ liệu có thể tồn tại bất thường, sai sót hoặc dấu hiệu bị chỉnh sửa. Trong trường hợp tập dữ liệu nhỏ, việc sai lệch so với Benford là điều bình thường và cần được cân nhắc khi phân tích.

Giảng viên Nguyễn Đỗ Anh Khoa
Bộ môn Công nghệ thông tin
FPT Polytechnic TP HCM

Hỗ trợ tư vấn và giải đáp thông tin tuyển sinh FPT Polytechnic

Cùng chuyên mục

Đăng ký nhập học tại FPT Polytechnic 2026

  • Max. file size: 50 MB.
  • Max. file size: 50 MB.
  • Max. file size: 50 MB.