AI Cho Mọi Người

AI Cho Mọi Người

Số liệu thống kê (statistics) cơ bản

 

 

Chúng ta dùng Python để khám phá các số liệu thống kê, giúp ta hiểu hơn về dữ liệu mà ta đang có. Trong bài này, chúng ta sẽ học các thước đo từ đơn giản như trung bình (Mean), trung vị (Median), phân bố đến những phần nâng cao như phương sai, độ lệch chuẩn, và phần cuối trình bày thuật toán tính hệ số tương quan (correlation coefficient).

I. Mean

Giá trị trung bình là một khái niệm tổng quát khi nói đến một tập số liệu. Khi nói đến bộ số liệu nào đó, chúng ta hay nhắc đến trung bình của bộ số liệu đó. Chúng ta đều hiểu bản chất của khái niệm trung bình là lấy tổng của dãy số cho trước sau đó chia cho độ dài của dãy số. Công thức tính mean cho một list X các số như sau

trong đó, \(x_i\) là phần tử thứ i của X.

Ví dụ: Chúng ta có dãy số bên dưới đây thể hiện số tiền quyên góp của một tổ chức từ thiện trong 12 ngày qua, đơn vị USD:

100, 60, 70, 900, 100, 200, 500, 500, 503, 600, 1000, 1200.

Viết hàm để tính trung bình của một dãy số.

def calculate_mean(numbers): #1
    s = sum(numbers)         #2
    N = len(numbers)         #3
    mean = s/N               #4
    return mean              #5

# Tạo mảng donations đại diện cho số tiền quyên góp trong 12 ngày
donations = [100, 60, 70, 900, 100, 200, 500, 500, 503, 600, 1000,1200]

mean_value = calculate_mean(donations)
print('Trung bình số tiền quyên góp là: ', mean_value)

#1. Bước đầu tiên ta xác định hàm cần tính, đặt tên là calculate_mean(), hàm này sẽ nhận đối số numbers, là chuỗi các số cần tính trung bình.

#2. Sử dụng hàm sum() để tính tổng dãy số cho trước.

#3. Sử dụng hàm len() để tính chiều dài của dãy số cần tính.

#4. Tính trung bình của dãy số trên bằng cách lấy tổng chia cho chiều dài.

#5. Cuối cùng ta cho hàm trả về giá trị mean tính được.

 

Kết quả

Trung bình số tiền quyên góp là: 477.75

 

II. Median

Số trung vị là một số đứng ở vị trí giữa trong dãy số đã được sắp xếp theo thứ tự tăng dần, median chia dãy số cho trước thành 2 nửa bằng nhau. Nếu độ dài của dãy số là số lẻ, thì số ở giữa là median, nếu chiều dài của dãy số là số chẵn thì median được xác định bằng cách lấy trung bình của hai số ở giữa.

Ví dụ: Chúng ta sử dụng lại dãy số liệu thể hiện số tiền quyên góp của một tổ chức từ thiện trong 12 ngày qua, đơn vị USD:

100, 60, 70, 900, 100, 200, 500, 500, 503, 600, 1000, 1200

Xây dựng hàm tính median.

def calculate_median(numbers):                      #1
    N = len(numbers)                                #2
    numbers.sort()                                  #3
    if N%2 == 0:                                    #4
        m1 = N/2
        m2 = (N/2) + 1
        m1 = int(m1)-1
        m2 = int(m2)-1
        median = (numbers[m1] + numbers[m2])/2
    else:                                           #5
        m = (N+1)/2
        m = int(m)-1
        median = numbers[m]
    return median                                   #6

donations = np.array([100, 60, 70, 900, 100, 200, 500, 500, 503, 600, 1000,1200])
meadian_value = calculate_median(donations)

print('Trung vị số tiền quyên góp là: ', meadian_value)

#1. Xác định hàm cần tính, đặt tên calculate_median; hàm này sẽ nhận đối số là chuỗi số numbers.

#2. Tính chiều dài của chuỗi số numbers, đại diện bởi biến N

#3. Sắp xếp chuỗi số numbers từ nhỏ đến lớn.

