当前位置: 首页 > 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.gsyq.cn/news/1589480.html

相关文章:

  • PianoPlayer深度解析:基于动态规划算法的钢琴指法生成技术实现
  • 拆解 musl libc 启动流程:从 __libc_start_main 到 main() 到底发生了什么?
  • 2026年重庆山三云企售后跟进的技术解析与工作要点说明
  • 现代gpu编程系统教程(一) ------- 概述
  • Bunny DNS 免费!多维度优化助力构建更快更安全应用
  • LoRA微调实战:在笔记本上高效微调大模型的完整指南
  • SAMTEC/申泰 asp系列 134488 01 中文资料 板对板连接器
  • Django毕业设计-基于 Django + 协同过滤算法的电影推荐系统设计与实现 基于 Django + 协同过滤算法的个性化电影推荐平台(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • LSTM时间序列实战:工业级预测的12个关键工程细节
  • 电影评分为什么是离散分布?认知、平台与技术的三重约束
  • 从 PHP 到 AI + Golang,程序员自救转型手记(六):泛型基服务、控制器、仓储实现,自动发现和注册业务路由
  • 线性回归实战:从数据到利润的商业建模指南
  • 一个项目对接N个团队,沟通到崩溃?公墓设计急需一站式的“省心方案”
  • 硬件安全引擎描述符机制:嵌入式网络加密加速的核心原理与实践
  • LLM基础原理与应用指南
  • 汽车调光玻璃透光率的太阳光模拟验证方法
  • MPC8315E安全引擎寄存器深度解析:MDEU、PKEU、RNGU实战配置与避坑指南
  • Windows 10 Microsoft Store 安装 Ubuntu 的默认目录及迁移指南
  • XGBoost标签噪声识别与清洗实战指南
  • 从素材库快速做歌的平台
  • 跨平台全栈开发神器FlyEnv,秒速切换多语言环境
  • Adobe-GenP 3.0完整指南:三步解锁Adobe全家桶的简单方案
  • 3步永久免费激活IDM:解锁Internet Download Manager完整功能的终极指南
  • 革命性Koikatsu Sunshine完整优化方案:一键解锁专业级角色创作体验
  • 如何用PX4神经网络控制技术让无人机自主巡检电力线路?
  • 告别网盘限速烦恼:开源下载助手LinkSwift让你的文件传输飞起来
  • 统一搜索与推荐:大语言模型时代的信息获取新探索
  • OpenCorePkg实战手册:构建稳定黑苹果引导的5个关键场景
  • 3步掌握Chrome图片格式转换:一键另存为JPG/PNG/WebP的终极指南
  • SSH 隧道实用指南:本地与远程端口转发全解析,助你成隧道高手!