File size: 4,201 Bytes
a7fd807
 
 
 
 
 
 
 
 
 
d880f04
 
a7fd807
d880f04
 
a7fd807
d880f04
 
 
 
a7fd807
 
d880f04
 
a7fd807
d880f04
 
a7fd807
 
d880f04
a7fd807
d880f04
 
a7fd807
d880f04
 
 
 
 
 
 
 
 
 
a7fd807
 
 
 
 
 
d880f04
a7fd807
 
d880f04
a7fd807
 
d880f04
a7fd807
 
 
d880f04
 
a7fd807
d880f04
a7fd807
 
d880f04
a7fd807
d880f04
a7fd807
 
 
 
 
d880f04
 
a7fd807
d880f04
a7fd807
 
d880f04
a7fd807
 
d880f04
 
a7fd807
d880f04
 
 
a7fd807
 
 
d880f04
 
a7fd807
d880f04
a7fd807
8b9d6c2
d880f04
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from datasets import load_dataset

# Tiêu đề ứng dụng
st.title("Ứng dụng Phân Cụm Dữ Liệu Không Giám Sát")

# Giới thiệu về ứng dụng
with st.expander("Giới thiệu về Ứng dụng"):
    st.write(
        "Ứng dụng này cho phép bạn tải lên bất kỳ loại tập dữ liệu không nhãn nào "
        "và tự động phân cụm dữ liệu bằng thuật toán K-means. "
        "Nó sẽ trực quan hóa các cụm bằng phương pháp PCA và cung cấp biểu đồ chuỗi thời gian cũng như phân phối cụm "
        "giúp bạn nhận diện các mô hình và nhóm trong dữ liệu."
    )

# Tải file
uploaded_file = st.file_uploader("Tải lên tập tin CSV", type=["csv"])

# Bộ dữ liệu mẫu
if st.button("Dùng thử với bộ dữ liệu mẫu"):
    dataset = load_dataset('kheejay88/country_data', split='train')
    df = pd.DataFrame(dataset)
    st.success("Đã tải thành công bộ dữ liệu mẫu từ Hugging Face.")

# Cột dữ liệu
with st.expander("Các Cột Dữ Liệu"):
    st.write("""
        **country** – Tên quốc gia\n
        **child_mort** – Tỷ lệ tử vong trẻ em dưới 5 tuổi trên 1000 ca sinh sống\n
        **exports** – Xuất khẩu hàng hóa và dịch vụ trên đầu người (tính theo phần trăm GDP)\n
        **health** – Chi tiêu y tế trên đầu người (tính theo phần trăm GDP)\n
        **imports** – Nhập khẩu hàng hóa và dịch vụ trên đầu người (tính theo phần trăm GDP)\n
        **income** – Thu nhập ròng trên đầu người\n
        **inflation** – Tỷ lệ lạm phát hàng năm (phần trăm)\n
        **life_expec** – Tuổi thọ trung bình khi sinh (năm)\n
        **total_fer** – Tổng tỷ suất sinh (số con trung bình mỗi phụ nữ)\n
        **gdpp** – GDP trên đầu người\n
    """)

if uploaded_file is not None:
    df = pd.read_csv(uploaded_file)

if 'df' in locals():
    # Loại bỏ cột không phải số
    categorical_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()
    df.drop(columns=categorical_cols, inplace=True)
    st.write("### Dữ liệu thô:")
    st.write(df.head())

    # Tiền xử lý dữ liệu
    scaler = StandardScaler()
    scaled_data = scaler.fit_transform(df)

    # Chọn số lượng cụm
    num_clusters = st.slider("Chọn số lượng cụm", min_value=2, max_value=10, value=3)

    # Phân cụm bằng K-Means
    kmeans = KMeans(n_clusters=num_clusters, random_state=42)
    clusters = kmeans.fit_predict(scaled_data)
    df['Cụm'] = clusters

    # Giảm chiều bằng PCA để trực quan hóa
    pca = PCA(n_components=2)
    pca_data = pca.fit_transform(scaled_data)
    df['PCA1'] = pca_data[:, 0]
    df['PCA2'] = pca_data[:, 1]

    # Vẽ biểu đồ phân cụm
    st.write("### Biểu đồ Phân Cụm:")
    fig, ax = plt.subplots()
    sns.scatterplot(x='PCA1', y='PCA2', hue='Cụm', data=df, palette='viridis', ax=ax)
    st.pyplot(fig)

    # Vẽ biểu đồ chuỗi thời gian (nếu có)
    numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
    if len(numeric_cols) >= 2:
        selected_col = st.selectbox("Chọn cột để vẽ biểu đồ chuỗi thời gian", numeric_cols)
        st.write("### Biểu đồ Chuỗi Thời Gian:")
        fig, ax = plt.subplots()
        for cluster in df['Cụm'].unique():
            cluster_data = df[df['Cụm'] == cluster]
            ax.plot(cluster_data.index, cluster_data[selected_col], label=f'Cụm {cluster}')
        ax.legend()
        st.pyplot(fig)

    # Phân phối cụm
    st.write("### Phân phối Cụm:")
    fig, ax = plt.subplots()
    sns.countplot(x='Cụm', data=df, palette='viridis', ax=ax)
    st.pyplot(fig)

    st.markdown("---")  # Kẻ một đường ngang
    st.markdown("**Cảm ơn bạn!**")