#4. Tính median: Nếu chiều dài của chuỗi số numbers là số lẻ, thì số trung vị là số ở vị trí chính giữa, nghĩa là (N + 1)/2. Nếu chiều dài của numbers là số chẵn thì lấy 2 phần tử ở giữa là N/2(N/2) + 1, đại diện bởi biến m1m2. Sau đó, lấy phần nguyên của phép chia rồi trừ một để lấy được vị trí của 2 phần tử. Cuối cùng ta lấy giá trị trung bình của 2 phần từ vừa tìm được.

#5. Hàm trả về giá trị trung vị tính ở bước 4

 

Kết quả

Trung vị số tiền quyên góp là:  500.0

 

III. Mode

Mode trả về phần tử có số lần xuất hiện nhiều nhất trong dãy số cho trước. Ví dụ, ta có điểm thi toán của 20 học sinh với thang 10 điểm:

7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10

Mode sẽ giúp ta trả lời câu hỏi: “Điểm số nào được học sinh đạt nhiều nhất?”. Ở ví dụ trên, quan sát cho chúng ta thấy được điểm 9 xuất hiện nhiều nhất. Do đó, mode = 9.

Cách tính mode được thực hiện như sau: với mỗi giá trị trong chuỗi số, đếm số lần xuất hiện của giá trị đó. Sau đó, trả về giá trị mà có số lần xuất hiện nhiều nhất.

Python cung cấp hàm most_common() để tính để tính số lần xuất hiện của một phần tử. Hàm này trả về một list các tuple (phần_tử, số_lần_xuất_hiện) được sắp xếp theo thứ tự giảm dần theo số_lần_xuất_hiện.

# import packages Counter để đếm số lần xuất hiện của mỗi giá trị trong chuỗi
from collections import Counter

# data
points = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10]

def calculate_mode(numbers): #1
    c = Counter(numbers)     #2
    mode = c.most_common(1)  #3
    return mode[0][0]        #4

print('Mode của chuỗi số đã cho: ', calculate_mode(points))

#1. Xác đinh hàm cần tìm, đặt tên calculate_mode, hàm này nhận đối số numbers truyền vào.

#2. Dùng hàm counter để đếm số lần xuất hiện của mỗi phần tử trong chuỗi, đại diện bởi biến c.

#3. Dùng most_common(), truyền vào 1, trả về giá trị và số lần xuất hiện của phần tử xuất hiện nhiều nhất, đại diện bởi biến mode.

#4. Trả về phần giá trị của mode được tính ở bước 3.

 

Kết quả

Mode của chuỗi số đã cho:  9

 

Trong trường hợp dãy số truyền vào có nhiều phần tử có mật độ xuất hiện giống nhau, chúng ta cần trả về toàn bộ các mode đó.

# import packages Counter để đếm số lần xuất hiện của mỗi giá trị trong chuỗi
from collections import Counter

# data
points = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10, 6, 6]

def calculate_mode(numbers):            #1
    c = Counter(numbers)                #2 
    numbers_freq = c.most_common()      #3
    max_count = numbers_freq[0][1]      #4
    modes = []                          #5
    for num in numbers_freq:
        if num[1] == max_count:         #6
             modes.append(num[0])
    return modes

print('Mode của dãy số points: ', calculate_mode(points))

#1. Xác đinh hàm cần tìm, đặt tên calculate_mode, hàm này nhận đối số numbers truyền vào.

#2. Dùng hàm counter để đếm số lần xuất hiện của mỗi phần tử trong chuỗi, đại diện bởi biến c.

#3. Dùng most_common(), trả về giá trị và số lần xuất hiện của mỗi phần tử, đại diện bởi biến number_freq.

#4. Theo sắp xếp của hàm most_common, vị trí đầu tiên chứa giá trị và số lần xuất hiện nhiền nhất, nên ta cần lấy số lần xuất hiện của giá trị xuất hiện nhiều nhất, đại diện bởi biến max_count.

#5. Tạo một chuỗi rỗng để chứa giá trị.

#6. Với lần lượt từng cặp giá trị trong bước 3 tính được, so sánh với max_count của bước 4 trả về, nếu bằng max_count thì bỏ giá trị phần tử vào mảng rỗng tạo ở bước 5

 

