当前位置: 首页 > news >正文

东西方时尚审美差异量化程序,分别统计男女消费者对中西服饰偏好打分。

用 Python 构建东西方时尚审美差异量化分析程序,通过对男女消费者的中西服饰偏好打分,统计分析性别与文化背景对审美偏好的影响,并以中立视角呈现分析结果。

一、实际应用场景描述

在《时尚产业与品牌创新》课程中,"跨文化审美差异"是国际时尚品牌本土化战略的核心议题。具体表现为:

- 东方审美偏好:含蓄、留白、对称、自然意象(山水、花鸟)、重意境与整体和谐感。

- 西方审美偏好:外放、曲线强调、视觉冲击、个体表达、重轮廓与比例张力。

- 性别差异:研究表明,男性消费者普遍更看重"功能性+身份象征",女性消费者更关注"美学细节+情感共鸣",但在不同文化背景下表现不同。

品牌面临核心问题:

"做全球化产品时,如何平衡东西方审美差异?男女消费者的跨文化偏好是否存在显著差异?哪些设计要素是'审美公约数'?"

本程序用 Python 构建审美维度评分 + 性别×文化双因素方差分析 + 可视化对比的完整统计框架,量化东西方时尚审美差异。

二、引入痛点

- 审美偏好研究多停留在"东方含蓄、西方奔放"的定性描述,缺乏可量化的维度评分体系。

- 真实跨文化消费者调研成本高(需中英美法日等多国样本),手工整理问卷数据效率低。

- 缺乏统计检验框架来判断"男女审美差异是否显著""东西方差异是否大于性别差异"等核心问题。

⇒ 用 Python 构建合成问卷数据 + 多维度 ANOVA 分析 + 可视化仪表盘,模拟完整分析流程。

三、核心逻辑讲解

1. 审美维度设计

基于审美心理学与时尚理论,提炼六大可量化审美维度:

维度 说明 东方偏好方向 西方偏好方向

色彩饱和度(Color Saturation) 0=低饱和莫兰迪 100=高饱和撞色 偏中低饱和 偏高饱和

剪裁复杂度(Cut Complexity) 0=极简直线 100=多层叠搭 偏简约流畅 偏结构感

装饰密度(Ornamentation) 0=无装饰 100=满绣满印 偏意境留白 偏繁复装饰

轮廓夸张度(Silhouette Boldness) 0=贴身自然 100=夸张廓形 偏自然垂坠 偏结构夸张

文化符号强度(Cultural Symbolism) 0=无文化标识 100=强文化符号 偏含蓄隐喻 偏直白表达

功能性权重(Functionality Weight) 0=纯装饰 100=纯功能 偏装饰意境 偏功能实用

2. 性别×文化双因素模型

审美偏好得分 = 基础分 + 文化效应 + 性别效应 + 交互效应 + 随机噪声

其中:

- 文化效应:东方 vs 西方的整体偏移

- 性别效应:男性 vs 女性的整体偏移

- 交互效应:文化×性别的交叉影响(如东方男性 vs 西方女性的差异模式不同)

3. 统计方法

- 描述性统计:各维度均值、标准差、分布

- 独立样本 t 检验:东西方差异是否显著 / 男女差异是否显著

- 双因素 ANOVA:文化 × 性别 交互效应检验

