진강이의 성장일지

데이터 분석 공모전 최종 + 도서관 아이디어 해커톤 공모전 기획안 본문

카테고리 없음

데이터 분석 공모전 최종 + 도서관 아이디어 해커톤 공모전 기획안

진강이 2024. 2. 13. 18:42

 

활용 데이터셋

2022 디지털 정보격차 실태조사 (from 한국지능정보사회진흥원(NIA))

codebook.xlsx
0.18MB
data.xlsx
1.38MB
every_data.csv
2.86MB

 

 

최종 기획안 

미래 도서관 정책 기획안

찐찐찐찐찐최종.pdf
1.45MB

 

 

 

빅데이터 활용 사회문제 해결 기획안

배포용pdf 미래와 소프트웨어 제3회 아이디어 공모전.pdf
1.20MB

 

코드

데이터 분석에 사용한 전체 코드는 다음과 같다

import matplotlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# read data xlsx
df = pd.read_excel('data.xlsx')

# read the columns from xlsx
#df2 = pd.read_excel("codebook.xlsx")
from matplotlib import rc
rc('font', family='AppleGothic')
every_df = pd.read_csv('every_data.csv')
plt.rcParams['axes.unicode_minus'] = False
# only keep the columns we need which is 변수정보, Unnamed: 1,  Unnamed: 2
# df2 = df2[['변수 정보', 'Unnamed: 1', 'Unnamed: 2']]
# # drop the first row
# df2 = df2.drop(df2.index[0])
# # drop the last row
# df2 = df2.drop(df2.index[-1])