Kết quả

Mode của dãy số points:  [9, 6]

 

Nếu chúng ta muốn trình bày toàn bộ số lần xuất hiện cùng giá trị của chuỗi thành bảng, chúng ta làm như sau:

# import packages Counter để đếm số lần xuất hiện của mỗi giá trị trong chuỗi
from collections import Counter

# data
points = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10, 6, 6]

def frequency_table(numbers):               #1
    table = Counter(numbers)                #2
    numbers_freq = table.most_common()      #3
    numbers_freq.sort()                     #4
    print('Number\tFrequency')              #5
    for number in numbers_freq:             #6
        print('{0}\t{1}'.format(number[0], number[1]))
        
frequency_table(points)

#1. Xác đinh hàm cần tìm, đặt tên frequency_table, hàm này nhận đối số numbers truyền vào.

#2. Dùng hàm counter để đếm số lần xuất hiện của mỗi phần tử trong chuỗi, đại diện bởi biến table.

#3. Dùng most_common(), trả về giá trị và số lần xuất hiện của mỗi phần tử, đại diện bởi biến number_freq.

#4. Vì hàm most_common sắp xếp theo số lần xuất hiện nhưng ta đang cần sắp xếp theo giá trị phần tử, nên chúng ta dùng sort().

#5. Tạo bảng với cột trái là giá trị phần tử, cột phải là số lần xuất hiện. \t tạo ra khoảng trống giữa 2 giá trị.

#6. Với lần lượt từng cặp giá trị trong bước 4 tính được, in giá trị phần tử trước rồi khoảng trống rồi số lần xuất hiện. Hàm format dùng để truyền giá trị vào các phần tử trước đó được bỏ trong cặp ngoặc {}.

 

Kết quả

Number	Frequency
1	2
2	1
4	1
5	2
6	5
7	2
8	2
9	5
10	2

 

IV. Range of data

Độ phân tán (range) của dữ liệu cho biết dữ liệu chúng ta có giá trị trải rộng như thế nào. Ví dụ, nếu chỉ quan tâm đến trung bình thì có khi ta đánh giá sai dữ liệu. Độ phân tán dữ liệu đơn giản là độ lệch giữa giá trị lớn nhất và giá trị nhỏ nhất của tập dữ liệu.

def find_range(numbers):        #1
    lowest  = min(numbers)      #2
    highest = max(numbers)      #3
    r = highest-lowest          #4
    print('Lowest: {0}\tHighest: {1}\tRange: {2}'.format(lowest, highest, r))

# data
points = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10, 6, 6]
find_range(points)

#1. Xác đinh hàm cần tìm, đặt đến là find_range, hàm nhận đối số numbers cho trước.

#2. Dùng hàm min tính giá trị nhỏ nhất của list numbers, đại diện bởi biến `lowest`.

#3. Dùng hàm max tính giá trị lớn nhất của list numbers, đại diện bởi biến highest.

#4. Tính range của list numbers bằng cách lấy giá trị lớn nhất trừ giá trị nhỏ nhất, đại diện bởi biến r.

 

Kết quả

Lowest: 1	Highest: 10	Range: 9

 

V. Variance

Phương sai (variance) cho ta biết các giá trị trong tập dữ liệu có khác biệt nhiều với giá trị trung bình của cả tập hay không? Đánh giá mức độ phân tán của dữ liệu so với giá trị trung bình. Nếu muốn tính độ lệch chuẩn chỉ cần lấy căn bậc hai của phương sai.

Công thức của variance: Lấy từng giá trị của tập dữ liệu trừ cho giá trị trung bình của cả tập, bình phương và chia cho số lượng phần tử có trong chuỗi.

trong đó, \(\mu\)là giá trị mean của tập dữ liệu và \(x_i\) là giá trị thứ i trong tập dữ liệu.

Code để tính variance như sau

# data
points = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4, 5, 6, 1, 5, 6, 7, 8, 6, 1, 10]

def calculate_mean(numbers):                    #1
    s = sum(numbers)
    N = len(numbers)
    mean = s/N
    return mean

