Ứng dụng kmean trong phân loại sản phẩm
BỘ CÔNG THƯƠNG TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI KHOA CÔNG NGHỆ THÔNG TIN BÀI TẬP LỚN HỆ CHUYÊN GIA Đề : Ứng dụng Kmean phân loại sản phẩm Giáo viên hướng dẫn : Lớp : Th.s Trần Thanh Hùng KHMT2-K4 LỜI NÓI ĐẦU Ngày không phủ nhận vai trò quan trọng máy tính nghiên cứu khoa học kỹ thuật đời sống Máy tính làm điều kỳ diệu giải vấn đề tưởng chừng nan giải Càng ngày có nhiều người tự hỏi, liệu máy tính có khả suy nghĩ người hay chưa? Chúng ta không trả lời câu hỏi Thay vào đó, nêu khác biệt chủ yếu cách làm việc máy tính óc người Một máy tính, dù có mạnh đến đâu nữa, phải làm việc theo chương trình xác hoạch định trước chuyên gia Bài toán phức tạp việc lập trình công phu Trong người làm việc cách học tập rèn luyện, làm việc người có khả liên tưởng, kết nối việc với việc khác, quan trọng hết, họ sáng tạo Ngày nay, website giới thiệu, mua bán sản phẩm trực tuyến ngày nhiều internet Có nhiều hình thức giới thiệu sản phẩm tới khách hàng, để khách hàng mua xong sản phẩm mà lại có hứng thú để mua sản phẩm khác đề đặt với trang web bán hàng trực tuyến Những website thông minh có giá thành cao cửa hàng bỏ tiền đầu tư Điều khó khăn khả phân loại liệu đầu vào phải chuẩn hóa xác đề chương trình phân loại sản phẩm vào nhóm phù hợp Với số phương pháp truyền thống, phân loại nhóm sản phẩm dựa theo mã nhóm sản phẩm Với cách làm này, hoàn toàn phụ thuộc vào việc đặt người nhập liệu Việc sử dụng Kmean để phân cụm tự động cho sản phẩm giúp cho việc phân loại mềm dẻo hơn, dựa tiêu chí sản phẩm mà ta phân loại sản phẩm thuộc nhóm Từ đưa gợi ý cần thiết làm vừa lòng vị khách hàng khó tính I Một số phương pháp phân cụm liệu điển hình Phương pháp phân cụm phân hoạch Ý tưởng phương pháp phân tập liệu có n phần tử cho trước thành k nhóm liệu cho phần tử liệu thuộc nhóm liệu nhóm liệu có tối thiểu phần tử liệu Các thuật toán phân hoạch có độ phức tạp lớn xác định nghiệm tối ưu toàn cục cho vấn đề PCDL, phải tìm kiếm tất cách phân hoạch Chính vậy, thực tế người ta thường tìm giải pháp tối ưu cục cho vấn đề cách sử dụng hàm tiêu chuẩn để đánh giá chất lượng cụm để hướng dẫn cho trình tìm kiếm phân hoạch liệu Với chiến lược này, thông thường người ta bắt đầu khải tạo phân hoạch ban đầu cho tập liệu theo phép ngẫu nhiên theo heuristic liên tục tinh chỉnh thu phân hoạch mong muốn, thoả mãn điều kiện ràng buộc cho trước Các thuật toán phân cụm phân hoạch cố gắng cải tiến tiêu chuẩn phân cụm cách tính giá trị độ đo tương tự đối tượng liệu xếp giá trị này, sau thuật toán lựa chọn giá trị dãy xếp cho hàm tiêu chuẩn đạt giá trị tối thiểu Như vậy, ý tưởng thuật toán phân cụm phân hoạch tối ưu cục sử dụng chiến lược tham ăn để tìm kiếm nghiệm Lớp thuật toán phân cụm phân hoạch bao gồm thuật toán đề xuất lĩnh vực KPDL thuật toán áp dụng nhiều thực tế Sau số thuật toán kinh điển áp dụng phương pháp phân hoạch kế thừa sử dụng rộng rãi: Thuật toán k-means Thuật toán phân cụm phân hoạch k- means MacQueen đề xuất lĩnh vực thống kê năm 1967, mục đích tuật toán k- means sinh k cụm liệu {C1, C2, …, Ck} từ tập liệu ban đầu gồm n đối tượng không gian d chiều Xi=(xi1, xi2, …, xid), (i = 1, n) , k cho hàm tiêu chuẩn: E = ∑ ∑ D ( x − mi ) đạt cực tiểu Trong đó: mi trọng tâm i =1 x∈Ci cụm Ci, D khoảng cách hai đối tượng Trọng tâm cụm vector, giá trị phần tử trung bình cộng thành phần tương ứng đối tượng vector liệu cụm xét Tham số đầu vào thuật toán số cụm k, tập CSDL gồm n phần tử tham số đầu thuật toán trọng tâm cụm liệu Độ đo khoảng cách D đối tượng liệu thường sử dụng khoảng cách Euclide, mô hình khoảng cách dễ để lấy đạo hàm xác định cực trị tối thiểu Hàm tiêu chuẩn độ đo khoảng cách xác định cụ thể tuỳ vào ứng dụng quan điểm người dùng Thuật toán k- means bao gồm bước sau: INPUT: Một CSDL gồm n đối tượng số cụm cần phân k OUTPUT: Các cụm Ci (i=1 k) cho hàm tiêu chuẩn E đạt giá trị tối thiểu Thuật toán tiến hành bước sau: Bước 1: Khởi tạo Chọn k đối tượng mj (j=1…k) trọng tâm ban đầu k cụm từ tập liệu đầu vào (việc lựa chọn ngẫu nhiên chọn theo kinh nghiệm chuyên gia) Bước 2: Tính khoảng cách Đối với đối tượng Xi (1 ≤ i ≤ n), tính khoảng cách tới trọng tâm mj với j=1,…,k, sau tìm trọng tâm gần đối tượng Bước 3: Cập nhật lại tâm Đối với j=1,…,k, cập nhật trọng tâm cụm mj cách xác định trung bình cộng vector đối tượng liệu Bước 4: Điều kiện dừng Lặp lại bước bước b trọng tâm cụm không thay đổi Hình .Thuật toán k-means Thuật toán k-means chứng minh hội tụ có độ phức tạp tính toán là: O((n.k.d).τ.Τflop) Trong đó, n số đối tượng liệu, k số cụm liệu, d số chiều vector đối tượng liệu, τ số vòng lặp, Τflop thời gian để thực để thực phép tính sở phép cộng, trừ, nhân, chia,… Như vậy, thuật toán k-means phân tích phân cụm đơn giản nên áp dụng tập liệu lớn Tuy nhiên, nhược điểm thuật toán k-means áp dụng với liệu có thuộc tính số khám phá cụm có dạng hình cầu, mà thuật toán k-means nhậy cảm với nhiễu phần tử ngoại lai liệu Hình sau diễn tả, mô số hình dạng cụm liệu khám phá thuật toán k-means: Hình .Hình dạng cụm liệu khám phá thuật toán k-means Hơn nữa, chất lượng PCDL thuật toán k-means phụ thuộc nhiều vào tham số đầu vào như: số cụm k k trọng tâm khởi tạo ban đầu Trong trường hợp, trọng tâm khởi tạo ban đầu mà lệch so với trọng tâm cụm tự nhiên kết phân cụm thuật toán k-means thấp, nghĩa cụm liệu khám phá lệch so với cụm thực tế Trên thực tế người ta chưa có giải pháp tối ưu để chọn tham số đầu vào, giải pháp thường sử dụng thử nghiệm với giá trị đầu vào k cụm liệu khác sau chọn giải pháp tốt Đến nay, có nhiều thuật toán kế thừa tư tưởng thuật toán k-means áp dụng KPDL để giải tập liệu có kích thước lớn áp dụng hiệu phổ biến thuật toán PAM, CLARA, CLARANS, k-medoid, k-prototypes,… II Ứng dụng kmean phân cụm website Giới thiệu Ngày nay, website giới thiệu, mua bán sản phẩm trực tuyến ngày nhiều internet Có nhiều hình thức giới thiệu sản phẩm tới khách hàng, để khách hàng mua xong sản phẩm mà lại có hứng thú để mua sản phẩm khác đề đặt với trang web bán hàng trực tuyến Những website thông minh có giá thành cao cửa hàng bỏ tiền đầu tư Điều khó khăn khả phân loại liệu đầu vào phải chuẩn hóa xác đề chương trình phân loại sản phẩm vào nhóm phù hợp Với số phương pháp truyền thống, phân loại nhóm sản phẩm dựa theo mã nhóm sản phẩm Với cách làm này, hoàn toàn phụ thuộc vào việc đặt người nhập liệu Việc sử dụng Kmean để phân cụm tự động cho sản phẩm giúp cho việc phân loại mềm dẻo hơn, dựa tiêu chí sản phẩm mà ta phân loại sản phẩm thuộc nhóm Từ đưa gợi ý cần thiết làm vừa lòng vị khách hàng khó tính 1.1 Phát biểu toán Cho sở liệu có bảng liệu sản phẩm Các sản phẩm gồm số lượng, giá, màu sắc, chất liệu, nhà sản xuất Tất khóa ngoại liên kết tới bảng khác Từ giả thiết, xây dựng ứng dụng phân chia số sản phẩm có csdl thành nhóm khác cho sản phẩm nhóm có tính chất giống Ý tưởng toán : Chọn n sản phẩm ngẫu nhiên làm trọng tâm để phân nhóm với n số nhóm cần phân Sử dụng Kmean để phân chia sản phẩm vào nhóm Tính lại trọng tâm nhóm Phân chia lại nhóm Lặp lại trọng tâm bước trước trọng tâm bước sau Các bước chương trình xử lý tự động Mỗi thêm sản phẩm mới, có liệu trọng tâm nhóm Ta so sánh sản phẩm với trọng tâm từ phân vào nhóm mà không cần phân nhóm lại cho toàn sản phẩm 1.2 1.2.1 Các bước giải giải toán Xây dựng tập liệu sản phẩm Người sử dụng vào quản trị website nhập liệu sản phẩm Trước tiên cần nhập bảng bảng khóa ngoại bảng sản phẩm bảng màu sắc, kích cỡ, chất liệu, nhà sản xuất… Dữ liệu nhập vào nhóm cho nhóm, tính chất sản phẩm phân bổ rõ ràng giúp việc phân loại thể rõ Việc gợi ý mua rõ ràng Danh sách sản phẩm sau nhập Dữ liệu lưu bảng sản phẩm Đầu vào danh sách sản phẩm thuộc tính: Price, Quantity, Color, Manufacturer, Size, Material Các thuộc tính mã hóa số đồng để dễ dàng cho việc tính toán với công thức toán học Ta phân thành nhóm, nhóm gồm sản phẩm có tính chất tương tự 1.2.1.1 Sử dụng Kmean đề phân chia sản phẩm vào nhóm III Cài đặt chương trình thử nghiệm 3.1.Source Code 3.1.1.Lớp Kmean.cs using System.Data; class KMean { public float [,] Center;//Tạo độ trọng tâm cuối /// /// Thuật toán phân cụm K-Mean /// Trả mảng chiều, phần tử mảng có giá trị cụm /// /// Số tập liệu /// Số thuộc tính liệu /// Dữ liệu đầu vào /// Số cụm public int[] Execute(int n, int m, float[,] input, int numGroup) { if (numGroup > n) return null; var oldCenter = new float[numGroup, m]; Center = new float[numGroup, m]; var result = new int[n]; for (int i = 0; i < n; i++) { result[i] = -1; } for (int i = 0; i < numGroup; i++) { result[i] = i; for (int j = 0; j < m; j++) { oldCenter[i, j] = input[i, j]; } } //duyet bool check = true; var distance = new float[numGroup]; while (check) { for (int i = 0; i < n; i++) { for (int j = 0; j < numGroup; j++) { distance[j] = 0; for (int k = 0; k < m; k++) { distance[j] += (input[i, k] - oldCenter[j, k]) * (input[i, k] - oldCenter[j, k]); } } float = distance[0]; result[i] = 0; for (int j = 1; j < numGroup; j++) { if (min > distance[j]) { = distance[j]; result[i] = j; } } } //tim toa tam float[,] newCenter = oldCenter; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { oldCenter[result[i], j] += input[i, j]; } } check = false; for (int i = 0; i < numGroup; i++) { for (int j = 0; j < m; j++) { oldCenter[i, j] /= m; if (newCenter[i, j] != oldCenter[i, j]) check = true; } } Center = oldCenter; } return result; } public float[,] ConvertDataTable(DataTable dt,int startCol,int endCol) { var result = new float[dt.Rows.Count, endCol - startCol]; for (int i = 0; i < dt.Rows.Count; i++) { for (int j = startCol; j < endCol; j++) { result[i, j - startCol] = float.Parse(dt.Rows[i][j].ToString()); } } return result; } } 3.1.2.Lớp SqlDataProvider.cs using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Security.Cryptography; using System.Text; public class SqlDataProvider { private static readonly string strConStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; #region DB Access Functions private static SqlConnection con; public static SqlConnection GetConnect() { if (con == null) = new SqlConnection(strConStr); if (con.State == ConnectionState.Closed) con.Open(); return con; } public static DataTable GetTable(SqlCommand cmd) { try { if (cmd.Connection != null) { using (var ds = new DataSet()) { using (var da = new SqlDataAdapter()) { da.SelectCommand = cmd; da.Fill(ds); return ds.Tables[0]; } } } else { 10 using (SqlConnection conn = GetConnect()) { using (var ds = new DataSet()) { using (var da = new SqlDataAdapter()) { da.SelectCommand = cmd; da.SelectCommand.Connection = conn; da.Fill(ds); return ds.Tables[0]; } } } } } finally { } } public static SqlDataReader ExecuteReader(SqlCommand cmd) { try { if (cmd.Connection != null) { return cmd.ExecuteReader(); } else { using (SqlConnection conn = GetConnect()) { cmd.Connection = conn; return cmd.ExecuteReader(); } } } finally { } } public static DataSet GetDsData(SqlCommand cmd) { try { if (cmd.Connection != null) { using (var ds = new DataSet()) 11 { using (var da = new SqlDataAdapter()) { da.SelectCommand = cmd; da.Fill(ds); return ds; } } } else { using (SqlConnection conn = GetConnect()) { using (var ds = new DataSet()) { using (var da = new SqlDataAdapter()) { da.SelectCommand = cmd; da.SelectCommand.Connection = conn; da.Fill(ds); return ds; } } } } } finally { } } public static DataTable GetTable(string sql) { SqlConnection conn = GetConnect(); var dt=new DataTable(); var ad = new SqlDataAdapter(sql, conn); ad.Fill(dt); return dt; } public static void ExeCuteNonquery(SqlCommand cmd) { try { SqlConnection conn = GetConnect(); cmd.Connection = conn; cmd.ExecuteNonQuery(); } finally { 12 } } public static void ExeCuteNonquery(string sql) { try { SqlConnection conn = GetConnect(); var cmd = new SqlCommand(sql, conn); cmd.ExecuteNonQuery(); } finally { } } public static SqlDataReader ExecuteReader(string sql) { try { var cmd = new SqlCommand(sql, GetConnect()); return cmd.ExecuteReader(); } finally { } } public static string ExecuteScalar(string sql) { try { SqlConnection conn = GetConnect(); var cmd = new SqlCommand(sql, conn); return cmd.ExecuteScalar().ToString(); } finally { } } public object ExecuteScalar(SqlCommand cmd) { try { SqlConnection conn = GetConnect(); cmd.Connection = conn; return cmd.ExecuteScalar(); } finally 13 { } } public int DBSize() { using (var cmd = new SqlCommand("select sum(size) * * 1024 from sysfiles")) { cmd.CommandType = CommandType.Text; return (int) ExecuteScalar(cmd); } } public bool CheckConnect() { var cmd = new SqlCommand("select getdate()"); if (GetTable(cmd).Rows.Count > 0) return true; return false; } public static string Encrypt(string toEncrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); if (useHashing) { var hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes("THANHNV")); } else keyArray = Encoding.UTF8.GetBytes("THANHNV"); var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } public static string Decrypt(string toDecrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); if (useHashing) { var hashmd5 = new MD5CryptoServiceProvider(); 14 keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes("THANHNV")); } else keyArray = Encoding.UTF8.GetBytes("THANHNV"); var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); } #endregion } 3.1.3 Mã nguồn phân loại sản phẩm thêm if (Insert.Checked) { if (!kt) return; try { #region Xếp vào nhóm DataTable dtGroup = ProductController.Product_GetDistinct_CenterKmean(); string s2 = txtQuantity.Text + "," + ddlUColor.SelectedValue + "," + ddlUManufacturer.SelectedValue + "," + ddlUSize.SelectedValue + "," + ddlUMaterial.SelectedValue; float = float.MaxValue; string nhom="", center=""; for (int i = 0; i < dtGroup.Rows.Count; i++) { string s1 = dtGroup.Rows[i]["Center_Kmean"].ToString(); float kq = CaculatorDistance(s1, s2); if (min < kq) { = kq; nhom = dtGroup.Rows[i]["Group_Kmean"].ToString(); center = dtGroup.Rows[i]["Center_Kmean"].ToString(); } } #endregion ProductController.Product_Insert(txtName.Text, Session["upload"] == null ? "" : Session["upload"].ToString(), txtDescription.Text, txtPrice.Text, txtQuantity.Text, ddlUColor.SelectedValue, ddlUManufacturer.SelectedValue, 15 ddlUSize.SelectedValue, ddlUMaterial.SelectedValue, ddlUGroupProduct.SelectedValue,nhom,center); } catch { WebMsgBox.Show("Lỗi :"); return; } } else { if (!kt) return; try { ProductController.Product_Update(ViewState["Id"].ToString(), Session["upload"] == null ? "" : Session["upload"].ToString(), txtName.Text, txtDescription.Text, txtPrice.Text, txtQuantity.Text, ddlUColor.SelectedValue, ddlUManufacturer.SelectedValue, ddlUSize.SelectedValue, ddlUMaterial.SelectedValue, ddlUGroupProduct.SelectedValue); } catch { WebMsgBox.Show("Lỗi :"); return; } } Loadgrd_showProduct(); WebMsgBox.Show("Cập nhật thành công"); pn_showProduct.Visible = true; pn_updateProduct.Visible = false; 3.1.4 Mã nguồn phân loại toàn sản phẩm DataTable dt = ProductController.Product_GetAll(); const int m = 5;//số tiêu chí phân cụm (màu sắc, chất liệu, hãng sx, kích cỡ) int numgroup = int.Parse(SqlDataProvider.ExecuteScalar("Select NumGroup from Config")); var km = new KMean(); float[,] data = km.ConvertDataTable(ProductController.Product_GetAll(), 5, 10); int[] result = km.Execute(dt.Rows.Count, m,data, numgroup); //lấy center var center=new string[numgroup]; for (int i = 0; i < numgroup; i++) { center[i] = ""; for (int j = 0; j < m; j++) { center[i] += km.Center[i,j]+","; 16 } center[i] = center[i].Remove(center[i].Length - 1, 1); } //update Group_Kmean, Center_Kmean for (int i = 0; i < result.Length; i++) { ProductController.Product_Update_GroupKmean(dt.Rows[i] ["Id"].ToString(),result[i].ToString()); ProductController.Product_Update_CenterKmean(dt.Rows[i]["Id"].ToString(), ReturnCenterKmean(result[i].ToString(),center)); } WebMsgBox.Show("Cập nhật thành công!"); 3.2.Giao diện chương trình 3.2.1 Giao diện trang chủ 17 3.2.2 Giao diện gợi ý sản phẩm 18 3.2.3 Giao diện giỏ hàng 19 3.2.4 Giao diện chức quản trị 3.2.5 Quản trị sản phẩm 3.2.6 Cấu hình phân nhóm 20 KẾT LUẬN Trong thời gian vừa qua, trình bày nội dung nghiên cứu đề tài nhóm em gồm phần sau: Tìm hiểu thuật toán phân cụm Kmean Tìm kỹ thuật thiết kế website ASP.NET Mô tả toán ứng dụng bán hàng sử dụng Kmean Thiết kế mạng phân cụm thành công sản phẩm dựa đặc tính sản phẩm để gợi ý mua hàng thông minh cho người sử dụng Cài đặt kiểm tra thực nghiệm toán Ngày này, website bán hàng thường không tương tác tối với người mua hàng Vì cần thiết kế dạng website thông minh hỗ trợ người mua hàng tới tối đa làm tăng doanh số cho doanh nghiệp Trong ví dụ thử nghiệm với tập liệu nhỏ, trình phân cụm diễn nhanh Các tiêu chí phân cụm chưa nhiều nên không xác tuyệt đối thực tế Hướng phát triển khóa luận tương lai Nâng cao hiệu độ xác việc phân loại nhóm sản phẩm Mở rộng thêm nhiều loại sản phẩm, đặc điểm sản phẩm 21 TÀI LIỆU THAM KHẢO [1.] Giá trình hệ chuyên gia – Đại học Bách Khoa Hà Nội [2.] MathNeuralNetworks Ben Krose, faculty of Mathematics and computer science, university of Amsterdam And Patrick van der smagt, institute of robotics and system dynamics German aerospase Reseach establishment [3.] Artificial Neural Networks and Information theory, colin Fyfe, department of computing and information system, the university of Paisley [4.] A Growth Algorithm for Neural Networks Decision Trees Mostefa golea and Mario Marchand, Deparment of physics, university of Ottawa Canada [5.] Artificial neural network From Wikipedia, the free encyclopedia [6.] Expert System From Wikipedia, the free encyclopedia [7.] http://en.wikipedia.org/wiki/Expert_system 22 [...]... mới chỉ thử nghiệm với tập dữ liệu nhỏ, quá trình phân cụm diễn ra khá nhanh Các tiêu chí phân cụm cũng chưa nhiều nên sẽ không được chính xác tuyệt đối như thực tế Hướng phát triển tiếp theo của khóa luận này trong tương lai Nâng cao hiệu quả và độ chính xác trong việc phân loại các nhóm sản phẩm Mở rộng thêm nhiều loại sản phẩm, đặc điểm sản phẩm 21 TÀI LIỆU THAM KHẢO [1.] Giá trình hệ chuyên... diện gợi ý sản phẩm 18 3.2.3 Giao diện giỏ hàng 19 3.2.4 Giao diện các chức năng quản trị 3.2.5 Quản trị sản phẩm 3.2.6 Cấu hình phân nhóm 20 KẾT LUẬN Trong thời gian vừa qua, như đã trình bày ở trên đây nội dung nghiên cứu đề tài của nhóm em được gồm các phần chính sau: Tìm hiểu thuật toán phân cụm Kmean Tìm kỹ thuật thiết kế website bằng ASP.NET Mô tả bài toán ứng dụng bán hàng sử dụng Kmean ... Kmean Thiết kế mạng và phân cụm thành công các sản phẩm dựa trên các đặc tính sản phẩm để gợi ý mua hàng thông minh cho người sử dụng Cài đặt và kiểm tra thực nghiệm bài toán này Ngày này, các website bán hàng thường không tương tác tối với người mua hàng Vì vậy cần thiết kế các dạng website thông minh hỗ trợ người mua hàng tới tối đa có thể và làm tăng doanh số cho doanh nghiệp Trong ví dụ trên mới... pn_showProduct.Visible = true; pn_updateProduct.Visible = false; 3.1.4 Mã nguồn phân loại toàn bộ sản phẩm DataTable dt = ProductController.Product_GetAll(); const int m = 5;//số tiêu chí phân cụm (màu sắc, chất liệu, hãng sx, kích cỡ) int numgroup = int.Parse(SqlDataProvider.ExecuteScalar("Select NumGroup from Config")); var km = new KMean( ); float[,] data = km.ConvertDataTable(ProductController.Product_GetAll(),... km.Center[i,j]+","; 16 } center[i] = center[i].Remove(center[i].Length - 1, 1); } //update Group _Kmean, Center _Kmean for (int i = 0; i < result.Length; i++) { ProductController.Product_Update_GroupKmean(dt.Rows[i] ["Id"].ToString(),result[i].ToString()); ProductController.Product_Update_CenterKmean(dt.Rows[i]["Id"].ToString(), ReturnCenterKmean(result[i].ToString(),center)); } WebMsgBox.Show("Cập nhật thành công!");... cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); } #endregion } 3.1.3 Mã nguồn phân loại sản phẩm khi thêm mới if (Insert.Checked) { if (!kt) return; try { #region Xếp vào nhóm DataTable dtGroup = ProductController.Product_GetDistinct_CenterKmean(); string s2 = txtQuantity.Text + "," + ddlUColor.SelectedValue + "," + ddlUManufacturer.SelectedValue + "," + ddlUSize.SelectedValue... float.MaxValue; string nhom="", center=""; for (int i = 0; i < dtGroup.Rows.Count; i++) { string s1 = dtGroup.Rows[i]["Center _Kmean" ].ToString(); float kq = CaculatorDistance(s1, s2); if (min < kq) { min = kq; nhom = dtGroup.Rows[i]["Group _Kmean" ].ToString(); center = dtGroup.Rows[i]["Center _Kmean" ].ToString(); } } #endregion ProductController.Product_Insert(txtName.Text, Session["upload"] == null ? "" : Session["upload"].ToString(),