# mapping the columns name which is on df2 to df using key '변수 정보' and value 'Unnamed: 2'
# and rename the columns name
#df = df.rename(columns=dict(zip(df2['변수 정보'], df2['Unnamed: 2'])))
print()
# unify the columns name Q2A11, Q2A12, Q2A13
# if value is overlap, then keep the highest value
every_df['Q2A1'] = every_df[['Q2A11', 'Q2A12', 'Q2A13']].max(axis=1)
df['Q2A1'] = df[['Q2A11', 'Q2A12', 'Q2A13']].max(axis=1)
# drop the columns Q2A11, Q2A12, Q2A13
every_df = every_df.drop(['Q2A11', 'Q2A12', 'Q2A13'], axis=1)
df = df.drop(['Q2A11', 'Q2A12', 'Q2A13'], axis=1)
# do Normalization on every comlumns except ID
# min_val = every_df.iloc[:, 1:].min()
# max_val = every_df.iloc[:, 1:].max()
# every_df.iloc[:, 1:] = (every_df.iloc[:, 1:] - min_val) / (max_val - min_val)
#
# df.iloc[:, 1:] = (df.iloc[:, 1:] - min_val) / (max_val - min_val)
"""
['ID', 'Q1A1', 'Q1A2', 'Q2A2', 'Q2A3', 'Q3', 'Q4A1', 'Q4A2', 'Q4A3', 'Q4A4', 'Q4A5', 'Q4A6', 'Q4A7', 'Q5A1', 'Q5A2', 'Q5A3', 'Q5A4', 'Q5A5', 'Q5A6', 'Q5A7', 'Q6', 'Q7A1', 'Q7A2', 'Q7A3', 'Q8A1', 'Q8A2', 'Q8A3', 'Q8A4', 'Q8B1', 'Q8B2', 'Q8B3', 'Q8B4', 'Q9A1', 'Q9A2', 'Q9A3', 'Q9A4', 'Q9A5', 'Q9B1', 'Q9B2', 'Q9B3', 'Q9B4', 'Q9B5', 'Q10A1', 'Q10A2', 'Q10A3', 'Q10A4', 'Q10B1', 'Q10B2', 'Q10B3', 'Q10B4', 'Q11A1', 'Q11A2', 'Q11B1', 'Q11B2', 'Q12A1', 'Q12A2', 'Q12B1', 'Q12B2', 'Q13A1', 'Q13A2', 'Q13A3', 'Q13A4', 'Q13B1', 'Q13B2', 'Q13B3', 'Q13B4', 'Q14A1', 'Q14A2', 'Q14A3', 'Q14A4', 'Q14B1', 'Q14B2', 'Q14B3', 'Q14B4', 'Q15A1', 'Q15A2', 'Q15A3', 'Q15A4', 'Q15A5', 'Q15A6', 'Q16A01', 'Q16A02', 'Q16A03', 'Q16A04', 'Q16A05', 'Q16A06', 'Q16A07', 'Q16A08', 'Q16A09', 'Q16A10', 'Q17A1', 'Q17A2', 'Q17A3', 'Q17A4', 'Q18A1', 'Q18A2', 'Q18A3', 'Q18A4', 'Q19A1', 'Q19A2', 'Q19A3', 'Q19A4', 'Q19A5', 'Q19A6', 'Q19A7', 'Q19A8', 'Q20A1', 'Q20A2', 'Q20A3', 'Q20A4', 'Q20A5', 'Q21AA1', 'Q21AA2', 'Q21AA3', 'Q21AA4', 'Q21AA5', 'Q21AA6', 'Q21AA7', 'Q21AA8', 'Q21BA1', 'Q21BA2', 'Q21BA3', 'Q21BA4', 'Q21BB1', 'Q21BB2', 'Q21BB3', 'Q21BB4', 'Q21BC1', 'Q21BC2', 'Q21BC3', 'Q21BC4', 'Q21BCA11', 'Q21BCA12', 'Q21BCA21', 'Q21BCA22', 'Q21BCA31', 'Q21BCA32', 'Q21BCA41', 'Q21BCA42', 'Q21CA1', 'Q21CA2', 'Q21CA3', 'Q21CA4', 'Q21CA5', 'Q21CA6', 'Q21CB1', 'Q21CB2', 'Q21CB3', 'Q21CB4', 'Q21CC1', 'Q21CC2', 'Q21CC3', 'Q21CC4', 'Q22A01', 'Q22A02', 'Q22A03', 'Q22A04', 'Q22A05', 'Q22A06', 'Q22A07', 'Q22A08', 'Q22A09', 'Q22A10', 'Q22A11', 'Q22A12', 'Q22A13', 'Q22A14', 'Q22A15', 'Q22A16', 'Q22A17', 'Q22A18', 'Q22A19', 'Q22A20', 'Q22A21', 'Q22A22', 'Q22A23', 'Q22A24', 'Q22A25', 'Q22A26', 'Q22A27', 'Q22A28', 'Q23', 'Q24A1', 'Q24A2', 'Q24A3', 'Q24A4', 'Q25', 'Q26', 'Q27', 'Q28A01', 'Q28A02', 'Q28A03', 'Q28A04', 'Q28A05', 'Q28A06', 'Q28A07', 'Q28A08', 'Q28A09', 'Q28A10', 'Q28A11', 'Q28A12', 'Q29A1', 'Q29A2', 'Q29A3', 'Q29A4', 'Q29A5', 'Q29A6', 'Q29A7', 'ADQ1', 'ADQ2', 'ADQ3', 'ADQ3A', 'ADQ4', 'ADQ5', 'ADQ6', 'ADQ7', 'ADQ8', 'ADQ8A', 'ADQ8A1', 'ADQ8A2', 'ADQ8A3', 'ADQ8A4', 'ADQ8A5', 'ADQ8A6', 'ADQ8A7', 'ADQ8A8', 'ADQ9', 'ADQ101', 'ADQ102', 'ADQ103', 'WT2', 'Q2A1']
"""
# 접근: Q1-3 +Q6-7(12문항)
# sum value of column name 'Q1A1', 'Q1A2', 'Q2A2', 'Q2A3', 'Q3'
every_df['Q1-3'] = every_df[['Q1A1', 'Q1A2', 'Q2A2', 'Q2A3', 'Q3']].sum(axis=1)
df['Q1-3'] = df[['Q1A1', 'Q1A2', 'Q2A2', 'Q2A3', 'Q3']].sum(axis=1)
# sum value of column name 'Q6', 'Q7A1', 'Q7A2', 'Q7A3'
every_df['Q6-7'] = every_df[['Q6', 'Q7A1', 'Q7A2', 'Q7A3']].sum(axis=1)
df['Q6-7'] = df[['Q6', 'Q7A1', 'Q7A2', 'Q7A3']].sum(axis=1)
# sum the value of df columns name 'Q1-3', 'Q6-7' to variable
every_df['접근'] = every_df[['Q1-3', 'Q6-7']].sum(axis=1)
df['접근'] = df[['Q1-3', 'Q6-7']].sum(axis=1)