def caculate_variance(numbers):                 #2
    mean = calculate_mean(numbers)              #3
    
    diff = []                                   #4
    for num in numbers: 
         diff.append(num-mean)
            
    squared_diff = []                           #5
    for d in diff:
        squared_diff.append(d**2)
        sum_squared_diff = sum(squared_diff)
        variance = sum_squared_diff/len(numbers)
        
    return variance

print('Phương sai của dãy số là: ', caculate_variance(points))
print('Độ lệch chuẩn của dãy số là: ', caculate_variance(points)**0.5)

#1. Trong công thức cần phép tính trung bình nên ta dùng lại hàm calculate_mean() phía trên.

#2. Xác định hàm cần tìm, đặt đến là caculate_variance, hàm nhận đối số numbers cho trước.

#3. Tính giá trị trung bình của dãy numbers cho trước, đại diện bởi biến mean.

#4. Tạo mảng diff rỗng, với mỗi giá trị của dãy numbers, đem trừ cho mean rồi bỏ kết quả vào mảng diff

#5. Tạo mảng squared_diff rỗng, với mỗi giá trị của mảng diff ở bước 4, bình phương mỗi giá trị, cộng dồn toàn bộ giá trị của mảng và chia cho chiều dài của mảng.

#6. Trả kết quả phương sai.

 

Kết quả

Phương sai của dãy số là:  7.647499999999999
Độ lệch chuẩn của dãy số là:  2.7654113618049663

 

VI. CORRELATION COEFFECIENT

Khi phân tích hồi quy tuyến tính thì yêu cầu hai biến độc lập phải có mối quan hệ tuyến tính với nhau. Khi đó ta đánh giá qua hệ số tương quan. Hệ số tương quan thể hiện mối quan hệ tương quan tuyến tính giữa hai biến, hệ số tương quan nằm trong khoảng [-1; 1],

– Khi hệ số tương quan bằng 0 thì ta kết luận hai biến không có tương quan tuyến tính với nhau (nhưng không chắc chúng độc lập).

– Khi hệ số gần bằng 1 thì ta nói có mối quan hệ tuyến tính dương (cùng tăng hoặc cùng giảm).

– khi hệ số gần bằng -1 thì ta nói hai biến số có mối quan hệ tuyến tính âm (x giảm y tăng và ngược lại).

Lưu ý rằng tương quan tuyến tinh khác với mối quan hệ nhân quả, giả sử khi hệ số tương quan là dương thì ta chỉ được kết luận hai biến có mối quan hệ tuyến tính dương thôi. Ví dụ vào mùa hè, doanh số bán đồ tắm tăng mạnh và số lượng kem bán ra cũng tăng mạnh, khi xét hệ số tuyến tính có kết quả dương gần 1 ta không thể kết luận do lượng kem bán ra nhiều làm tăng doanh số bán áo tắm.

Công thức tính hệ số tương quan của hai biến XY

$$\begin{array}{l}
\rho _{xy} = \frac{{E\left[ {\left( {x – \mu _x } \right)\left( {y – \mu _y } \right)} \right]}}{{\sqrt {{\mathop{\rm var}} \left( x \right)} \sqrt {{\mathop{\rm var}} \left( y \right)} }} \\
\,\,\,\,\,\,\,\, = \frac{{\frac{1}{n}\sum\limits_i {\left( {x_i – \mu _x } \right)\left( {y_i – \mu _y } \right)} }}{{\sqrt {\frac{1}{n}\sum\limits_i {\left( {x_i – \mu _x } \right)^2 } } \sqrt {\frac{1}{n}\sum\limits_i {\left( {y_i – \mu _y } \right)^2 } } }} \\
\,\,\,\,\,\,\,\, = \frac{{n\left( {\sum\limits_i {x_i y_i } } \right) – \left( {\sum\limits_i {x_i } } \right)\left( {\sum\limits_i {y_i } } \right)}}{{\sqrt {n\sum\limits_i {x_i^2 – \left( {\sum\limits_i {x_i } } \right)^2 } } \sqrt {n\sum\limits_i {y_i^2 – \left( {\sum\limits_i {y_i } } \right)^2 } } }} \\
\end{array}$$

 

