chuyển đổi cấu trúc
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 438 KiB |
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"Age": {
|
||||
"Mean": 35.25316455696203,
|
||||
"Std": 16.342855691857576,
|
||||
"Min": 19.0,
|
||||
"Max": 79.0,
|
||||
"Shapiro-Wilk_W": 0.8454128859887641,
|
||||
"Shapiro-Wilk_p": 1.310419664520166e-07,
|
||||
"Normal_Distribution": false
|
||||
},
|
||||
"Gender": {
|
||||
"2": 55.0,
|
||||
"1": 44.3,
|
||||
"3": 0.7
|
||||
},
|
||||
"Income": {
|
||||
"439.9999999999999": 15.5,
|
||||
"586.6666666666666": 8.0,
|
||||
"220.0": 6.5,
|
||||
"330.0": 4.5,
|
||||
"550.0": 4.5,
|
||||
"293.3333333333333": 4.0,
|
||||
"264.0": 4.0,
|
||||
"660.0": 4.0,
|
||||
"132.0": 3.5,
|
||||
"165.0": 3.0,
|
||||
"176.0": 3.0,
|
||||
"528.0": 3.0,
|
||||
"733.3333333333334": 2.5,
|
||||
"33.0": 2.5,
|
||||
"385.0": 2.5,
|
||||
"110.0": 2.0,
|
||||
"275.0": 2.0,
|
||||
"366.6666666666667": 2.0,
|
||||
"513.3333333333333": 2.0,
|
||||
"183.3333333333333": 1.5,
|
||||
"73.33333333333333": 1.5,
|
||||
"352.0": 1.5,
|
||||
"322.6666666666666": 1.0,
|
||||
"234.6666666666667": 1.0,
|
||||
"146.6666666666667": 1.0,
|
||||
"88.0": 1.0,
|
||||
"308.0": 1.0,
|
||||
"54.99999999999999": 1.0,
|
||||
"35.2": 1.0,
|
||||
"879.9999999999999": 1.0,
|
||||
"495.0": 1.0,
|
||||
"484.0": 1.0,
|
||||
"809.5999999999999": 0.5,
|
||||
"704.0": 0.5,
|
||||
"990.0": 0.5,
|
||||
"44.0": 0.5,
|
||||
"188.5714285714286": 0.5,
|
||||
"256.6666666666666": 0.5,
|
||||
"469.3333333333333": 0.5,
|
||||
"806.6666666666666": 0.5,
|
||||
"282.8571428571428": 0.5,
|
||||
"1320.0": 0.5,
|
||||
"605.0": 0.5,
|
||||
"572.0": 0.5,
|
||||
"616.0": 0.5
|
||||
},
|
||||
"Literacy": {
|
||||
"6": 43.0,
|
||||
"4": 31.9,
|
||||
"3": 16.3,
|
||||
"2": 4.6,
|
||||
"1": 2.9,
|
||||
"5": 1.3
|
||||
},
|
||||
"Career": {
|
||||
"4": 30.3,
|
||||
"1": 24.8,
|
||||
"3": 15.3,
|
||||
"2": 14.7,
|
||||
"6": 14.0,
|
||||
"5": 1.0
|
||||
},
|
||||
"Habits": {
|
||||
"Distance": {
|
||||
"1": "31.3% (n=96)",
|
||||
"2": "24.8% (n=76)",
|
||||
"3": "17.6% (n=54)",
|
||||
"4": "16.0% (n=49)",
|
||||
"5": "10.1% (n=31)",
|
||||
"6": "0.3% (n=1)"
|
||||
},
|
||||
"Frequency": {
|
||||
"4": "27.0% (n=83)",
|
||||
"5": "25.4% (n=78)",
|
||||
"2": "17.6% (n=54)",
|
||||
"1": "15.3% (n=47)",
|
||||
"3": "14.7% (n=45)"
|
||||
},
|
||||
"Time": {
|
||||
"4": "35.2% (n=108)",
|
||||
"5": "28.3% (n=87)",
|
||||
"3": "27.4% (n=84)",
|
||||
"2": "7.2% (n=22)",
|
||||
"1": "2.0% (n=6)"
|
||||
},
|
||||
"Transportation": {
|
||||
"3": "57.0% (n=175)",
|
||||
"2": "19.9% (n=61)",
|
||||
"1": "16.3% (n=50)",
|
||||
"4": "5.2% (n=16)",
|
||||
"5": "1.6% (n=5)"
|
||||
}
|
||||
},
|
||||
"Activities": {
|
||||
"Jogging": 0.21,
|
||||
"Workout": 0.35,
|
||||
"Sightseeing": 0.76,
|
||||
"Talking": 0.54,
|
||||
"Photography": 0.27
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
from scipy import stats
|
||||
import json
|
||||
|
||||
df = pd.read_excel('Data_VN_filter_v5.xlsx')
|
||||
|
||||
# Tùy chỉnh font chữ matplotlib nếu cần
|
||||
plt.rcParams.update({'font.size': 12})
|
||||
|
||||
output_data = {}
|
||||
|
||||
# 1. Kiểm tra biến Tuổi (Age)
|
||||
if 'Age' in df.columns:
|
||||
# Convert age to numeric just in case
|
||||
age_data = pd.to_numeric(df['Age'], errors='coerce').dropna()
|
||||
stat, p = stats.shapiro(age_data)
|
||||
output_data['Age'] = {
|
||||
'Mean': age_data.mean(),
|
||||
'Std': age_data.std(),
|
||||
'Min': age_data.min(),
|
||||
'Max': age_data.max(),
|
||||
'Shapiro-Wilk_W': stat,
|
||||
'Shapiro-Wilk_p': p,
|
||||
'Normal_Distribution': bool(p > 0.05)
|
||||
}
|
||||
|
||||
# Plot Age histogram
|
||||
plt.figure(figsize=(8, 5))
|
||||
sns.histplot(age_data, kde=True, color='skyblue')
|
||||
plt.title('Phân phối Tuổi (Age)')
|
||||
plt.xlabel('Tuổi')
|
||||
plt.ylabel('Tần số')
|
||||
plt.savefig('Age_Distribution.png', dpi=300, bbox_inches='tight')
|
||||
plt.close()
|
||||
|
||||
# 2. Nhân khẩu học (Demographics)
|
||||
demo_cols = ['Gender', 'Income', 'Literacy', 'Career']
|
||||
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
|
||||
fig.suptitle('Cơ cấu Nhân khẩu học của Mẫu Khảo sát (N = 307)', fontsize=18, fontweight='bold', y=1.02)
|
||||
|
||||
for i, col in enumerate(demo_cols):
|
||||
if col in df.columns:
|
||||
ax = axes[i//2, i%2]
|
||||
val_counts = df[col].value_counts()
|
||||
|
||||
# Nếu biến có quá nhiều giá trị (như Income), vẽ Histogram thay vì Pie chart
|
||||
if len(val_counts) > 10 or col == 'Income':
|
||||
numeric_data = pd.to_numeric(df[col], errors='coerce').dropna()
|
||||
sns.histplot(numeric_data, kde=True, ax=ax, color='coral', bins=20)
|
||||
ax.set_title(f'Phân phối {col}', fontsize=14, pad=10)
|
||||
ax.set_xlabel(col)
|
||||
ax.set_ylabel('Tần số')
|
||||
else:
|
||||
# Plot Pie Chart cho biến phân loại
|
||||
wedges, texts, autotexts = ax.pie(val_counts, autopct='%1.1f%%', startangle=140,
|
||||
colors=sns.color_palette('Set2'), pctdistance=0.8)
|
||||
ax.legend(wedges, val_counts.index, title=col, loc="center left", bbox_to_anchor=(1, 0.5))
|
||||
ax.set_title(f'Tỷ lệ {col}', fontsize=14, pad=10)
|
||||
|
||||
output_data[col] = df[col].value_counts(normalize=True).mul(100).round(1).to_dict()
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig('Demographics_Charts.png', dpi=300, bbox_inches='tight')
|
||||
plt.close()
|
||||
|
||||
# 3. Thói quen tương tác (Interactions)
|
||||
habit_cols = ['Distance', 'Frequency', 'Time', 'Transportation']
|
||||
output_data['Habits'] = {}
|
||||
for col in habit_cols:
|
||||
if col in df.columns:
|
||||
counts = df[col].value_counts()
|
||||
pcts = df[col].value_counts(normalize=True).mul(100).round(1)
|
||||
output_data['Habits'][col] = {str(k): f"{pcts[k]}% (n={counts[k]})" for k in counts.index}
|
||||
|
||||
# 4. Các hoạt động phổ biến (Activities)
|
||||
# Bảng hỏi thường dùng Yes/No (1/0) hoặc Likert. Tính tỷ lệ % chọn Yes (1).
|
||||
act_cols = ['Jogging', 'Workout', 'Pet', 'Sightseeing', 'Talking', 'Photography']
|
||||
output_data['Activities'] = {}
|
||||
for col in act_cols:
|
||||
# Nếu biến là 'Pet Walking' thay vì 'Pet'
|
||||
actual_col = col if col in df.columns else (col + ' Walking' if col + ' Walking' in df.columns else None)
|
||||
if actual_col:
|
||||
mean_val = pd.to_numeric(df[actual_col], errors='coerce').mean()
|
||||
# Nếu mean < 1.5, có thể là dữ liệu nhị phân (0-1), ngược lại là Likert
|
||||
output_data['Activities'][actual_col] = round(mean_val, 2)
|
||||
|
||||
# Save summary to JSON
|
||||
with open('descriptive_output.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(output_data, f, ensure_ascii=False, indent=4)
|
||||
|
||||
print("Descriptive statistics run complete. Outputs saved.")
|
||||
Reference in New Issue
Block a user