#역량은 Q4 + Q5 (14문항)
# sum value of column name 'Q4A1', 'Q4A2', 'Q4A3', 'Q4A4', 'Q4A5', 'Q4A6', 'Q4A7'
every_df['Q4'] = every_df[['Q4A1', 'Q4A2', 'Q4A3', 'Q4A4', 'Q4A5', 'Q4A6', 'Q4A7']].sum(axis=1)
df['Q4'] = df[['Q4A1', 'Q4A2', 'Q4A3', 'Q4A4', 'Q4A5', 'Q4A6', 'Q4A7']].sum(axis=1)
# sum value of column name 'Q5A1', 'Q5A2', 'Q5A3', 'Q5A4', 'Q5A5', 'Q5A6', 'Q5A7'
every_df['Q5'] = every_df[['Q5A1', 'Q5A2', 'Q5A3', 'Q5A4', 'Q5A5', 'Q5A6', 'Q5A7']].sum(axis=1)
df['Q5'] = df[['Q5A1', 'Q5A2', 'Q5A3', 'Q5A4', 'Q5A5', 'Q5A6', 'Q5A7']].sum(axis=1)
# sum the value of df columns name 'Q4', 'Q5' to variable
every_df['역량'] = every_df[['Q4', 'Q5']].sum(axis=1)
df['역량'] = df[['Q4', 'Q5']].sum(axis=1)