Code để tính hệ số tương quan như sau

# aivietnam.ai

def find_corr_x_y(x,y):                                         #1
    n = len(x)                                                  #2
    prod = []
    for xi,yi in zip(x,y):                                      #3
         prod.append(xi*yi)
         
    sum_prod_x_y = sum(prod)                                    #4
    
    sum_x = sum(x)
    sum_y = sum(y)
    
    squared_sum_x = sum_x**2
    squared_sum_y = sum_y**2 
    
    x_square = []
    for xi in x:
        x_square.append(xi**2)            
    x_square_sum = sum(x_square)

    y_square=[]
    for yi in y:
        y_square.append(yi**2)        
    y_square_sum = sum(y_square)
    
    # Use formula to calculate correlation                      #5
    numerator = n*sum_prod_x_y - sum_x*sum_y
    denominator_term1 = n*x_square_sum - squared_sum_x
    denominator_term2 = n*y_square_sum - squared_sum_y
    denominator = (denominator_term1*denominator_term2)**0.5
    correlation = numerator/denominator
    
    return correlation 

x = [7, 18, 29, 2, 10, 9, 9]
y = [1, 6, 12, 8, 6, 21, 10]
print('Hệ số tương quan tuyến tính giữa hai biến x,y: ',find_corr_x_y(x,y))

#1. Trong công thức phép tính hệ số tương quan, n là chiều dài của dữ liệu.

#2. Xác đinh hàm cần tìm, đặt đến là find_corr_x_y, hàm nhận đối số X và Y cho trước.

#3. Trong công thức, chủ yếu là phép nhân X.Y nên ta dùng hàm zip để ghép 2 mảng X, Y thành table rồi hàm in để chỉ tới phần tử cần tính.

#4. Tính tổng của tích X.Y .

#5. Thay lần lượt vào công thức.

#6. Trả về kết quả hệ số tương quan giữa X và Y.

 

Kết quả

Hệ số tương quan tuyến tính giữa hai biến x,y:  0.14953944411984518

 

Ứng dụng hệ số tương quan để tính similarity giữa 2 ảnh

Hệ số tương quan được ứng dụng rất nhiều trong việc tính mức độ tương quan giữa 2 biến ngẫu nhiên trong nhiều lĩnh vực. Nếu chúng ta xem điểm ảnh (pixel) là một biến ngẫu nhiên với các giá trị nằm trong đoạn [0, 255] cho ảnh grayscale. Với ảnh màu, pixel thường có 3 kênh màu (x, y, z), trong đó x, y, z nằm trong đoạn [0, 255].

Với 1 ảnh màu có hình dạng là (50, 50, 3), trong đó chiều cao và chiều rồng là 50 và số kênh màu là 3. Chúng ta có thể kéo ảnh có hình khối như trên thành dạng dữ liệu kiểu List với chiều dài là 50x50x3.

Hình trên hiển thị 4 ảnh traffic sign, trong đó có 3 loại traffic sign. Hình img1 và hình img2 cùng một loại traffic sign và hình img3 và img4 khác loại. Chúng ta thử kiểm tra khả năng hoạt động của hệ số tương quan cho các cặp (img1, img2), (img1, img3), và (img1, img4).

Đoạn code sau chứa vài hàm để đọc hình và chuyển sang kiểu dữ liệu List mà bài học chưa nói đến. Các bạn có thể tìm hiểu thêm hoặc dùng các hàm đó như black-box.

# aivietnam.ai

import numpy as np
from PIL import Image

# load ảnh và chuyển về kiểu list
image1 = Image.open('images/img1.png')
image2 = Image.open('images/img2.png')
image3 = Image.open('images/img3.png')
image4 = Image.open('images/img4.png')

image1_list = np.asarray(image1).flatten().tolist()
image2_list = np.asarray(image2).flatten().tolist()
image3_list = np.asarray(image3).flatten().tolist()
image4_list = np.asarray(image4).flatten().tolist()


# tính correlation coefficient
corr_1_2 = find_corr_x_y(image1_list, image2_list)
corr_1_3 = find_corr_x_y(image1_list, image3_list)
corr_1_4 = find_corr_x_y(image1_list, image4_list)

