Khi training, thuật toán này không học một điều gì từ dữ liệu training đây cũng là lý do thuật toán này được xếp vào loại lazy learning, mọi tính toán được thực hiện khi nó cần dự đoán k
Trang 1TRƯỜNG ĐẠI HỌC HẢI PHÒNG KHOA CÔNG NGHỆ THÔNG TIN
BÀI BÁO CÁO
Môn: Nhập Môn Trí Tuệ Nhân Tạo
Đề tài: Thuật toán nhận dạng ký tự viết tay
Nhóm sinh viên thực hiện: Nguyễn Duy Nam
Trịnh Đức Toàn Hoàng Anh Thế
Hải Phòng 04/2022
Trang 2Đề Tài Thuật Toán Nhận Dạng Ký Tự Viết Tay
1.Thuật toán giải quyết đề tài
1.1 Giới thiệu thuật toán KNN(K-nearest neighbor)
K-nearest neighbor là một trong những thuật toán supervised-learning đơn giản nhất (mà hiệu quả trong một vài trường hợp) trong Machine Learning Khi training, thuật toán này không học một điều gì từ dữ liệu training (đây cũng là lý do thuật toán này được xếp vào loại lazy learning), mọi tính toán được thực hiện khi
nó cần dự đoán kết quả của dữ liệu mới K-nearest neighbor có thể áp dụng được vào cả hai loại của bài toán Supervised learning là Classification và Regression
Với KNN, trong bài toán Classification, label của một điểm dữ liệu mới (hay kết quả của câu hỏi trong bài thi) được suy ra trực tiếp từ K điểm dữ liệu gần nhất trong training set Label của một test data có thể được quyết định bằng major voting (bầu chọn theo số phiếu) giữa các điểm gần nhất, hoặc nó có thể được suy
ra bằng cách đánh trọng số khác nhau cho mỗi trong các điểm gần nhất đó rồi suy
ra label Chi tiết sẽ được nêu trong phần tiếp theo
Trong bài toán Regresssion, đầu ra của một điểm dữ liệu sẽ bằng chính đầu ra của điểm dữ liệu đã biết gần nhất (trong trường hợp K=1), hoặc là trung bình có trọng
số của đầu ra của những điểm gần nhất, hoặc bằng một mối quan hệ dựa trên khoảng cách tới các điểm gần nhất đó
Một cách ngắn gọn, KNN là thuật toán đi tìm đầu ra của một điểm dữ liệu mới bằng cách chỉ dựa trên thông tin của K điểm dữ liệu trong training set gần nó nhất (K-lân cận), không quan tâm đến việc có một vài điểm dữ liệu trong những điểm gần nhất này là nhiễu Hình dưới đây là một ví dụ về KNN trong classification với
K = 1
Ví dụ :
Giả sử ta có D là tập các dữ liệu đã được phân loại thành 2 nhãn (+) và (-) được biểu diễn trên trục tọa độ như hình vẽ và một điểm dữ liệu mới A chưa biết nhãn Vậy làm cách nào để chúng ta có thể xác định được nhãn của A là (+) hay (-)?
Có thể thấy cách đơn giản nhất là so sánh tất cả các đặc điểm của dữ liệu A với
Trang 3tất cả tập dữ liệu học đã được gắn nhãn và xem nó giống cái nào nhất, nếu dữ liệu (đặc điểm) của A giống với dữ liệu của điểm mang nhãn (+) thì điểm A mang nhãn (+), nếu dữ liệu A giống với dữ liệu nhãn (-) hơn thì nó mang nhãn (-), trông có vẻ rất đơn giản nhưng đó là những gì mà KNN làm
Trong trường hợp của KNN, thực tế nó không so sánh dữ liệu mới (không được phân lớp) với tất cả các dữ liệu khác, thực tế nó thực hiện một phép tính toán học
để đo khoảng cách giữa dữ liệu mới với tất cả các điểm trong tập dữ liệu học D để thực hiện phân lớp Phép tính khoảng cách giữa 2 điểm có thể là Euclidian, Manhattan, trọng số, Minkowski, …
Các bước trong KNN
1 Ta có D là tập các điểm dữ liệu đã được gắn nhãn và A là dữ liệu chưa được phân loại
2 Đo khoảng cách (Euclidian, Manhattan, Minkowski, Minkowski hoặc Trọng số) từ dữ liệu mới A đến tất cả các dữ liệu khác đã được phân loại trong D
3 Chọn K (K là tham số mà bạn định nghĩa) khoảng cách nhỏ nhất
4 Kiểm tra danh sách các lớp có khoảng cách ngắn nhất và đếm số lượng của mỗi lớp xuất hiện
5 Lấy đúng lớp (lớp xuất hiện nhiều lần nhất)
6 Lớp của dữ liệu mới là lớp mà bạn đã nhận được ở bước 5
Trang 4Ưu điểm
1 Thuật toán đơn giản, dễ dàng triển khai
2 Độ phức tạp tính toán nhỏ
3 Xử lý tốt với tập dữ liệu nhiễu
Nhược điểm
1 Với K nhỏ dễ gặp nhiễu dẫn tới kết quả đưa ra không chính xác
2 Cần nhiều thời gian để thực hiện do phải tính toán khoảng cách với tất cả các đối tượng trong tập dữ liệu
3 Cần chuyển đổi kiểu dữ liệu thành các yếu tố định tính
1.2 Diễn giải thuật toán bằng C++
1.2.1 CODE
#include <bits/stdc++.h>
using namespace std;
struct Point{
int val; // class cua point
double x, y;
double distance;
};
int phanLopKnn(Point arr[], int n, int k, Point p)
Trang 5{
arr[i].distance = sqrt(((arr[i].x - p.x)*(arr[i].x - p.x)) + ((arr[i].y - p.y)*(arr[i].y - p.y)) ); }
for(int i=0;i<n-1;i++)
{
for(int j = i+1; j<n;j++)
{
if(arr[i].distance > arr[j].distance)
{
swap(arr[i], arr[j]);
}
}
}
int dem1 = 0;
int dem2 = 0;
for(int i=0;i<k;i++)
{
if(arr[i].val == 0)
{
Trang 6else if(arr[i].val == 1) {
dem2++; }
}
if(dem1 > dem2) {
return 0;
}
else{
return 1;
}
}
int main()
{
int n = 17;
Point arr[n];
arr[0].x = 1; arr[0].y = 12; arr[0].val = 0;
Trang 7arr[1].y = 5; arr[1].val = 0;
arr[2].x = 5; arr[2].y = 3; arr[2].val = 1;
arr[3].x = 3; arr[3].y = 2; arr[3].val = 1;
arr[4].x = 3; arr[4].y = 6; arr[4].val = 0;
arr[5].x = 1.5; arr[5].y = 9; arr[5].val = 1;
arr[6].x = 7; arr[6].y = 2; arr[6].val = 1;
Trang 8arr[7].y = 1; arr[7].val = 1;
arr[8].x = 3.8; arr[8].y = 3; arr[8].val = 1;
arr[9].x = 3; arr[9].y = 10; arr[9].val = 0;
arr[10].x = 5.6; arr[10].y = 4; arr[10].val = 1;
arr[11].x = 4; arr[11].y = 2; arr[11].val = 1;
arr[12].x = 3.5; arr[12].y = 8; arr[12].val = 0;
Trang 9arr[13].y = 11;
arr[13].val = 0;
arr[14].x = 2;
arr[14].y = 5;
arr[14].val = 1;
arr[15].x = 2;
arr[15].y = 9;
arr[15].val = 0;
arr[16].x = 1;
arr[16].y = 7;
arr[16].val = 0;
Point p;
p.x = 5.5;
p.y = 1;
int nhom = phanLopKnn(arr, n, 3, p); cout<<"Nhom la: "<<nhom<<endl;
Trang 10Mỗi lần thay đổi k trong hàm phanLopKnn() ta sẽ được kết quả khác nhau(số k phải vừa với số phần tử được so sánh với chủ thể,số k càng lớn độ chính xác càng cao)
1.3 Giải quyết đề tài bằng thuật toán KNN với python
1.3.1 CODE
1.3.2 GIẢI THÍCH CODE
1.3.2.1:
Để giải quyết đề tài,trước tiên phải cần thao tác giữ liệu để luyện giải thuật +Thư viện numpy:cho phép thao tác với mảng
+Thư viện cv2:cho phép them ảnh và thao tác ảnh
Trang 11+Thư viện matplotlib: Dùng để thiết kế đồ thị trong quá trình thực hiện chương trình
1.3.2.2:
Trước tiên ta cần đọc dữ liệu ảnh để cho AI luyện,ta chỉnh toàn bộ màu của ảnh về màu xám
1.3.2.3:
Tiếp theo chúng ta sẽ cắt 1 nửa bức ảnh ra thành nhiều phần,mục đích là để AI train,ta sẽ lưu những bức ảnh vừa cắt vào biến Cell
1.3.4:
Sau khi cắt,ta chuyển những ảnh vừa cắt về dạng mảng
1.3.6:
Ta chuyển những mảng vừa rồi về dạng mảng 1 chiều với kiểu dữ liệu float Một nửa dữ liệu ta sẽ để train,còn lại để test
1.3.7:
Ta tạo 1 biến k để chứa giá trị từ 1-9
1.3.8:
Ta thực hiện gán nhãn cho giữ liệu train bằng mảng k vừa khởi tạo
1.3.9:
Khởi tạo thuật toán KNN
Trang 12Câu lệnh để train AI,với dữ liệu là train và nhãn là train_labels
1.3.11:
Cho AI nhận dạng với dữ liệu test,AI sẽ tìm theo 5 hàng xóm gần nhất,do kết quả đầu ra khá phức tạp,nên sẽ lưu kết quả vào 4 biến k1,k2,k3,k4
1.3.11:
Với lệnh: print k2 ,ta được kết quả 1 mảng với các giá trị từ 0-9,điều này cho thấy
AI đã nhận diện thành công ký tự viết tay
Với lệnh: print k2[505],ta được kết quả là 2,điều này chứng tỏ AI đã nhận diện thành công bức ảnh số 505 là số 2
2 Kết luận
Trang 13Thuật toán KNN có thể hữu ích trong trường hợp dữ liệu phi tuyến Nó có thể được sử dụng với bài toán hồi quy Giá trị đầu ra cho đối tượng được tính bằng giá trị trung bình của k giá trị lân cận gần nhất Nó yêu cầu bộ nhớ lớn để lưu trữ toàn bộ tập dữ liệu đào tạo để dự đoán
Thuật toán KNN được đánh giá là không phù hợp với dữ liệu kích thước lớn Các thuật toán máy học đều cần một tập dữ liệu dày đặc để có thể dự đoán chính xác trên toàn bộ không gian dữ liệu KNN cũng yêu cầu một điểm phải gần trong mọi chiều đơn lẻ, các điểm gần nhau dọc theo mọi trục trong không gian dữ liệu