# 활용은 Q8-Q14+Q28-29(69문항)
# sum value of column name 'Q8A1', 'Q8A2', 'Q8A3', 'Q8A4', 'Q8B1', 'Q8B2', 'Q8B3', 'Q8B4'
every_df['Q8'] = every_df[['Q8A1', 'Q8A2', 'Q8A3', 'Q8A4', 'Q8B1', 'Q8B2', 'Q8B3', 'Q8B4']].sum(axis=1)
df['Q8'] = df[['Q8A1', 'Q8A2', 'Q8A3', 'Q8A4', 'Q8B1', 'Q8B2', 'Q8B3', 'Q8B4']].sum(axis=1)
# sum value of column name 'Q9A1', 'Q9A2', 'Q9A3', 'Q9A4', 'Q9A5', 'Q9B1', 'Q9B2', 'Q9B3', 'Q9B4', 'Q9B5'
every_df['Q9'] = every_df[['Q9A1', 'Q9A2', 'Q9A3', 'Q9A4', 'Q9A5', 'Q9B1', 'Q9B2', 'Q9B3', 'Q9B4', 'Q9B5']].sum(axis=1)
df['Q9'] = df[['Q9A1', 'Q9A2', 'Q9A3', 'Q9A4', 'Q9A5', 'Q9B1', 'Q9B2', 'Q9B3', 'Q9B4', 'Q9B5']].sum(axis=1)
# sum value of column name 'Q10A1', 'Q10A2', 'Q10A3', 'Q10A4', 'Q10B1', 'Q10B2', 'Q10B3', 'Q10B4'
every_df['Q10'] = every_df[['Q10A1', 'Q10A2', 'Q10A3', 'Q10A4', 'Q10B1', 'Q10B2', 'Q10B3', 'Q10B4']].sum(axis=1)
df['Q10'] = df[['Q10A1', 'Q10A2', 'Q10A3', 'Q10A4', 'Q10B1', 'Q10B2', 'Q10B3', 'Q10B4']].sum(axis=1)
# sum value of column name 'Q11A1', 'Q11A2', 'Q11B1', 'Q11B2'
every_df['Q11'] = every_df[['Q11A1', 'Q11A2', 'Q11B1', 'Q11B2']].sum(axis=1)
df['Q11'] = df[['Q11A1', 'Q11A2', 'Q11B1', 'Q11B2']].sum(axis=1)
# sum value of column name 'Q12A1', 'Q12A2', 'Q12B1', 'Q12B2'
every_df['Q12'] = every_df[['Q12A1', 'Q12A2', 'Q12B1', 'Q12B2']].sum(axis=1)
df['Q12'] = df[['Q12A1', 'Q12A2', 'Q12B1', 'Q12B2']].sum(axis=1)
# sum value of column name 'Q13A1', 'Q13A2', 'Q13A3', 'Q13A4', 'Q13B1', 'Q13B2', 'Q13B3', 'Q13B4'
every_df['Q13'] = every_df[['Q13A1', 'Q13A2', 'Q13A3', 'Q13A4', 'Q13B1', 'Q13B2', 'Q13B3', 'Q13B4']].sum(axis=1)
df['Q13'] = df[['Q13A1', 'Q13A2', 'Q13A3', 'Q13A4', 'Q13B1', 'Q13B2', 'Q13B3', 'Q13B4']].sum(axis=1)
# sum value of column name 'Q14A1', 'Q14A2', 'Q14A3', 'Q14A4', 'Q14B1', 'Q14B2', 'Q14B3', 'Q14B4'
every_df['Q14'] = every_df[['Q14A1', 'Q14A2', 'Q14A3', 'Q14A4', 'Q14B1', 'Q14B2', 'Q14B3', 'Q14B4']].sum(axis=1)
df['Q14'] = df[['Q14A1', 'Q14A2', 'Q14A3', 'Q14A4', 'Q14B1', 'Q14B2', 'Q14B3', 'Q14B4']].sum(axis=1)
# sum value of column name 'Q28A01', 'Q28A02', 'Q28A03', 'Q28A04', 'Q28A05', 'Q28A06', 'Q28A07', 'Q28A08', 'Q28A09', 'Q28A10', 'Q28A11', 'Q28A12'
every_df['Q28'] = every_df[['Q28A01', 'Q28A02', 'Q28A03', 'Q28A04', 'Q28A05', 'Q28A06', 'Q28A07', 'Q28A08', 'Q28A09', 'Q28A10', 'Q28A11', 'Q28A12']].sum(axis=1)
df['Q28'] = df[['Q28A01', 'Q28A02', 'Q28A03', 'Q28A04', 'Q28A05', 'Q28A06', 'Q28A07', 'Q28A08', 'Q28A09', 'Q28A10', 'Q28A11', 'Q28A12']].sum(axis=1)
# sum value of column name 'Q29A1', 'Q29A2', 'Q29A3', 'Q29A4', 'Q29A5', 'Q29A6', 'Q29A7'
every_df['Q29'] = every_df[['Q29A1', 'Q29A2', 'Q29A3', 'Q29A4', 'Q29A5', 'Q29A6', 'Q29A7']].sum(axis=1)
df['Q29'] = df[['Q29A1', 'Q29A2', 'Q29A3', 'Q29A4', 'Q29A5', 'Q29A6', 'Q29A7']].sum(axis=1)
# sum the value of df columns name 'Q8', 'Q9', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14', 'Q28', 'Q29' to variable
every_df['활용'] = every_df[['Q8', 'Q9', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14', 'Q28', 'Q29']].sum(axis=1)
df['활용'] = df[['Q8', 'Q9', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14', 'Q28', 'Q29']].sum(axis=1)
#종합 지수는 접근 *0.2 + 역량 *0.4 + 활용 *0.4 이구요.
# multiply the value of df columns name '접근', '역량', '활용' to variable


# 접근 역량 활용 항목에 대해서 각각 평균을 내주세요
# calculate the mean value of df columns name '접근', '역량', '활용'
df['접근_mean'] = df[['접근']].mean(axis=1)
df['역량_mean'] = df[['역량']].mean(axis=1)
df['활용_mean'] = df[['활용']].mean(axis=1)
every_df['접근_mean'] = every_df[['접근']].mean(axis=1)
every_df['역량_mean'] = every_df[['역량']].mean(axis=1)
every_df['활용_mean'] = every_df[['활용']].mean(axis=1)

every_df['종합지수'] = every_df[['접근', '역량', '활용']].mul([0.2, 0.4, 0.4]).sum(axis=1)
df['종합지수'] = df[['접근', '역량', '활용']].mul([0.2, 0.4, 0.4]).sum(axis=1)
print()
# do K means through the columns name '접근', '역량', '활용'
# set the number of cluster
num_of_cluster = 3
# set the number of iteration
num_of_iter = 100
# set the initial point of each cluster using df which id is 105820, 103672 and 102611
"""3유형(젤 잘 쓰시는 분) : 105820
2유형(중간유형) : 103672
1유형(디지털소외계층) : 102611"""
#init_point = df[df['ID'].isin([105820, 103672, 102611])][['접근', '역량', '활용']].values

# k means
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=num_of_cluster, init='k-means++', n_init=1, max_iter=num_of_iter, random_state=0).fit(df[['접근', '역량', '활용']])
df['cluster'] = kmeans.labels_

# do visualization using t-sne
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt


# Combine the dataset with the initial points
combined_data = df[['접근', '역량', '활용']]

# Apply t-SNE to reduce the dataset to 2 dimensions for visualization
tsne = TSNE(n_components=2, random_state=0)
tsne_results = tsne.fit_transform(df[['접근', '역량', '활용']])

# Add the t-SNE results as new columns in the DataFrame
df['tsne-2d-one'] = tsne_results[:, 0]
df['tsne-2d-two'] = tsne_results[:, 1]

# Visualize the clusters in the t-SNE transformed space
plt.figure(figsize=(16,10))
sns.scatterplot(
    x="tsne-2d-one", y="tsne-2d-two",
    hue=df['cluster'].astype(str),  # Convert cluster numbers to strings for the color palette
    palette=sns.color_palette("hsv", num_of_cluster),
    data=df,
    legend="full",
    alpha=0.8
)

plt.title('t-SNE Visualization of Clusters')
plt.xlabel('t-SNE Feature 1')
plt.ylabel('t-SNE Feature 2')
plt.legend(title='Cluster')
plt.show()



# Group by 'cluster' and calculate the mean for '종합지수'
cluster_means = df.groupby('cluster')['종합지수'].mean().reset_index()

# Sort the clusters by mean '종합지수'
cluster_means = cluster_means.sort_values('종합지수')

# Assign the type labels based on sorted means
cluster_mapping = {1: 'A', 2: "B", 0:'C'}

# Map the clusters to the type labels
df['yoohyung'] = df['cluster'].map(cluster_mapping)

# Print the result of the mapping

# Plot the clusters on the scatter plot
plt.figure(figsize=(8,6))
sns.scatterplot(
    x='tsne-2d-one', y='tsne-2d-two',
    hue='yoohyung',
    palette=sns.color_palette('hsv', num_of_cluster),
    data=df,
    legend='full',
    alpha=0.7
)
plt.title('t-SNE results with K-means Clusters')
plt.legend()
plt.show()


# Continue from your previous code

# 1. Assign the type labels based on sorted means of '종합지수'
cluster_means = df.groupby('cluster')['종합지수'].mean().sort_values().index
type_labels = {cluster_means[i]: ('A유형' if i == 0 else 'B유형' if i == 1 else 'C유형') for i in range(num_of_cluster)}
df['유형'] = df['cluster'].map(type_labels)

# 2. Calculate the average, minimum, and maximum values for '접근', '역량', and '활용' for each type
# Adjust the groupby method to use a list of column names
stats_df = df.groupby('유형')[['접근', '역량', '활용', '종합지수']].agg(['mean', 'min', 'max']).reset_index()

# Now flatten the multi-index created by the agg function
stats_df.columns = [' '.join(col).strip() for col in stats_df.columns.values]

# Sort the DataFrame based on the type to match the image: A유형, B유형, then C유형
stats_df['sort'] = stats_df['유형'].map({'A유형': 1, 'B유형': 2, 'C유형': 3})
stats_df.sort_values('sort', inplace=True)
stats_df.drop('sort', axis=1, inplace=True)

# Optionally, rename columns to match the format in the image
stats_df.rename(columns=lambda x: x.replace('_', ' '), inplace=True)

# Add 사례수(비율) column
case_counts = df['유형'].value_counts().rename_axis('유형').reset_index(name='사례수')
case_counts['비율'] = (case_counts['사례수'] / df.shape[0]) * 100
case_counts['사례수(비율)'] = case_counts.apply(lambda x: f"{x['사례수']}({x['비율']:.1f}%)", axis=1)

# Merge the 사례수(비율) with the stats_df
stats_df = pd.merge(stats_df, case_counts[['유형', '사례수(비율)']], on='유형')

# draw table and save it

fig, ax = plt.subplots(figsize=(10, 3))
ax.axis('off')
ax.axis('tight')
ax.table(cellText=stats_df.values, colLabels=stats_df.columns, loc='center')
plt.savefig('table.png', dpi=300, bbox_inches='tight')







import matplotlib.pyplot as plt

# Make sure 'stats_df' has the correct mappings:
# 'A유형' corresponds to '디지털소외형', 'B유형' corresponds to '저역량*저활용형', 'C유형' corresponds to '적극활용형'

# Create a mapping for the names to match those in the image
name_mapping = {'A유형': '디지털소외형', 'B유형': '저역량*저활용형', 'C유형': '적극활용형'}
stats_df['유형'] = stats_df['유형'].map(name_mapping)

# Prepare the data for plotting
plot_data = stats_df.set_index('유형')[['접근 mean', '역량 mean', '활용 mean', '종합지수 mean']]
# get every_df column wise mean of '접근', '역량', '활용' every person
every_jeobgeun = every_df[['접근']].mean(axis=0)
every_yeogryang = every_df[['역량']].mean(axis=0)
every_hwaryong = every_df[['활용']].mean(axis=0)
every_jonghap = every_df[['종합지수']].mean(axis=0)

# get percentage of plot_data using every_jeobgeun, every_yeogryang, every_hwaryong
plot_data['접근'] = plot_data['접근 mean'] / every_jeobgeun[0]
plot_data['역량'] = plot_data['역량 mean'] / every_yeogryang[0]
plot_data['활용'] = plot_data['활용 mean'] / every_hwaryong[0]
plot_data['종합지수'] = plot_data['종합지수 mean'] / every_jonghap[0]

# drop of '접근', '역량', '활용' of plot_data
plot_data = plot_data.drop(['접근 mean', '역량 mean', '활용 mean', '종합지수 mean'], axis=1)



# Plotting
import numpy as np

# Width of a bar
import numpy as np
# Assuming plot_data is a DataFrame with the appropriate data

# Set the width of the bars
width = 0.20
plot_data = plot_data * 100
# Set positions for the groups
positions = np.arange(len(plot_data))

# Plotting
fig, ax = plt.subplots(figsize=(12, 8))

# Define colors for each set of bars for visual appeal
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']

# Plot each set of bars
for i, col in enumerate(plot_data.columns):
    bars = ax.bar(positions + (i - 1.5) * width, plot_data[col], width=width, color=colors[i], label=col)

    # Add the data labels on the bars
    for bar in bars:
        yval = bar.get_height()
        ax.text(bar.get_x() + bar.get_width() / 2, yval, f"{yval:.1f}%", ha='center', va='bottom', fontsize=10)

# Customizations
ax.set_ylabel('Percentage (단위: %)', fontsize=14)
ax.set_title('유형별 디지털정보화수준', fontsize=16)
ax.set_xticks(positions)
ax.set_xticklabels(plot_data.index, fontsize=12)
ax.legend(title='유형', fontsize=12)

# Add gridlines behind the bars
ax.yaxis.grid(True, linestyle='--', which='major', color='grey', alpha=0.6)

# Set the limit for the y-axis to accommodate the text labels
ax.set_ylim(0, plot_data.max().max() + 20)

# Remove the top and right spines for a cleaner look
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Show the plot
plt.tight_layout()
plt.show()


from mpl_toolkits.mplot3d import Axes3D

# Set up a 3D figure
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

# Extract data for plotting
x = df['접근']
y = df['역량']
z = df['활용']
groups = df['유형'].unique()  # Get unique cluster names

# Plot data points
for group in groups:
    # Select data points that belong to the current group
    group_data = df[df['유형'] == group]
    ax.scatter(group_data['접근'], group_data['역량'], group_data['활용'], label=group, s=40, edgecolor='k', alpha=0.7)

# Create a legend for the clusters
ax.legend(title='유형')

# Add axis labels
ax.set_xlabel('접근')
ax.set_ylabel('역량')
ax.set_zlabel('활용')

# Set title
ax.set_title('3D Scatter Plot of Clusters')

# Show the plot
plt.show()

"""ADQ2   1   남성
   2   여성
   9   무응답
ADQ3   1   관리자
   2   전문가 및 관련 종사자
   3   사무 종사자
   4   서비스 종사자
   5   판매 종사자
   6   농림어업 숙련 종사자
   7   기능원 및 관련 기능 종사자
   8   장치/기계조작 및 조립 종사자
   9   단순노무 종사자
   10   군인
   11   전업주부
   12   초/중/고등학생
   13   대학생(전문대생 및 대학원생 포함)
   14   무직
   15   기타
   99   무응답
ADQ3A   1   고용주/사장/주인
   2   피고용주/종업원/직원
ADQ4   1   초등졸 이하
   2   중졸 (고등학교 중퇴 포함)
   3   고졸 (대학교 중퇴 포함)
   4   대졸 (전문대 포함) 이상
   9   무응답
ADQ5   1   장애 없음
   2   장애 있음
ADQ6   1   가구주임
   2   가구주 아님
   9   무응답
ADQ7   1   단독주택
   2   아파트
   3   연립/다세대(빌라)
   4   기타
ADQ8   1   1인 가구
   2   2인 이상 다인 가구
ADQ8A1   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A2   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A3   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A4   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A5   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A6   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A7   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ8A8   1   배우자
   2   형제
   3   자녀
   4   부모님
   5   조부모님
   6   손자
   7   삼촌/고모/이모
   8   기타
ADQ9   1   100만원 미만
   2   100-199만원
   3   200-299만원
   4   300-399만원
   5   400-499만원
   6   500-599만원
   7   600-699만원
   8   700-799만원
   9   800-899만원
   10   900-999만원
   11   1000만원 이상
ADQ101   1   서울
   2   부산
   3   대구
   4   인천
   5   광주
   6   대전
   7   울산
   8   세종
   9   경기
   10   강원
   11   충북
   12   충남
   13   전북
   14   전남
   15   경북
   16   경남
   17   제주
   99   무응답
ADQ102   1   시
   2   군
ADQ103   1   동
   2   읍면
```
```
ADQ1   212   자료분류용 질문(장노년)_연령
ADQ2   213   자료분류용 질문(장노년)_성별
ADQ3   214   자료분류용 질문(장노년)_직업
ADQ3A   215   자료분류용 질문(장노년)_직업_고용주/피고용주
ADQ4   216   자료분류용 질문(장노년)_최종학력
ADQ5   217   자료분류용 질문(장노년)_장애구분
ADQ6   218   자료분류용 질문(장노년)_가구주와의관계
ADQ7   219   자료분류용 질문(장노년)_가구 거주형태
ADQ8   220   자료분류용 질문(장노년)_가구구성형태
ADQ8A   221   자료분류용 질문(장노년)_가구구성형태_다인가구 명수
ADQ8A1   222   자료분류용 질문(장노년)_가구구성형태_다인가구1
ADQ8A2   223   자료분류용 질문(장노년)_가구구성형태_다인가구2
ADQ8A3   224   자료분류용 질문(장노년)_가구구성형태_다인가구3
ADQ8A4   225   자료분류용 질문(장노년)_가구구성형태_다인가구4
ADQ8A5   226   자료분류용 질문(장노년)_가구구성형태_다인가구5
ADQ8A6   227   자료분류용 질문(장노년)_가구구성형태_다인가구6
ADQ8A7   228   자료분류용 질문(장노년)_가구구성형태_다인가구7
ADQ8A8   229   자료분류용 질문(장노년)_가구구성형태_다인가구8
ADQ9   230   자료분류용 질문(장노년)_가구 월평균 소득
ADQ101   231   자료분류용 질문(장노년)_현재 거주지역
ADQ102   232   자료분류용 질문(장노년)_지역구분(시/군)
ADQ103   233   자료분류용 질문(장노년)_지역구분(읍면동)
"""

question_descriptions = {
    "ADQ1": "자료분류용 질문(장노년)_연령",
    "ADQ2": "자료분류용 질문(장노년)_성별",
    "ADQ3": "자료분류용 질문(장노년)_직업",
    "ADQ3A": "자료분류용 질문(장노년)_직업_고용주/피고용주",
    "ADQ4": "자료분류용 질문(장노년)_최종학력",
    "ADQ5": "자료분류용 질문(장노년)_장애구분",
    "ADQ6": "자료분류용 질문(장노년)_가구주와의관계",
    "ADQ7": "자료분류용 질문(장노년)_가구 거주형태",
    "ADQ8": "자료분류용 질문(장노년)_가구구성형태",
    "ADQ8A": "자료분류용 질문(장노년)_가구구성형태_다인가구 명수",
    "ADQ8A1": "자료분류용 질문(장노년)_가구구성형태_다인가구1",
    "ADQ8A2": "자료분류용 질문(장노년)_가구구성형태_다인가구2",
    "ADQ8A3": "자료분류용 질문(장노년)_가구구성형태_다인가구3",
    "ADQ8A4": "자료분류용 질문(장노년)_가구구성형태_다인가구4",
    "ADQ8A5": "자료분류용 질문(장노년)_가구구성형태_다인가구5",
    "ADQ8A6": "자료분류용 질문(장노년)_가구구성형태_다인가구6",
    "ADQ8A7": "자료분류용 질문(장노년)_가구구성형태_다인가구7",
    "ADQ8A8": "자료분류용 질문(장노년)_가구구성형태_다인가구8",
    "ADQ9": "자료분류용 질문(장노년)_가구 월평균 소득",
    "ADQ101": "자료분류용 질문(장노년)_현재 거주지역",
    "ADQ102": "자료분류용 질문(장노년)_지역구분(시/군)",
    "ADQ103": "자료분류용 질문(장노년)_지역구분(읍면동)"
}

question_options = {
    "ADQ2": {1: "남성", 2: "여성", 9: "무응답"},  # Male, Female, No response
    "ADQ3": {
        1: "관리자", 2: "전문가 및 관련 종사자", 3: "사무 종사자", 4: "서비스 종사자",
        5: "판매 종사자", 6: "농림어업 숙련 종사자", 7: "기능원 및 관련 기능 종사자",
        8: "장치/기계조작 및 조립 종사자", 9: "단순노무 종사자", 10: "군인",
        11: "전업주부", 12: "초/중/고등학생", 13: "대학생(전문대생 및 대학원생 포함)",
        14: "무직", 15: "기타", 99: "무응답"
    },
    "ADQ3A": {1: "고용주/사장/주인", 2: "피고용주/종업원/직원"},
    "ADQ4": {1: "초등졸 이하", 2: "중졸 (고등학교 중퇴 포함)", 3: "고졸 (대학교 중퇴 포함)",
             4: "대졸 (전문대 포함) 이상", 9: "무응답"},
    "ADQ5": {1: "장애 없음", 2: "장애 있음"},
    "ADQ6": {1: "가구주임", 2: "가구주 아님", 9: "무응답"},
    "ADQ7": {1: "단독주택", 2: "아파트", 3: "연립/다세대(빌라)", 4: "기타"},
    "ADQ8": {1: "1인 가구", 2: "2인 이상 다인 가구"},
    "ADQ8A1": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A2": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A3": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A4": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A5": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A6": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A7": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ8A8": {1: "배우자", 2: "형제", 3: "자녀", 4: "부모님", 5: "조부모님", 6: "손자", 7: "삼촌/고모/이모", 8: "기타"},
    "ADQ9": {1: "100만원 미만", 2: "100-199만원", 3: "200-299만원", 4: "300-399만원", 5: "400-499만원",
                6: "500-599만원", 7: "600-699만원", 8: "700-799만원", 9: "800-899만원", 10: "900-999만원",
                11: "1000만원 이상"},
    "ADQ101": {1: "서울", 2: "부산", 3: "대구", 4: "인천", 5: "광주", 6: "대전", 7: "울산", 8: "세종", 9: "경기",
                     10: "강원", 11: "충북", 12: "충남", 13: "전북", 14: "전남", 15: "경북", 16: "경남", 17: "제주", 99: "무응답"},
    "ADQ102": {1: "시", 2: "군"},
    "ADQ103": {1: "동", 2: "읍면"}
}