print('corr_1_2:', corr_1_2)
print('corr_1_3:', corr_1_3)
print('corr_1_4:', corr_1_4)

 

Kết quả

corr_1_2: 0.5597078993054261
corr_1_3: 0.23464323667481513
corr_1_4: 0.3044435718683657

 

Chúng ta thấy rằng hệ số tương quan giữa cặp img1 và img2 có giá trị cao hơn 2 cặp còn lại. Nếu chúng ta xem các ảnh img2, img3, img4 là các mẫu ảnh có sẵn trong hệ thống, và img1 là ảnh input được yêu cầu phân loại; thì hệ số tương quan đã giúp chúng ta xác đinh được ảnh input (ảnh img1) giống với ảnh img2 nhất và chúng ta có thể kết luận ảnh input có cùng loại traffic sign với ảnh img2.

Code trên có thể thay đổi để lấy dữ liệu ảnh từ internet. Các bạn có thể dùng các link ảnh trong đoạn code sau để lấy dữ liệu ảnh.

# aivietnam.ai

import numpy as np
from PIL import Image
from io import BytesIO
import requests

def find_corr_x_y(x,y):                                         
    n = len(x)                                                  
    prod = []
    for xi,yi in zip(x,y):                                      
         prod.append(xi*yi)
         
    sum_prod_x_y = sum(prod)                                    
    
    sum_x = sum(x)
    sum_y = sum(y)
    
    squared_sum_x = sum_x**2
    squared_sum_y = sum_y**2 
    
    x_square = []
    for xi in x:
        x_square.append(xi**2)            
    x_square_sum = sum(x_square)

    y_square=[]
    for yi in y:
        y_square.append(yi**2)        
    y_square_sum = sum(y_square)
    
    # Use formula to calculate correlation                      
    numerator = n*sum_prod_x_y - sum_x*sum_y
    denominator_term1 = n*x_square_sum - squared_sum_x
    denominator_term2 = n*y_square_sum - squared_sum_y
    denominator = (denominator_term1*denominator_term2)**0.5
    correlation = numerator/denominator
    
    return correlation 


# load ảnh và chuyển về kiểu list
req1 = requests.get('https://www.dropbox.com/s/vfe090qo24t3v46/img1.png?raw=1')
req2 = requests.get('https://www.dropbox.com/s/vtz8ik7mb1e1is7/img2.png?raw=1')
req3 = requests.get('https://www.dropbox.com/s/auxezlf6ijoejwo/img3.png?raw=1')
req4 = requests.get('https://www.dropbox.com/s/w5oc29l57f77arp/img4.png?raw=1')

image1 = Image.open(BytesIO(req1.content))
image2 = Image.open(BytesIO(req2.content))
image3 = Image.open(BytesIO(req3.content))
image4 = Image.open(BytesIO(req4.content))

image1_list = np.asarray(image1).flatten().tolist()
image2_list = np.asarray(image2).flatten().tolist()
image3_list = np.asarray(image3).flatten().tolist()
image4_list = np.asarray(image4).flatten().tolist()

corr_1_2 = find_corr_x_y(image1_list, image2_list)
corr_1_3 = find_corr_x_y(image1_list, image3_list)
corr_1_4 = find_corr_x_y(image1_list, image4_list)

print('corr_1_2:', corr_1_2)
print('corr_1_3:', corr_1_3)
print('corr_1_4:', corr_1_4)

 

Kết quả

corr_1_2: 0.5597078993054261
corr_1_3: 0.23464323667481513
corr_1_4: 0.3044435718683657

 

Một tính chất quan trọng của hệ số tương quan là khả năng hoạt động tốt với linear transformation (dữ liệu thay đổi dạng tuyến tính).  Hình bên dưới hiển thị ảnh img1, img5 và img6. Trong đó img5 = img1 + 50 và img6 = img1*1.2 + 10.

Tính hệ số tương quan cho cặp (img1, img5) và (img1, img6).

# aivietnam.ai

import numpy as np
from PIL import Image
from io import BytesIO
import requests