- 效应量(Cohen's d):差异的实际意义大小,而非仅看 p 值

四、代码模块化(aesthetic_preference_analysis.py)

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

"""

aesthetic_preference_analysis.py

东西方时尚审美差异量化分析

男女消费者对中西服饰偏好的统计建模与显著性检验

依赖: numpy, pandas, matplotlib, scipy, statsmodels

安装: pip install numpy pandas matplotlib scipy statsmodels

"""

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from matplotlib import rcParams

from scipy import stats

import statsmodels.api as sm

from statsmodels.formula.api import ols

from dataclasses import dataclass, field

from typing import Dict, List, Tuple

from enum import Enum

# 中文字体设置

rcParams['font.sans-serif'] = ['Noto Sans CJK SC', 'SimHei', 'Microsoft YaHei']

rcParams['axes.unicode_minus'] = False

# ──────────────────────────────────────────────

# 1. 枚举与配置模块

# ──────────────────────────────────────────────

class Culture(Enum):

"""文化背景"""

EAST = "东方"

WEST = "西方"

class Gender(Enum):

"""性别"""

MALE = "男性"

FEMALE = "女性"

@dataclass

class AestheticDimension:

"""审美维度定义"""

name_en: str

name_cn: str

description: str

# 东西方基准偏移(0-100 量表)

east_base: float

west_base: float

# 性别偏移(叠加在文化基准上)

male_shift: float

female_shift: float

# 交互效应强度(文化×性别)

interaction_strength: float

# 组内标准差

std: float

# ──────────────────────────────────────────────

# 2. 审美维度数据库模块

# ──────────────────────────────────────────────

class AestheticDatabase:

"""

东西方时尚审美维度评分体系

基于审美心理学文献与跨文化时尚研究综合构建

"""

@staticmethod

def get_dimensions() -> Dict[str, AestheticDimension]:

"""返回六大审美维度的完整定义"""

return {

'color_saturation': AestheticDimension(

name_en='Color Saturation',

name_cn='色彩饱和度',

description='对色彩鲜艳/柔和程度的偏好',

east_base=35, west_base=65,

male_shift=-5, female_shift=+8,

interaction_strength=0.3, std=15

),

'cut_complexity': AestheticDimension(

name_en='Cut Complexity',

name_cn='剪裁复杂度',

description='对服装结构层次感的偏好',

east_base=40, west_base=60,

male_shift=-3, female_shift=+5,

interaction_strength=0.2, std=12

),

'ornamentation': AestheticDimension(

name_en='Ornamentation',

name_cn='装饰密度',

description='对装饰元素(刺绣/印花/铆钉等)的接受度',

east_base=55, west_base=50,

male_shift=-12, female_shift=+10,

interaction_strength=0.5, std=18

),

'silhouette_boldness': AestheticDimension(

name_en='Silhouette Boldness',

name_cn='轮廓夸张度',

description='对廓形夸张程度的接受度',

east_base=30, west_base=70,

male_shift=-8, female_shift=+5,

interaction_strength=0.4, std=16

),

'cultural_symbolism': AestheticDimension(

name_en='Cultural Symbolism',

name_cn='文化符号强度',

description='对显性文化标识(龙纹/十字架/图腾等)的偏好',

east_base=45, west_base=55,

male_shift=+3, female_shift=-2,

interaction_strength=0.3, std=14

),

'functionality_weight': AestheticDimension(

name_en='Functionality Weight',

name_cn='功能性权重',

description='对服装实用功能(口袋/防水/多用途)的重视程度',

east_base=50, west_base=55,

male_shift=+15, female_shift=-8,

interaction_strength=0.6, std=13

)

}

# ──────────────────────────────────────────────

# 3. 合成数据生成模块

# ──────────────────────────────────────────────

class SurveyDataGenerator:

"""

生成模拟的消费者审美偏好问卷数据

基于维度定义中的文化/性别效应叠加生成

"""

PERCEIVED_QUALITY_BASE = {

Culture.EAST: {

Gender.MALE: 62, Gender.FEMALE: 68

},

Culture.WEST: {

Gender.MALE: 58, Gender.FEMALE: 72

}

}

SAMPLE_SIZE_PER_CELL = 150 # 每个 文化×性别 组合的样本量

@classmethod

def generate(cls, seed: int = 42) -> pd.DataFrame:

"""

生成完整问卷数据集

每行 = 一位受访者对六大维度的评分(0-100)

加上人口统计变量与综合审美得分

"""

np.random.seed(seed)

dims = AestheticDatabase.get_dimensions()

rows = []

for culture in Culture:

for gender in Gender:

n = cls.SAMPLE_SIZE_PER_CELL

for i in range(n):

respondent = {

'respondent_id': f"{culture.name[:1]}{gender.name[:1]}_{i:04d}",

'culture': culture.value,

'culture_code': 0 if culture == Culture.EAST else 1,

'gender': gender.value,

'gender_code': 0 if gender == Gender.MALE else 1,

}

# 各维度评分

total_score = 0

for key, dim in dims.items():

base = dim.east_base if culture == Culture.EAST else dim.west_base

gender_shift = (dim.male_shift if gender == Gender.MALE

else dim.female_shift)

interaction = (dim.interaction_strength

* (1 if culture == Culture.WEST else -1)

* (1 if gender == Gender.FEMALE else -1))

true_score = base + gender_shift + interaction

noise = np.random.normal(0, dim.std)

final_score = np.clip(true_score + noise, 0, 100)

respondent[key] = round(final_score, 1)

total_score += final_score

# 综合审美得分(标准化到 0-100)

respondent['overall_aesthetic_score'] = round(

total_score / len(dims), 1

)

# 人口统计模拟(年龄、收入层级)

respondent['age'] = int(np.random.choice(

[22, 27, 32, 37, 42, 47],

p=[0.15, 0.30, 0.25, 0.15, 0.10, 0.05]

))

respondent['income_tier'] = np.random.choice(

['Low', 'Mid', 'High'], p=[0.25, 0.50, 0.25]

)

rows.append(respondent)

return pd.DataFrame(rows)

# ──────────────────────────────────────────────

# 4. 统计分析模块

# ──────────────────────────────────────────────

class AestheticAnalyzer:

"""核心统计分析引擎"""

DIMENSION_KEYS = list(AestheticDatabase.get_dimensions().keys())

DIMENSION_NAMES = {

k: v.name_cn for k, v in AestheticDatabase.get_dimensions().items()

}

@classmethod

def describe_by_group(cls, df: pd.DataFrame,

group_cols: List[str]) -> pd.DataFrame:

"""按分组计算各维度描述性统计"""

return df.groupby(group_cols)[cls.DIMENSION_KEYS].agg(

['mean', 'std', 'count']

).round(2)

@classmethod

def t_test_culture(cls, df: pd.DataFrame) -> pd.DataFrame:

"""东西方差异 t 检验(全样本)"""

results = []

for key in cls.DIMENSION_KEYS:

east = df[df['culture'] == Culture.EAST.value][key]

west = df[df['culture'] == Culture.WEST.value][key]

t_stat, p_value = stats.ttest_ind(east, west, equal_var=False)

cohen_d = (east.mean() - west.mean()) / np.sqrt(

(east.std()**2 + west.std()**2) / 2

)

results.append({

'dimension': cls.DIMENSION_NAMES[key],

'east_mean': round(east.mean(), 2),

'west_mean': round(west.mean(), 2),

'diff': round(east.mean() - west.mean(), 2),

't_statistic': round(t_stat, 3),

'p_value': round(p_value, 4),

'cohen_d': round(cohen_d, 3),

'significant': p_value < 0.05,

'sig_level': ('**' if p_value < 0.01

else '*' if p_value < 0.05 else 'ns')

})

return pd.DataFrame(results)

@classmethod

def t_test_gender(cls, df: pd.DataFrame) -> pd.DataFrame:

"""男女差异 t 检验(全样本)"""

results = []

for key in cls.DIMENSION_KEYS:

male = df[df['gender'] == Gender.MALE.value][key]

female = df[df['gender'] == Gender.FEMALE.value][key]

t_stat, p_value = stats.ttest_ind(male, female, equal_var=False)

cohen_d = (male.mean() - female.mean()) / np.sqrt(

(male.std()**2 + female.std()**2) / 2

)

results.append({

'dimension': cls.DIMENSION_NAMES[key],

'male_mean': round(male.mean(), 2),

'female_mean': round(female.mean(), 2),

'diff': round(male.mean() - female.mean(), 2),

't_statistic': round(t_stat, 3),

'p_value': round(p_value, 4),

'cohen_d': round(cohen_d, 3),

'significant': p_value < 0.05,

'sig_level': ('**' if p_value < 0.01

else '*' if p_value < 0.05 else 'ns')

})

return pd.DataFrame(results)

@classmethod

def two_way_anova(cls, df: pd.DataFrame) -> pd.DataFrame:

"""

双因素 ANOVA:文化 × 性别 对综合审美得分的影响

"""

results = []

for key in cls.DIMENSION_KEYS + ['overall_aesthetic_score']:

# 构建 OLS 模型

formula = f'{key} ~ C(culture) * C(gender)'

model = ols(formula, data=df).fit()

anova_table = sm.stats.anova_lm(model, typ=2)

row = {'dimension': cls.DIMENSION_NAMES.get(key, key)}

# 提取各效应

for effect in ['C(culture)', 'C(gender)', 'C(culture):C(gender)']:

if effect in anova_table.index:

row[f'{effect}_F'] = round(anova_table.loc[effect, 'F'], 3)

row[f'{effect}_p'] = round(anova_table.loc[effect, 'PR(>F)'], 4)

row[f'{effect}_sig'] = ('**' if row[f'{effect}_p'] < 0.01

else '*' if row[f'{effect}_p'] < 0.05

else 'ns')

else:

row[f'{effect}_F'] = np.nan

row[f'{effect}_p'] = np.nan

row[f'{effect}_sig'] = '—'

results.append(row)

return pd.DataFrame(results)

@classmethod

def find_aesthetic_overlap(cls, df: pd.DataFrame) -> pd.DataFrame:

"""

寻找"审美公约数"——东西方男女都给出高分的维度

"""

results = []

for key in cls.DIMENSION_KEYS:

east_male = df[(df['culture'] == '东方') & (df['gender'] == '男性')][key].mean()

east_female = df[(df['culture'] == '东方') & (df['gender'] == '女性')][key].mean()

west_male = df[(df['culture'] == '西方') & (df['gender'] == '男性')][key].mean()

west_female = df[(df['culture'] == '西方') & (df['gender'] == '女性')][key].mean()

overall_mean = df[key].mean()

min_group = min(east_male, east_female, west_male, west_female)

max_group = max(east_male, east_female, west_male, west_female)

spread = max_group - min_group

results.append({

'dimension': cls.DIMENSION_NAMES[key],

'east_male': round(east_male, 1),

'east_female': round(east_female, 1),

'west_male': round(west_male, 1),

'west_female': round(west_female, 1),

'overall_mean': round(overall_mean, 1),

'min': round(min_group, 1),

'max': round(max_group, 1),

'spread': round(spread, 1),

'is_consensus': spread < 15 # 四组差异 < 15 分视为共识区

})

return pd.DataFrame(results)

# ──────────────────────────────────────────────

# 5. 可视化仪表盘模块

# ──────────────────────────────────────────────

class Dashboard:

"""多面板可视化仪表盘"""

CULTURE_COLORS = {'东方': '#E74C3C', '西方': '#3498DB'}

GENDER_MARKERS = {'男性': 's', '女性': 'o'}

GENDER_COLORS = {'男性': '#2C3E50', '女性': '#E91E63'}

DIMENSION_SHORT = {

'color_saturation': '色彩饱和度',

'cut_complexity': '剪裁复杂度',

'ornamentation': '装饰密度',

'silhouette_boldness': '轮廓夸张度',

'cultural_symbolism': '文化符号',

'functionality_weight': '功能性'

}

@classmethod

def plot_dashboard(cls,

df: pd.DataFrame,

culture_ttest: pd.DataFrame,

gender_ttest: pd.DataFrame,

anova_df: pd.DataFrame,

overlap_df: pd.DataFrame,

filename: str = "aesthetic_preference_dashboard.png"):

fig = plt.figure(figsize=(24, 20))

fig.suptitle('东西方时尚审美差异量化分析',

fontsize=22, fontweight='bold', y=0.99)

# ── 图1:文化×性别 分组雷达图 ──

ax1 = fig.add_subplot(3, 2, 1, polar=True)

cls._plot_group_radar(ax1, df)

# ── 图2:东西方差异(Cohen's d 森林图) ──

ax2 = fig.add_subplot(3, 2, 2)

cls._plot_culture_effect(ax2, culture_ttest)

# ── 图3:男女差异(分维度箱线图) ──

ax3 = fig.add_subplot(3, 2, 3)

cls._plot_gender_boxplot(ax3, df)

# ── 图4:双因素 ANOVA 热力图 ──

ax4 = fig.add_subplot(3, 2, 4)

cls._plot_anova_heatmap(ax4, anova_df)

# ── 图5:审美公约数 ──

ax5 = fig.add_subplot(3, 2, 5)

cls._plot_overlap_chart(ax5, overlap_df)

# ── 图6:综合审美得分分布 ──

ax6 = fig.add_subplot(3, 2, 6)

cls._plot_overall_distribution(ax6, df)

plt.tight_layout(rect=[0, 0, 1, 0.96])

plt.savefig(filename, dpi=150, bbox_inches='tight')

plt.show()

print(f"[INFO] 仪表盘已保存: {filename}")

@classmethod

def _plot_group_radar(cls, ax, df: pd.DataFrame):

"""四组(东西×男女)雷达图"""

dims = list(cls.DIMENSION_SHORT.keys())

angles = np.linspace(0, 2 * np.pi, len(dims), endpoint=False).tolist()

angles += angles[:1]

ax.set_theta_offset(np.pi / 2)

ax.set_theta_direction(-1)

for culture in ['东方', '西方']:

for gender in ['男性', '女性']:

subset = df[(df['culture'] == culture) & (df['gender'] == gender)]

values = []

for d in dims:

values.append(subset[d].mean())

values += values[:1]

color = cls.CULTURE_COLORS[culture]

marker = cls.GENDER_MARKERS[gender]

linestyle = '-' if gender == '女性' else '--'

label = f"{culture}{gender}"

ax.plot(angles, values, marker, linestyle=linestyle,

color=color, linewidth=1.5, markersize=4, label=label)

ax.fill(angles, values, alpha=0.03, color=color)

ax.set_xticks(angles[:-1])

ax.set_xticklabels([cls.DIMENSION_SHORT[d] for d in dims], fontsize=8)

ax.set_ylim(0, 100)

ax.set_title('文化×性别 审美维度画像', fontsize=13, fontweight='bold', pad=15)

ax.legend(fontsize=7, loc='upper right', bbox_to_anchor=(1.25, 1.1))

@classmethod

def _plot_culture_effect(cls, ax, ttest_df: pd.DataFrame):

"""东西方差异 Cohen's d 森林图"""

df = ttest_df.sort_values('cohen_d')

y_pos = range(len(df))

colors = []

for _, row in df.iterrows():

if row['significant'] and abs(row['cohen_d']) > 0.5:

colors.append('#e74c3c')

elif row['significant']:

colors.append('#f39c12')

else:

colors.append('#95a5a6')

ax.barh(y_pos, df['cohen_d'], color=colors, edgecolor='white')

ax.set_yticks(y_pos)

ax.set_yticklabels(df['dimension'], fontsize=9)

ax.set_xlabel("Cohen's d(负=东方高于西方)")

ax.set_title('东西方审美差异效应量', fontsize=13, fontweight='bold')

# 标注数值

for i, (_, row) in enumerate(df.iterrows()):

sig = row['sig_level']

ax.text(row['cohen_d'] + (0.05 if row['cohen_d'] >= 0 else -0.05),

i, f"{row['cohen_d']:.2f} {sig}",

va='center', fontsize=8, fontweight='bold',

ha='left' if row['cohen_d'] >= 0 else 'right')

ax.axvline(x=0, color='gray', linewidth=0.8)

ax.axvline(x=-0.5, color='gray', linestyle=':', alpha=0.5)

ax.axvline(x=0.5, color='gray', linestyle=':', alpha=0.5)

ax.grid(axis='x', alpha=0.3)

@classmethod

def _plot_gender_boxplot(cls, ax, df: pd.DataFrame):

"""男女差异箱线图(分维度)"""

dims = list(cls.DIMENSION_SHORT.keys())

data_by_group = []

labels = []

colors = []

for dim in dims:

for gender in ['男性', '女性']:

subset = df[df['gender'] == gender][dim]

if len(subset) > 0:

data_by_group.append(subset.values)

labels.append(f"{cls.DIMENSION_SHORT[dim]}-{gender}")

colors.append(cls.GENDER_COLORS[gender])

if len(data_by_group) > 0:

bp = ax.boxplot(data_by_group, patch_artist=True, labels=labels,

medianprops=dict(color='black', linewidth=2))

for patch, color in zip(bp['boxes'], colors):

patch.set_facecolor(color)

patch.set_alpha(0.5)

ax.set_ylabel('评分 (0-100)')

ax.set_title('男女审美差异分布', fontsize=13, fontweight='bold')

ax.tick_params(axis='x', rotation=45, labelsize=7)

ax.grid(axis='y', alpha=0.3)

@classmethod

def _plot_anova_heatmap(cls, ax, anova_df: pd.DataFrame):

"""ANOVA F 值热力图"""

# 提取文化主效应和性别主效应的 F 值

dims = anova_df['dimension'].tolist()

culture_f = []

gender_f = []

interaction_f = []

for _, row in anova_df.iterrows():

culture_f.append(row.get('C(culture)_F', np.nan))

gender_f.append(row.get('C(gender)_F', np.nan))

interaction_f.append(row.get('C(culture):C(gender)_F', np.nan))

data = np.array([culture_f, gender_f, interaction_f])

im = ax.imshow(data, cmap='YlOrRd', aspect='auto')

ax.set_xticks(range(len(dims)))

ax.set_xticklabels(dims, rotation=30, ha='right', fontsize=8)

ax.set_yticks(range(3))

ax.set_yticklabels(['文化主效应', '性别主效应', '交互效应'], fontsize=9)

for i in range(3):

for j in range(len(dims)):

val = data[i, j]

if not np.isnan(val):

ax.text(j, i, f'{val:.1f}', ha

利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!

http://www.jsqmd.com/news/1077547/

相关文章:

  • 免费文档下载工具终极指南:如何用kill-doc脚本突破30+平台限制
  • 数据聚类如何驱动业务决策:从混沌到可执行分群的实战指南
  • 【计算机毕业设计案例】基于 Django + 协同过滤算法的电影收藏推荐管理平台设计与实现 基于 Django + 协同过滤算法的在线观影智能推荐系统(程序+文档+讲解+定制)
  • PianoPlayer深度解析:基于动态规划算法的钢琴指法生成技术实现
  • 拆解 musl libc 启动流程:从 __libc_start_main 到 main() 到底发生了什么?
  • MCP Inspector 调试——开发必备调试工具实战
  • [Android] AudioEditor音频剪辑高级版-多轨+分割+混合+超级好用
  • Sunshine游戏串流终极指南:如何用开源软件打造专业级游戏串流服务器
  • OFDM项目开发(05):FPGA跨时钟域IFFT数据接口设计——异步FIFO + 精准时序控制
  • STM32-S369-存取柜+光敏+灯光+消毒+取件码+二维码+语音播报+存件+手机号录入+后台数据+4舵机+OLED屏+按键+(无线方式选择)-2(设计源文件+万字报告+讲解)(支持资料、图片参考_
  • 循环学习率CLR实战指南:提升收敛速度与泛化能力
  • Adobe-GenP 3.0:开源逆向工程的艺术与实用指南
  • OpenCLIP与Diffusion Bee:AI模型工程化落地实战指南
  • 5大理由:为什么企业需要billd-desk私有化部署的远程控制解决方案
  • LoRA微调实战:在笔记本上高效微调大模型的完整指南
  • Bunny DNS 免费!多维度优化助力构建更快更安全应用
  • 2026年重庆山三云企售后跟进的技术解析与工作要点说明
  • 现代gpu编程系统教程(一) ------- 概述
  • NCMDump是什么?网易云NCM格式转换工具详解及使用教程(附替代方案)
  • 3.7V升压5V2A芯片哪个好?PW6276同步升压低功耗方案
  • 基于 OB2513x开关芯片的PSR DCM模式反激电源的FB波形
  • 欧拉-丸山法在McKean-Vlasov SDE不变测度收敛性中的分析与MATLAB实践
  • Django毕业设计-基于 Django + 协同过滤算法的电影推荐系统设计与实现 基于 Django + 协同过滤算法的个性化电影推荐平台(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • SAMTEC/申泰 asp系列 134488 01 中文资料 板对板连接器
  • 2019年全球10km分辨率人类发展指数栅格数据集
  • 星载深度学习实战:空间遥感与自主导航的轻量AI部署
  • LSTM时间序列实战:工业级预测的12个关键工程细节
  • 电影评分为什么是离散分布?认知、平台与技术的三重约束
  • 从 PHP 到 AI + Golang,程序员自救转型手记(六):泛型基服务、控制器、仓储实现,自动发现和注册业务路由
  • 游泳池表面涂装,从别墅泳池到大型主题乐园,选对材料是关键