# load ảnh và chuyển về kiểu list
req1 = requests.get('https://www.dropbox.com/s/vfe090qo24t3v46/img1.png?raw=1')
req5 = requests.get('https://www.dropbox.com/s/wdj080tsf92a0l0/img1_scale2.png?raw=1')
req6 = requests.get('https://www.dropbox.com/s/9fr6h5y9vejyl7h/img1_scale1.png?raw=1')

image1 = Image.open(BytesIO(req1.content))
image5 = Image.open(BytesIO(req5.content))
image6 = Image.open(BytesIO(req6.content))

image1_list = np.asarray(image1).flatten().tolist()
image5_list = np.asarray(image5).flatten().tolist()
image6_list = np.asarray(image6).flatten().tolist()


# tính correlation coefficient
corr_1_5 = find_corr_x_y(image1_list, image5_list)
corr_1_6 = find_corr_x_y(image1_list, image6_list)

print('corr_1_5:', corr_1_5)
print('corr_1_6:', corr_1_6)

 

Kết quả

corr_1_5: 0.9970069053677388
corr_1_6: 0.9979081493981881

 

Chúng ta thấy rằng hệ số tương quan gần như tuyệt đối cho 2 cặp ảnh trên mặc dù ảnh img5 và img6 đã bị thay đổi (tuyến tính). Liên hệ lại bài toán phân loại traffic sign, dù hình input (img1) có thể có các điều kiện ánh sáng khác nhau, thì hệ thống vẫn có thể hoạt động tốt khi hệ số tương quan không bị ảnh hưởng bởi linear transformation.

Các bạn có thể chỉnh sửa hoặc chạy các ví dụ tương tự với đoạn code sau

# aivietnam.ai

import numpy as np
from PIL import Image
from io import BytesIO
import requests

def find_corr_x_y(x,y):                                         #1
    n = len(x)                                                  #2
    prod = []
    for xi,yi in zip(x,y):                                      #3
         prod.append(xi*yi)
         
    sum_prod_x_y = sum(prod)                                    #4
    
    sum_x = sum(x)
    sum_y = sum(y)
    
    squared_sum_x = sum_x**2
    squared_sum_y = sum_y**2 
    
    x_square = []
    for xi in x:
        x_square.append(xi**2)            
    x_square_sum = sum(x_square)

    y_square=[]
    for yi in y:
        y_square.append(yi**2)        
    y_square_sum = sum(y_square)
    
    # Use formula to calculate correlation                      #5
    numerator = n*sum_prod_x_y - sum_x*sum_y
    denominator_term1 = n*x_square_sum - squared_sum_x
    denominator_term2 = n*y_square_sum - squared_sum_y
    denominator = (denominator_term1*denominator_term2)**0.5
    correlation = numerator/denominator
    
    return correlation 

# load ảnh và chuyển về kiểu list
req1 = requests.get('https://www.dropbox.com/s/vfe090qo24t3v46/img1.png?raw=1')
req5 = requests.get('https://www.dropbox.com/s/wdj080tsf92a0l0/img1_scale2.png?raw=1')
req6 = requests.get('https://www.dropbox.com/s/9fr6h5y9vejyl7h/img1_scale1.png?raw=1')

image1 = Image.open(BytesIO(req1.content))
image5 = Image.open(BytesIO(req5.content))
image6 = Image.open(BytesIO(req6.content))

image1_list = np.asarray(image1).flatten().tolist()
image5_list = np.asarray(image5).flatten().tolist()
image6_list = np.asarray(image6).flatten().tolist()


# tính correlation coefficient
corr_1_5 = find_corr_x_y(image1_list, image5_list)
corr_1_6 = find_corr_x_y(image1_list, image6_list)

print('corr_1_5:', corr_1_5)
print('corr_1_6:', corr_1_6)

 

Kết quả

corr_1_5: 0.9970069053677388
corr_1_6: 0.9979081493981881

 

 

Bài tập: Dựa vào công thức tính hệ số tương quan, hãy chứng minh khả năng hoạt động tốt của hệ số tương quan dưới điều kiện dữ liệu thay đổi dạng tuyến tính. Nghĩa là chứng minh

$$\rho (X, Y) = \rho (X, Y*a + b)$$