引言:认知融合问卷分析的重要性
认知融合(Cognitive Fusion)是接纳与承诺疗法(ACT)中的核心概念,指个体将思想与现实混淆,过度认同内在体验的心理过程。认知融合问卷(如CFQ, Cognitive Fusion Questionnaire)是测量这一构念的常用工具。在心理学研究和临床实践中,对这类问卷进行科学分析至关重要,它直接影响研究结论的可靠性和干预效果的评估。本指南将从理论基础出发,系统阐述从数据清洗到高级统计建模的全流程分析方法,帮助研究者掌握严谨的分析技术。
第一部分:认知融合的理论基础与问卷设计
认知融合的概念框架
认知融合的概念源于关系框架理论(RFT),它描述了人类语言和认知的”衍生关系”特性如何导致心理困扰。当个体将语言等同于现实时,就会产生认知融合,例如将”我感到焦虑”等同于”我是一个焦虑的人”。理解这一理论背景对问卷分析至关重要,因为它决定了问卷应测量的核心维度和潜在的心理结构。
常用认知融合问卷介绍
目前最常用的是Gil-lucas等人开发的CFQ(Cognitive Fusion Questionnaire),包含7个条目,采用7点计分(1=非常不符合,7=非常符合)。例如条目1:”我的想法会让我感到情绪困扰”。其他变体包括简版CFQ-7和针对特定人群的改编版本。了解问卷的结构和计分方式是分析的前提。
1.1 问卷设计的理论依据
认知融合问卷的设计严格遵循ACT理论模型。每个条目都针对特定的认知融合表现:
- 思维内容融合(如”我必须控制我的想法”)
- 思维过程融合(如”如果我有负面想法,就意味着我是坏人”)
- 思维-情绪融合(如”我的想法让我感到痛苦”)
这种理论驱动的设计确保了问卷的内容效度,也为后续的因子分析提供了理论预期。
第二部分:数据清洗与预处理
数据收集与导入
在分析之前,首先需要规范地收集数据。假设我们使用Qualtrics或问卷星等平台收集了500份CFQ问卷数据,导出为CSV格式。使用Python的pandas库进行初步导入:
import pandas as pd
import numpy as np
# 导入数据
df = pd.read_csv('cognitive_fusion_data.csv')
# 查看数据基本信息
print(df.info())
print(df.head())
# 检查数据维度
print(f"数据集包含 {df.shape[0]} 个样本,{df.shape[1]} 个变量")
缺失值处理
缺失值是问卷数据常见问题。需要系统评估缺失模式:
# 计算每个变量的缺失比例
missing_ratio = df.isnull().mean() * 100
print("各变量缺失比例:")
print(missing_ratio)
# 可视化缺失模式
import missingno as msno
msno.matrix(df)
# 根据缺失机制选择处理方法
# 如果是完全随机缺失(MCAR),可以使用删除或均值插补
# 如果是随机缺失(MAR),建议使用多重插补
# 简单删除法(适用于缺失<5%)
df_clean = df.dropna()
# 均值插补(适用于小样本)
df_imputed = df.fillna(df.mean())
# 多重插补(推荐方法)
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imputer = IterativeImputer(random_state=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
异常值检测与处理
异常值可能影响统计结果,需要系统检测:
# 方法1:箱线图法检测异常值
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.boxplot(data=df_imputed)
plt.title('CFQ各条目得分箱线图')
plt.show()
# 方法2:Z分数法(适用于正态分布)
from scipy import stats
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > 3).any(axis=1)
print(f"检测到 {outliers.sum()} 个异常值样本")
# 方法3:孤立森林算法(适用于多维数据)
from sklearn.ensemble import IsolationForest
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outlier_labels = iso_forest.fit_predict(df_imputed)
outlier_indices = np.where(outlier_labels == -1)[0]
print(f"孤立森林检测到 {len(outlier_indices)} 个异常值")
# 处理策略:根据理论判断是否删除或Winsorize
# Winsorize处理(将极端值替换为第5/95百分位数)
from scipy.stats.mstats import winsorize
df_winsorized = df_imputed.apply(lambda x: winsorize(x, limits=[0.05, 0.05]))
数据分布检验
检查数据是否符合参数检验的假设:
# 正态性检验(Shapiro-Wilk检验)
for col in df_winsorized.columns:
stat, p = stats.shapiro(df_winsorized[col])
print(f"{col}: W={stat:.3f}, p={p:.4f}")
if p < 0.05:
print(f" → 拒绝正态性假设")
else:
print(f" → 接受正态性假设")
# 可视化分布
plt.figure(figsize=(12, 8))
for i, col in enumerate(df_winsorized.columns, 1):
plt.subplot(2, 4, i)
sns.histplot(df_winsorized[col], kde=True)
plt.title(col)
plt.tight_layout()
plt.show()
数据标准化与反向计分
检查问卷是否有反向计分条目并进行转换:
# 假设CFQ的第2、4、6条目是反向计分(实际需根据问卷说明)
reverse_items = ['CFQ2', 'CFQ4', 'CFQ6']
for item in reverse_items:
if item in df_winsorized.columns:
# 反向计分:7点计分转换为1-7的反向
df_winsorized[item] = 8 - df_winsorized[item]
print(f"已反向计分:{item}")
# 计算总分(如果需要)
df_winsorized['CFQ_Total'] = df_winsorized.sum(axis=1)
print("CFQ总分描述统计:")
print(df_winsorized['CFQ_Total'].describe())
第三部分:信度分析
3.1 内部一致性信度
内部一致性反映问卷各条目测量同一构念的程度:
import pingouin as pg
# 计算Cronbach's Alpha
alpha_result = pg.cronbach_alpha(data=df_winsorized.iloc[:, :7])
print(f"Cronbach's Alpha系数: {alpha_result[0]:.3f}")
print(f"95%置信区间: ({alpha_result[1][0]:.3f}, {alpha_result[1][1]:.3f})")
# 逐项删除后的Alpha值
for item in df_winsorized.columns[:7]:
alpha_if_deleted = pg.cronbach_alpha(data=df_winsorized.drop(columns=[item]))
print(f"删除 {item} 后的Alpha: {alpha_if_deleted[0]:.3f}")
# 分半信度(如果问卷条目较多)
# 将条目分为奇偶两部分
odd_items = df_winsorized.columns[0::2] # 奇数索引
even_items = df_w1
even_items = df_winsorized.columns[1::2] # 偶数索引
odd_sum = df_winsorized[odd_items].sum(axis=1)
even_sum = df_winsorized[even_items].sum(axis=1)
# Spearman-Brown校正
split_half = pg.corr(odd_sum, even_sum)
r = split_half['r'].values[0]
spearman_brown = (2 * r) / (1 + r)
print(f"分半信度系数(Spearman-Brown校正): {spearman_brown:.3f}")
3.2 重测信度
如果有纵向数据,可以计算重测信度:
# 假设有时间1和时间2的数据
# df_long = pd.read_csv('longitudinal_data.csv')
# 计算皮尔逊相关系数
# retest_corr = pg.corr(df_long['CFQ_T1'], df_long['CFQ_T2'])
# print(f"重测信度: {retest_corr['r'].values[0]:.3f}")
# 如果数据是配对样本,可以使用ICC
# from sklearn.metrics import cohen_kappa_score
# 或使用pingouin的ICC函数
# icc = pg.intraclass_corr(data=df_long, targets='subject', raters='time', ratings='CFQ_score')
3.3 信度结果解读标准
- Cronbach’s Alpha:>0.7 可接受,>0.8 良好,>0.9 优秀
- 分半信度:>0.7 可接受
- 重测信度:>0.7 表明时间稳定性良好
如果信度不达标,需要检查:
- 条目是否测量同一构念
- 是否存在反向计分错误
- 样本量是否足够
- 被试是否理解条目含义
第四部分:效度分析
4.1 结构效度:探索性因子分析(EFA)
EFA用于探索问卷的潜在结构:
from factor_analyzer import FactorAnalyzer
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
from factor_analyzer.factor_analyzer import calculate_kmo
# 1. 适用性检验
# Bartlett球形检验
chi_square_value, p_value = calculate_bartlett_sphericity(df_winsorized.iloc[:, :7])
print(f"Bartlett球形检验: χ² = {chi_square_value:.2f}, p = {p_value:.4f}")
# KMO检验
kmo_all, kmo_model = calculate_kmo(df_winsorized.iloc[:, :7])
print(f"KMO值: {kmo_model:.3f}")
print("KMO标准: >0.6 可接受,>0.8 良好")
# 2. 因子提取
fa = FactorAnalyzer(n_factors=1, rotation=None) # 理论预期是单因子结构
fa.fit(df_winsorized.iloc[:, :7])
# 查看因子载荷
loadings = fa.loadings_
print("因子载荷矩阵:")
for i, item in enumerate(df_winsorized.columns[:7]):
print(f"{item}: {loadings[i, 0]:.3f}")
# 查看公因子方差
communalities = fa.get_communalities()
print("\n公因子方差:")
for i, item in enumerate(df_winsorized.columns[:7]):
print(f"{item}: {communalities[i]:.3f}")
# 3. 碎石图确定因子数量
fa = FactorAnalyzer(n_factors=7, rotation=None)
fa.fit(df_winsorized.iloc[:, :7])
ev, v = fa.get_eigenvalues()
plt.figure(figsize=(8, 6))
plt.plot(range(1, 8), ev, 'o-')
plt.axhline(y=1, color='r', linestyle='--')
plt.title('碎石图')
plt.xlabel('因子数量')
plt.ylabel('特征值')
plt.show()
# 4. 验证性因子分析(CFA)
import semopy as sem
# 定义模型(单因子模型)
model_spec = """
# 测量模型
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
"""
# 拟合模型
mod = sem.Model(model_spec)
mod.fit(df_winsorized.iloc[:, :7])
print(mod.summary())
# 模型拟合指标
# CFI > 0.9, TLI > 0.9, RMSEA < 0.08, SRMR < 0.08
4.2 效标效度
评估问卷与其他变量的关系:
# 假设我们有焦虑量表(Anxiety)、抑郁量表(Depression)和生活满意度(LifeSat)
# 计算相关矩阵
criteria_vars = ['Anxiety', 'Depression', 'LifeSat']
cfq_vars = df_winsorized.columns[:7]
# 合并数据(假设df_full包含所有变量)
# 相关分析
corr_matrix = df_full[cfq_vars + criteria_vars].corr()
print("CFQ与效标变量的相关矩阵:")
print(corr_matrix.loc[criteria_vars, cfq_vars])
# 绘制热图
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('CFQ与效标变量相关矩阵')
plt.show()
# 差异检验:高分组 vs 低分组
# 创建高分组(前27%)和低分组(后27%)
cfq_total = df_full[cfq_vars].sum(axis=1)
high_group = df_full[cfq_total > np.percentile(cfq_total, 73)]
low_group = df_full[cfq_total < np.percentile(cfq_total, 27)]
# 比较两组在效标变量上的差异
from scipy.stats import ttest_ind
for var in criteria_vars:
t_stat, p_val = ttest_ind(high_group[var], low_group[var])
print(f"{var}: t = {t_stat:.3f}, p = {p_val:.4f}")
4.3 聚合效度与区分效度
# 聚合效度:CFQ与ACT其他核心过程的关系
# 假设我们有接纳量表(AAQ)、正念(FFMQ)等
act_vars = ['AAQ', 'FFMQ', 'Values']
corr_matrix_act = df_full[cfq_vars + act_vars].corr()
print("CFQ与ACT核心过程的相关:")
print(corr_matrix_act.loc[act_vars, cfq_vars])
# 区分效度:CFQ与其他无关构念的关系
# 假设有社会赞许性量表(Marlowe-Crowne)
irrelevant_vars = ['Social_Desirability']
corr_irrelevant = df_full[cfq_vars + irrelevant_vars].corr()
print("\nCFQ与无关构念的相关(应接近0):")
print(corr_irrelevant.loc[irrelevant_vars, cfq_vars])
第五部分:统计建模技巧
5.1 描述性统计与可视化
# 完整描述性统计
desc_stats = df_winsorized.describe()
print(desc_stats)
# 绘制得分分布
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
sns.histplot(df_winsorized['CFQ_Total'], kde=True, bins=20)
plt.title('CFQ总分分布')
plt.xlabel('总分')
plt.ylabel('频数')
plt.subplot(1, 2, 2)
sns.boxplot(y=df_winsorized['CFQ_Total'])
plt.title('CFQ总分箱线图')
plt.ylabel('总分')
plt.tight_layout()
plt.show()
# 条目得分分布
plt.figure(figsize=(15, 10))
for i, col in enumerate(df_winsorized.columns[:7], 1):
plt.subplot(2, 4, i)
sns.countplot(x=df_winsorized[col])
plt.title(f'条目 {col}')
plt.xlabel('得分')
plt.ylabel('频数')
plt.tight_layout()
plt.show()
5.2 组间差异分析
# 独立样本t检验(性别差异)
if 'Gender' in df_full.columns:
male = df_full[df_full['Gender'] == 'Male']['CFQ_Total']
female = df_full[df_full['Gender'] == 'Female']['CFQ_Total']
t_stat, p_val = stats.ttest_ind(male, female)
print(f"性别差异: t({len(male)+len(female)-2}) = {t_stat:.3f}, p = {p_val:.4f}")
# 效应量Cohen's d
pooled_std = np.sqrt(((len(male)-1)*male.var() + (len(female)-1)*female.var()) /
(len(male)+len(female)-2))
d = (male.mean() - female.mean()) / pooled_std
print(f"效应量 d = {d:.3f}")
# 单因素方差分析(年龄组)
if 'Age_Group' in df_full.columns:
groups = [group['CFQ_Total'].values for name, group in df_full.groupby('Age_Group')]
f_stat, p_val = stats.f_oneway(*groups)
print(f"年龄组差异: F = {f_stat:.3f}, p = {p_val:.4f}")
# 事后检验(Tukey HSD)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
tukey = pairwise_tukeyhsd(df_full['CFQ_Total'], df_full['Age_Group'])
print(tukey)
5.3 回归分析预测模型
# 线性回归:预测CFQ得分
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 准备特征矩阵(假设包含人口学变量和预测变量)
features = ['Age', 'Education', 'Anxiety', 'Depression', 'Values']
X = df_full[features]
y = df_full['CFQ_Total']
# 处理分类变量(如有)
X = pd.get_dummies(X, drop_first=True)
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 拟合模型
lr = LinearRegression()
lr.fit(X_train, y_train)
# 预测与评估
y_pred = lr.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"回归模型性能:")
print(f"均方误差 (MSE): {mse:.3f}")
print(f"R²: {r2:.3f}")
# 查看系数
coef_df = pd.DataFrame({
'变量': X.columns,
'系数': lr.coef_,
'绝对值': np.abs(lr.coef_)
}).sort_values('绝对值', ascending=False)
print("\n回归系数(按重要性排序):")
print(coef_df)
# 使用statsmodels获取详细统计信息
import statsmodels.api as sm
X_sm = sm.add_constant(X_train)
model_sm = sm.OLS(y_train, X_sm).fit()
print(model_sm.summary())
5.4 中介与调节效应分析
# 中介模型:认知融合在ACT核心过程与心理健康间的中介作用
# 使用semopy进行结构方程建模
model_mediation = """
# 测量模型
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
Anxiety =~ Anxiety1 + Anxiety2 + Anxiety3
Depression =~ Depression1 + Depression2 + Depression3
Acceptance =~ AAQ1 + AAQ2 + AAQ3
# 结构模型
CFQ ~ Acceptance
Anxiety ~ CFQ + Acceptance
Depression ~ CFQ + Acceptance
# 间接效应
Acceptance_CFQ_Anx := Acceptance -> CFQ -> Anxiety
Acceptance_CFQ_Dep := Acceptance -> CFQ -> Depression
"""
mod_med = sem.Model(model_mediation)
mod_med.fit(df_full)
print(mod_med.summary())
# Bootstrap检验间接效应
# semopy支持bootstrap,但需要额外配置
# 替代方案:使用process宏或手动bootstrap
# 调节效应:性别调节CFQ与抑郁的关系
model_moderation = """
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
Depression =~ Depression1 + Depression2 + Depression3
Gender =~ 1*Gender_Male # 二分变量
# 交互项(需要预先创建)
CFQ_Gender ~ CFQ * Gender
Depression ~ CFQ + Gender + CFQ_Gender
"""
5.5 潜在类别分析(LCA)
识别认知融合的亚群体:
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler
# 使用CFQ条目进行潜在类别分析
cfq_items = df_winsorized.columns[:7]
X_lca = df_winsorized[cfq_items]
# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_lca)
# 尝试不同类别数
bic_scores = []
aic_scores = []
for n in range(2, 6):
gmm = GaussianMixture(n_components=n, random_state=42)
gmm.fit(X_scaled)
bic_scores.append(gmm.bic(X_scaled))
aic_scores.append(gmm.aic(X_scaled))
# 绘制信息准则
plt.figure(figsize=(8, 5))
plt.plot(range(2, 6), bic_scores, 'o-', label='BIC')
plt.plot(range(2, 6), aic_scores, 'o-', label='AIC')
plt.xlabel('类别数')
plt.ylabel('信息准则')
plt.title('潜在类别分析:选择最优类别数')
plt.legend()
plt.show()
# 拟合最优模型(假设3类最优)
optimal_n = 3
gmm_optimal = GaussianMixture(n_components=optimal_n, random_state=42)
gmm_optimal.fit(X_scaled)
class_labels = gmm_optimal.predict(X_scaled)
# 分析各类别特征
df_lca = df_winsorized.copy()
df_lca['Class'] = class_labels
print("各类别样本量:")
print(df_lca['Class'].value_counts())
print("\n各类别CFQ总分均值:")
print(df_lca.groupby('Class')['CFQ_Total'].mean())
print("\n各类别在各条目上的特征:")
print(df_lca.groupby('Class')[cfq_items].mean())
5.6 纵向数据分析(如果有重复测量)
# 重复测量ANOVA或混合效应模型
# 假设数据格式:每个被试有时间1、时间2、时间3的CFQ得分
# 使用混合效应模型(推荐)
import statsmodels.formula.api as smf
# 准备长格式数据
# df_long = pd.melt(df_wide, id_vars=['SubjectID'], value_vars=['CFQ_T1', 'CFQ_T2', 'CFQ_T3'],
# var_name='Time', value_name='CFQ')
# 混合效应模型
# model = smf.mixedlm("CFQ ~ Time + Group", df_long, groups=df_long["SubjectID"])
# result = model.fit()
# print(result.summary())
# 如果是干预研究,可以比较组间变化
# model = smf.mixedlm("CFQ ~ Time * Group", df_long, groups=df_long["SubjectID"])
第六部分:高级分析技巧与注意事项
6.1 处理非正态分布数据
# 如果数据严重偏态,考虑非参数方法
# Mann-Whitney U检验(替代t检验)
from scipy.stats import mannwhitneyu
# 假设比较高低分组
high_scores = df_full.loc[df_full['CFQ_Total'] > df_full['CFQ_Total'].median(), 'CFQ_Total']
low_scores = df_full.loc[df_full['CFQ_Total'] <= df_full['CRQ_Total'].median(), 'CFQ_Total']
u_stat, p_val = mannwhitneyu(high_scores, low_scores)
print(f"Mann-Whitney U检验: U = {u_stat}, p = {p_val:.4f}")
# Spearman相关(替代Pearson相关)
corr_spearman = df_full[cfq_vars + criteria_vars].corr(method='spearman')
print("Spearman相关矩阵:")
print(corr_s1
6.2 共同方法偏差检验
# Harman单因子检验
from factor_analyzer import FactorAnalyzer
# 将所有变量(包括CFQ和效标)放入EFA
all_vars = cfq_vars + criteria_vars
fa_harman = FactorAnalyzer(n_factors=1, rotation=None)
fa_harman.fit(df_full[all_vars])
# 查看第一个因子解释的方差比例
ev, _ = fa_harman.get_eigenvalues()
first_factor_variance = ev[0] / sum(ev)
print(f"第一个因子解释的方差比例: {first_factor_variance:.3f}")
# 如果>40%,可能存在共同方法偏差
if first_factor_variance > 0.4:
print("警告:可能存在共同方法偏差")
else:
print("共同方法偏差在可接受范围内")
# 更严格的方法:控制未测量的潜在方法因子(ULMC)
# 需要使用CFA,比较包含和不包含方法因子的模型
6.3 多组比较(测量不变性)
# 检验问卷在不同群体(如性别、文化)中的测量不变性
# 需要使用CFA多组分析
# 1. 形态不变性(Configural Invariance)
# 2. 弱不变性(Metric Invariance)
# 3. 强不变性(Scalar Invariance)
# 4. 严格不变性(Strict Invariance)
# 使用semopy的多组分析功能
# model = """
# CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
# """
# 分组拟合
# groups = ['Male', 'Female']
# for group in groups:
# group_data = df_full[df_full['Gender'] == group]
# mod = sem.Model(model)
# mod.fit(group_data)
# 比较模型差异(ΔCFI < 0.01 表示不变性成立)
6.4 敏感性分析
# 检验分析结果的稳健性
# 1. 使用不同缺失值处理方法比较结果
methods = ['complete', 'mean', 'median', 'knn']
results = {}
for method in methods:
if method == 'complete':
df_method = df.dropna()
elif method == 'mean':
df_method = df.fillna(df.mean())
elif method == 'median':
df_method = df.fillna(df.median())
elif method == 'knn':
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
df_method = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
# 计算Alpha
alpha = pg.cronbach_alpha(data=df_method.iloc[:, :7])[0]
results[method] = alpha
print("不同缺失值处理方法的Alpha系数:")
for method, alpha in results.items():
print(f"{method}: {alpha:.3f}")
# 2. 使用不同异常值处理阈值
thresholds = [2.5, 3.0, 3.5]
for thresh in thresholds:
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > thresh).any(axis=1)
df_no_outliers = df_imputed[~outliers]
alpha = pg.cronbach_alpha(data=df_no_outliers.iloc[:, :7])[0]
print(f"Z阈值={thresh}时的Alpha: {alpha:.3f}")
第七部分:结果报告与解释
7.1 报告标准
根据APA和期刊要求,信效度报告应包括:
- 信度:Cronbach’s Alpha值、置信区间、条目-总分相关
- 效度:因子载荷、模型拟合指数(CFI, TLI, RMSEA, SRMR)
- 效标关联效度:与相关变量的相关系数
- 测量不变性:多组比较结果
7.2 结果解释示例
# 生成报告摘要
def generate_report(df, cfq_vars):
report = {}
# 信度
alpha = pg.cronbach_alpha(data=df[cfq_vars])[0]
report['Cronbach_alpha'] = alpha
# 描述统计
report['Mean'] = df[cfq_vars].mean().mean()
report['SD'] = df[cfq_vars].std().mean()
# 效度(假设已进行CFA)
# report['CFI'] = 0.95
# report['RMSEA'] = 0.04
return report
report = generate_report(df_winsorized, cfq_vars)
print("分析结果摘要:")
for key, value in report.items():
print(f"{key}: {value:.3f}")
7.3 可视化结果
# 创建发表质量的图表
plt.style.use('seaborn-v0_8-whitegrid')
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. 条目载荷图
loadings = fa.loadings_
axes[0, 0].bar(range(len(loadings)), loadings[:, 0])
axes[0, 0].set_title('因子载荷')
axes[0, 0].set_ylabel('载荷值')
axes[0, 0].set_xticks(range(len(loadings)))
axes[0, 0].set_xticklabels(cfq_vars, rotation=45)
# 2. 效标相关热图
corr_matrix = df_full[cfq_vars + criteria_vars].corr()
sns.heatmap(corr_matrix.loc[criteria_vars, cfq_vars], annot=True, cmap='coolwarm',
center=0, ax=axes[0, 1])
axes[0, 1].set_title('效标相关')
# 3. 组间差异
if 'Gender' in df_full.columns:
sns.boxplot(data=df_full, x='Gender', y='CFQ_Total', ax=axes[1, 0])
axes[1, 0].set_title('性别差异')
# 4. 回归系数
coef_df = pd.DataFrame({'变量': X.columns, '系数': lr.coef_})
sns.barplot(data=coef_df, x='系数', y='变量', ax=axes[1, 1])
axes[1, 1].set_title('回归系数')
plt.tight_layout()
plt.savefig('cognitive_fusion_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
第八部分:常见问题与解决方案
8.1 信度不达标
问题:Alpha < 0.7
解决方案:
- 检查反向计分是否正确
- 删除低相关条目(item-total correlation < 0.3)
- 增加样本量
- 考虑问卷是否适合当前人群
# 识别低相关条目
item_total_corr = []
for item in cfq_vars:
corr = pg.corr(df_winsorized[item], df_winsorized['CFQ_Total'])
item_total_corr.append(corr['r'].values[0])
low_corr_items = [item for i, item in enumerate(cfq_vars) if item_total_corr[i] < 0.3]
print("低相关条目(r < 0.3):", low_corr_items)
8.2 CFA模型拟合不佳
问题:CFI < 0.9 或 RMSEA > 0.08
解决方案:
- 检查因子载荷是否<0.4
- 考虑添加残差相关
- 检查数据是否有多维结构
- 考虑使用修正指数(Modification Indices)
# 识别低载荷条目
low_loadings = [item for i, item in enumerate(cfq_vars) if abs(loadings[i, 0]) < 0.4]
print("低载荷条目(<0.4):", low_loadings)
8.3 样本量不足
问题:样本量 < 100
解决方案:
- 使用Bootstrap重抽样
- 采用贝叶斯方法
- 报告置信区间而非仅p值
- 考虑使用简版问卷
8.4 数据非正态
问题:Shapiro-Wilk检验p < 0.05
解决方案:
- 使用非参数检验
- 数据转换(如对数、平方根)
- 使用稳健标准误
- 增加样本量(中心极限定理)
第九部分:完整分析流程示例
从原始数据到最终报告
# 完整流程封装
def analyze_cognitive_fusion_questionnaire(df, cfq_items, demographics=None):
"""
完整分析CFQ问卷的函数
参数:
df: 原始数据DataFrame
cfq_items: CFQ条目名称列表
demographics: 人口学变量列表
"""
print("="*60)
print("认知融合问卷完整分析流程")
print("="*60)
# 1. 数据清洗
print("\n1. 数据清洗...")
# 缺失值处理
missing_rate = df[cfq_items].isnull().mean().mean()
print(f" 平均缺失率: {missing_rate:.2%}")
if missing_rate > 0.05:
print(" → 使用多重插补")
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imputer = IterativeImputer(random_state=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df[cfq_items]), columns=cfq_items)
else:
df_imputed = df[cfq_items].dropna()
# 异常值检测
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > 3).any(axis=1)
print(f" 异常值样本: {outliers.sum()} 个")
df_clean = df_imputed[~outliers]
# 2. 信度分析
print("\n2. 信度分析...")
alpha = pg.cronbach_alpha(data=df_clean)[0]
print(f" Cronbach's Alpha: {alpha:.3f}")
if alpha < 0.7:
print(" → 信度不达标,检查数据质量")
else:
print(" → 信度良好")
# 3. 效度分析(EFA)
print("\n3. 效度分析(探索性因子分析)...")
from factor_analyzer import FactorAnalyzer
fa = FactorAnalyzer(n_factors=1, rotation=None)
fa.fit(df_clean)
loadings = fa.loadings_
print(" 因子载荷:")
for i, item in enumerate(cfq_items):
print(f" {item}: {loadings[i,0]:.3f}")
# 4. 描述性统计
print("\n4. 描述性统计...")
desc = df_clean.describe()
print(f" 总分均值: {df_clean.sum(axis=1).mean():.2f} (SD={df_clean.sum(axis=1).std():.2f})")
# 5. 效标效度(如果有效标数据)
if demographics:
print("\n5. 效标效度分析...")
# 这里需要实际的效标数据
print(" (需提供效标变量数据)")
# 6. 生成报告
report = {
'样本量': len(df_clean),
'Cronbach_alpha': alpha,
'因子载荷范围': (loadings.min(), loadings.max()),
'总分均值': df_clean.sum(axis=1).mean(),
'总分标准差': df_clean.sum(axis=1).std()
}
return report
# 使用示例
# report = analyze_cognitive_fusion_questionnaire(df, cfq_items=['CFQ1', 'CFQ2', 'CFQ3', 'CFQ4', 'CFQ5', 'CFQ6', 'CFQ7'])
# print("\n最终报告:")
# print(report)
第十部分:总结与最佳实践
关键要点总结
- 数据质量是基础:严格的清洗流程确保分析结果的可靠性
- 信度先行:没有良好的信度,效度无从谈起
- 理论驱动:所有分析都应基于认知融合的理论框架
- 方法透明:详细报告分析过程,便于他人重复和验证
- 结果稳健:通过敏感性分析检验结果的稳定性
最佳实践清单
- [ ] 样本量至少200(EFA)或100(CFA)
- [ ] 报告完整的信效度指标
- [ ] 检查测量不变性(多组比较)
- [ ] 考虑共同方法偏差
- [ ] 使用多种方法交叉验证结果
- [ ] 可视化结果便于理解
- [ ] 保存完整代码和随机种子以便复现
进一步学习资源
- 书籍:《心理测量学》、《结构方程模型》
- 软件:R的lavaan包、Mplus、JASP
- 文献:Gil-lucas et al. (2014) CFQ开发论文
- 在线课程:Coursera心理测量学课程
通过本指南的系统学习,研究者应能独立完成认知融合问卷的完整分析流程,从数据清洗到高级建模,确保研究的科学性和严谨性。记住,好的分析不仅需要技术技能,更需要对理论和方法的深入理解。# 认知融合问卷怎么分析 从理论到实践的完整指南 包括数据清洗信效度检验与统计建模技巧
引言:认知融合问卷分析的重要性
认知融合(Cognitive Fusion)是接纳与承诺疗法(ACT)中的核心概念,指个体将思想与现实混淆,过度认同内在体验的心理过程。认知融合问卷(如CFQ, Cognitive Fusion Questionnaire)是测量这一构念的常用工具。在心理学研究和临床实践中,对这类问卷进行科学分析至关重要,它直接影响研究结论的可靠性和干预效果的评估。本指南将从理论基础出发,系统阐述从数据清洗到高级统计建模的全流程分析方法,帮助研究者掌握严谨的分析技术。
第一部分:认知融合的理论基础与问卷设计
认知融合的概念框架
认知融合的概念源于关系框架理论(RFT),它描述了人类语言和认知的”衍生关系”特性如何导致心理困扰。当个体将语言等同于现实时,就会产生认知融合,例如将”我感到焦虑”等同于”我是一个焦虑的人”。理解这一理论背景对问卷分析至关重要,因为它决定了问卷应测量的核心维度和潜在的心理结构。
常用认知融合问卷介绍
目前最常用的是Gil-lucas等人开发的CFQ(Cognitive Fusion Questionnaire),包含7个条目,采用7点计分(1=非常不符合,7=非常符合)。例如条目1:”我的想法会让我感到情绪困扰”。其他变体包括简版CFQ-7和针对特定人群的改编版本。了解问卷的结构和计分方式是分析的前提。
1.1 问卷设计的理论依据
认知融合问卷的设计严格遵循ACT理论模型。每个条目都针对特定的认知融合表现:
- 思维内容融合(如”我必须控制我的想法”)
- 思维过程融合(如”如果我有负面想法,就意味着我是坏人”)
- 思维-情绪融合(如”我的想法让我感到痛苦”)
这种理论驱动的设计确保了问卷的内容效度,也为后续的因子分析提供了理论预期。
第二部分:数据清洗与预处理
数据收集与导入
在分析之前,首先需要规范地收集数据。假设我们使用Qualtrics或问卷星等平台收集了500份CFQ问卷数据,导出为CSV格式。使用Python的pandas库进行初步导入:
import pandas as pd
import numpy as np
# 导入数据
df = pd.read_csv('cognitive_fusion_data.csv')
# 查看数据基本信息
print(df.info())
print(df.head())
# 检查数据维度
print(f"数据集包含 {df.shape[0]} 个样本,{df.shape[1]} 个变量")
缺失值处理
缺失值是问卷数据常见问题。需要系统评估缺失模式:
# 计算每个变量的缺失比例
missing_ratio = df.isnull().mean() * 100
print("各变量缺失比例:")
print(missing_ratio)
# 可视化缺失模式
import missingno as msno
msno.matrix(df)
# 根据缺失机制选择处理方法
# 如果是完全随机缺失(MCAR),可以使用删除或均值插补
# 如果是随机缺失(MAR),建议使用多重插补
# 简单删除法(适用于缺失<5%)
df_clean = df.dropna()
# 均值插补(适用于小样本)
df_imputed = df.fillna(df.mean())
# 多重插补(推荐方法)
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imputer = IterativeImputer(random_state=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
异常值检测与处理
异常值可能影响统计结果,需要系统检测:
# 方法1:箱线图法检测异常值
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
sns.boxplot(data=df_imputed)
plt.title('CFQ各条目得分箱线图')
plt.show()
# 方法2:Z分数法(适用于正态分布)
from scipy import stats
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > 3).any(axis=1)
print(f"检测到 {outliers.sum()} 个异常值样本")
# 方法3:孤立森林算法(适用于多维数据)
from sklearn.ensemble import IsolationForest
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outlier_labels = iso_forest.fit_predict(df_imputed)
outlier_indices = np.where(outlier_labels == -1)[0]
print(f"孤立森林检测到 {len(outlier_indices)} 个异常值")
# 处理策略:根据理论判断是否删除或Winsorize
# Winsorize处理(将极端值替换为第5/95百分位数)
from scipy.stats.mstats import winsorize
df_winsorized = df_imputed.apply(lambda x: winsorize(x, limits=[0.05, 0.05]))
数据分布检验
检查数据是否符合参数检验的假设:
# 正态性检验(Shapiro-Wilk检验)
for col in df_winsorized.columns:
stat, p = stats.shapiro(df_winsorized[col])
print(f"{col}: W={stat:.3f}, p={p:.4f}")
if p < 0.05:
print(f" → 拒绝正态性假设")
else:
print(f" → 接受正态性假设")
# 可视化分布
plt.figure(figsize=(12, 8))
for i, col in enumerate(df_winsorized.columns, 1):
plt.subplot(2, 4, i)
sns.histplot(df_winsorized[col], kde=True)
plt.title(col)
plt.tight_layout()
plt.show()
数据标准化与反向计分
检查问卷是否有反向计分条目并进行转换:
# 假设CFQ的第2、4、6条目是反向计分(实际需根据问卷说明)
reverse_items = ['CFQ2', 'CFQ4', 'CFQ6']
for item in reverse_items:
if item in df_winsorized.columns:
# 反向计分:7点计分转换为1-7的反向
df_winsorized[item] = 8 - df_winsorized[item]
print(f"已反向计分:{item}")
# 计算总分(如果需要)
df_winsorized['CFQ_Total'] = df_winsorized.sum(axis=1)
print("CFQ总分描述统计:")
print(df_winsorized['CFQ_Total'].describe())
第三部分:信度分析
3.1 内部一致性信度
内部一致性反映问卷各条目测量同一构念的程度:
import pingouin as pg
# 计算Cronbach's Alpha
alpha_result = pg.cronbach_alpha(data=df_winsorized.iloc[:, :7])
print(f"Cronbach's Alpha系数: {alpha_result[0]:.3f}")
print(f"95%置信区间: ({alpha_result[1][0]:.3f}, {alpha_result[1][1]:.3f})")
# 逐项删除后的Alpha值
for item in df_winsorized.columns[:7]:
alpha_if_deleted = pg.cronbach_alpha(data=df_winsorized.drop(columns=[item]))
print(f"删除 {item} 后的Alpha: {alpha_if_deleted[0]:.3f}")
# 分半信度(如果问卷条目较多)
# 将条目分为奇偶两部分
odd_items = df_winsorized.columns[0::2] # 奇数索引
even_items = df_winsorized.columns[1::2] # 偶数索引
odd_sum = df_winsorized[odd_items].sum(axis=1)
even_sum = df_winsorized[even_items].sum(axis=1)
# Spearman-Brown校正
split_half = pg.corr(odd_sum, even_sum)
r = split_half['r'].values[0]
spearman_brown = (2 * r) / (1 + r)
print(f"分半信度系数(Spearman-Brown校正): {spearman_brown:.3f}")
3.2 重测信度
如果有纵向数据,可以计算重测信度:
# 假设有时间1和时间2的数据
# df_long = pd.read_csv('longitudinal_data.csv')
# 计算皮尔逊相关系数
# retest_corr = pg.corr(df_long['CFQ_T1'], df_long['CFQ_T2'])
# print(f"重测信度: {retest_corr['r'].values[0]:.3f}")
# 如果数据是配对样本,可以使用ICC
# from sklearn.metrics import cohen_kappa_score
# 或使用pingouin的ICC函数
# icc = pg.intraclass_corr(data=df_long, targets='subject', raters='time', ratings='CFQ_score')
3.3 信度结果解读标准
- Cronbach’s Alpha:>0.7 可接受,>0.8 良好,>0.9 优秀
- 分半信度:>0.7 可接受
- 重测信度:>0.7 表明时间稳定性良好
如果信度不达标,需要检查:
- 条目是否测量同一构念
- 是否存在反向计分错误
- 样本量是否足够
- 被试是否理解条目含义
第四部分:效度分析
4.1 结构效度:探索性因子分析(EFA)
EFA用于探索问卷的潜在结构:
from factor_analyzer import FactorAnalyzer
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
from factor_analyzer.factor_analyzer import calculate_kmo
# 1. 适用性检验
# Bartlett球形检验
chi_square_value, p_value = calculate_bartlett_sphericity(df_winsorized.iloc[:, :7])
print(f"Bartlett球形检验: χ² = {chi_square_value:.2f}, p = {p_value:.4f}")
# KMO检验
kmo_all, kmo_model = calculate_kmo(df_winsorized.iloc[:, :7])
print(f"KMO值: {kmo_model:.3f}")
print("KMO标准: >0.6 可接受,>0.8 良好")
# 2. 因子提取
fa = FactorAnalyzer(n_factors=1, rotation=None) # 理论预期是单因子结构
fa.fit(df_winsorized.iloc[:, :7])
# 查看因子载荷
loadings = fa.loadings_
print("因子载荷矩阵:")
for i, item in enumerate(df_winsorized.columns[:7]):
print(f"{item}: {loadings[i, 0]:.3f}")
# 查看公因子方差
communalities = fa.get_communalities()
print("\n公因子方差:")
for i, item in enumerate(df_winsorized.columns[:7]):
print(f"{item}: {communalities[i]:.3f}")
# 3. 碎石图确定因子数量
fa = FactorAnalyzer(n_factors=7, rotation=None)
fa.fit(df_winsorized.iloc[:, :7])
ev, v = fa.get_eigenvalues()
plt.figure(figsize=(8, 6))
plt.plot(range(1, 8), ev, 'o-')
plt.axhline(y=1, color='r', linestyle='--')
plt.title('碎石图')
plt.xlabel('因子数量')
plt.ylabel('特征值')
plt.show()
# 4. 验证性因子分析(CFA)
import semopy as sem
# 定义模型(单因子模型)
model_spec = """
# 测量模型
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
"""
# 拟合模型
mod = sem.Model(model_spec)
mod.fit(df_winsorized.iloc[:, :7])
print(mod.summary())
# 模型拟合指标
# CFI > 0.9, TLI > 0.9, RMSEA < 0.08, SRMR < 0.08
4.2 效标效度
评估问卷与其他变量的关系:
# 假设我们有焦虑量表(Anxiety)、抑郁量表(Depression)和生活满意度(LifeSat)
# 计算相关矩阵
criteria_vars = ['Anxiety', 'Depression', 'LifeSat']
cfq_vars = df_winsorized.columns[:7]
# 合并数据(假设df_full包含所有变量)
# 相关分析
corr_matrix = df_full[cfq_vars + criteria_vars].corr()
print("CFQ与效标变量的相关矩阵:")
print(corr_matrix.loc[criteria_vars, cfq_vars])
# 绘制热图
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('CFQ与效标变量相关矩阵')
plt.show()
# 差异检验:高分组 vs 低分组
# 创建高分组(前27%)和低分组(后27%)
cfq_total = df_full[cfq_vars].sum(axis=1)
high_group = df_full[cfq_total > np.percentile(cfq_total, 73)]
low_group = df_full[cfq_total < np.percentile(cfq_total, 27)]
# 比较两组在效标变量上的差异
from scipy.stats import ttest_ind
for var in criteria_vars:
t_stat, p_val = ttest_ind(high_group[var], low_group[var])
print(f"{var}: t = {t_stat:.3f}, p = {p_val:.4f}")
4.3 聚合效度与区分效度
# 聚合效度:CFQ与ACT其他核心过程的关系
# 假设我们有接纳量表(AAQ)、正念(FFMQ)等
act_vars = ['AAQ', 'FFMQ', 'Values']
corr_matrix_act = df_full[cfq_vars + act_vars].corr()
print("CFQ与ACT核心过程的相关:")
print(corr_matrix_act.loc[act_vars, cfq_vars])
# 区分效度:CFQ与其他无关构念的关系
# 假设有社会赞许性量表(Marlowe-Crowne)
irrelevant_vars = ['Social_Desirability']
corr_irrelevant = df_full[cfq_vars + irrelevant_vars].corr()
print("\nCFQ与无关构念的相关(应接近0):")
print(corr_irrelevant.loc[irrelevant_vars, cfq_vars])
第五部分:统计建模技巧
5.1 描述性统计与可视化
# 完整描述性统计
desc_stats = df_winsorized.describe()
print(desc_stats)
# 绘制得分分布
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
sns.histplot(df_winsorized['CFQ_Total'], kde=True, bins=20)
plt.title('CFQ总分分布')
plt.xlabel('总分')
plt.ylabel('频数')
plt.subplot(1, 2, 2)
sns.boxplot(y=df_winsorized['CFQ_Total'])
plt.title('CFQ总分箱线图')
plt.ylabel('总分')
plt.tight_layout()
plt.show()
# 条目得分分布
plt.figure(figsize=(15, 10))
for i, col in enumerate(df_winsorized.columns[:7], 1):
plt.subplot(2, 4, i)
sns.countplot(x=df_winsorized[col])
plt.title(f'条目 {col}')
plt.xlabel('得分')
plt.ylabel('频数')
plt.tight_layout()
plt.show()
5.2 组间差异分析
# 独立样本t检验(性别差异)
if 'Gender' in df_full.columns:
male = df_full[df_full['Gender'] == 'Male']['CFQ_Total']
female = df_full[df_full['Gender'] == 'Female']['CFQ_Total']
t_stat, p_val = stats.ttest_ind(male, female)
print(f"性别差异: t({len(male)+len(female)-2}) = {t_stat:.3f}, p = {p_val:.4f}")
# 效应量Cohen's d
pooled_std = np.sqrt(((len(male)-1)*male.var() + (len(female)-1)*female.var()) /
(len(male)+len(female)-2))
d = (male.mean() - female.mean()) / pooled_std
print(f"效应量 d = {d:.3f}")
# 单因素方差分析(年龄组)
if 'Age_Group' in df_full.columns:
groups = [group['CFQ_Total'].values for name, group in df_full.groupby('Age_Group')]
f_stat, p_val = stats.f_oneway(*groups)
print(f"年龄组差异: F = {f_stat:.3f}, p = {p_val:.4f}")
# 事后检验(Tukey HSD)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
tukey = pairwise_tukeyhsd(df_full['CFQ_Total'], df_full['Age_Group'])
print(tukey)
5.3 回归分析预测模型
# 线性回归:预测CFQ得分
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 准备特征矩阵(假设包含人口学变量和预测变量)
features = ['Age', 'Education', 'Anxiety', 'Depression', 'Values']
X = df_full[features]
y = df_full['CFQ_Total']
# 处理分类变量(如有)
X = pd.get_dummies(X, drop_first=True)
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 拟合模型
lr = LinearRegression()
lr.fit(X_train, y_train)
# 预测与评估
y_pred = lr.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"回归模型性能:")
print(f"均方误差 (MSE): {mse:.3f}")
print(f"R²: {r2:.3f}")
# 查看系数
coef_df = pd.DataFrame({
'变量': X.columns,
'系数': lr.coef_,
'绝对值': np.abs(lr.coef_)
}).sort_values('绝对值', ascending=False)
print("\n回归系数(按重要性排序):")
print(coef_df)
# 使用statsmodels获取详细统计信息
import statsmodels.api as sm
X_sm = sm.add_constant(X_train)
model_sm = sm.OLS(y_train, X_sm).fit()
print(model_sm.summary())
5.4 中介与调节效应分析
# 中介模型:认知融合在ACT核心过程与心理健康间的中介作用
# 使用semopy进行结构方程建模
model_mediation = """
# 测量模型
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
Anxiety =~ Anxiety1 + Anxiety2 + Anxiety3
Depression =~ Depression1 + Depression2 + Depression3
Acceptance =~ AAQ1 + AAQ2 + AAQ3
# 结构模型
CFQ ~ Acceptance
Anxiety ~ CFQ + Acceptance
Depression ~ CFQ + Acceptance
# 间接效应
Acceptance_CFQ_Anx := Acceptance -> CFQ -> Anxiety
Acceptance_CFQ_Dep := Acceptance -> CFQ -> Depression
"""
mod_med = sem.Model(model_mediation)
mod_med.fit(df_full)
print(mod_med.summary())
# Bootstrap检验间接效应
# semopy支持bootstrap,但需要额外配置
# 替代方案:使用process宏或手动bootstrap
# 调节效应:性别调节CFQ与抑郁的关系
model_moderation = """
CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
Depression =~ Depression1 + Depression2 + Depression3
Gender =~ 1*Gender_Male # 二分变量
# 交互项(需要预先创建)
CFQ_Gender ~ CFQ * Gender
Depression ~ CFQ + Gender + CFQ_Gender
"""
5.5 潜在类别分析(LCA)
识别认知融合的亚群体:
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler
# 使用CFQ条目进行潜在类别分析
cfq_items = df_winsorized.columns[:7]
X_lca = df_winsorized[cfq_items]
# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_lca)
# 尝试不同类别数
bic_scores = []
aic_scores = []
for n in range(2, 6):
gmm = GaussianMixture(n_components=n, random_state=42)
gmm.fit(X_scaled)
bic_scores.append(gmm.bic(X_scaled))
aic_scores.append(gmm.aic(X_scaled))
# 绘制信息准则
plt.figure(figsize=(8, 5))
plt.plot(range(2, 6), bic_scores, 'o-', label='BIC')
plt.plot(range(2, 6), aic_scores, 'o-', label='AIC')
plt.xlabel('类别数')
plt.ylabel('信息准则')
plt.title('潜在类别分析:选择最优类别数')
plt.legend()
plt.show()
# 拟合最优模型(假设3类最优)
optimal_n = 3
gmm_optimal = GaussianMixture(n_components=optimal_n, random_state=42)
gmm_optimal.fit(X_scaled)
class_labels = gmm_optimal.predict(X_scaled)
# 分析各类别特征
df_lca = df_winsorized.copy()
df_lca['Class'] = class_labels
print("各类别样本量:")
print(df_lca['Class'].value_counts())
print("\n各类别CFQ总分均值:")
print(df_lca.groupby('Class')['CFQ_Total'].mean())
print("\n各类别在各条目上的特征:")
print(df_lca.groupby('Class')[cfq_items].mean())
5.6 纵向数据分析(如果有重复测量)
# 重复测量ANOVA或混合效应模型
# 假设数据格式:每个被试有时间1、时间2、时间3的CFQ得分
# 使用混合效应模型(推荐)
import statsmodels.formula.api as smf
# 准备长格式数据
# df_long = pd.melt(df_wide, id_vars=['SubjectID'], value_vars=['CFQ_T1', 'CFQ_T2', 'CFQ_T3'],
# var_name='Time', value_name='CFQ')
# 混合效应模型
# model = smf.mixedlm("CFQ ~ Time + Group", df_long, groups=df_long["SubjectID"])
# result = model.fit()
# print(result.summary())
# 如果是干预研究,可以比较组间变化
# model = smf.mixedlm("CFQ ~ Time * Group", df_long, groups=df_long["SubjectID"])
第六部分:高级分析技巧与注意事项
6.1 处理非正态分布数据
# 如果数据严重偏态,考虑非参数方法
# Mann-Whitney U检验(替代t检验)
from scipy.stats import mannwhitneyu
# 假设比较高低分组
high_scores = df_full.loc[df_full['CFQ_Total'] > df_full['CFQ_Total'].median(), 'CFQ_Total']
low_scores = df_full.loc[df_full['CFQ_Total'] <= df_full['CFQ_Total'].median(), 'CFQ_Total']
u_stat, p_val = mannwhitneyu(high_scores, low_scores)
print(f"Mann-Whitney U检验: U = {u_stat}, p = {p_val:.4f}")
# Spearman相关(替代Pearson相关)
corr_spearman = df_full[cfq_vars + criteria_vars].corr(method='spearman')
print("Spearman相关矩阵:")
print(corr_spearman)
6.2 共同方法偏差检验
# Harman单因子检验
from factor_analyzer import FactorAnalyzer
# 将所有变量(包括CFQ和效标)放入EFA
all_vars = cfq_vars + criteria_vars
fa_harman = FactorAnalyzer(n_factors=1, rotation=None)
fa_harman.fit(df_full[all_vars])
# 查看第一个因子解释的方差比例
ev, _ = fa_harman.get_eigenvalues()
first_factor_variance = ev[0] / sum(ev)
print(f"第一个因子解释的方差比例: {first_factor_variance:.3f}")
# 如果>40%,可能存在共同方法偏差
if first_factor_variance > 0.4:
print("警告:可能存在共同方法偏差")
else:
print("共同方法偏差在可接受范围内")
# 更严格的方法:控制未测量的潜在方法因子(ULMC)
# 需要使用CFA,比较包含和不包含方法因子的模型
6.3 多组比较(测量不变性)
# 检验问卷在不同群体(如性别、文化)中的测量不变性
# 需要使用CFA多组分析
# 1. 形态不变性(Configural Invariance)
# 2. 弱不变性(Metric Invariance)
# 3. 强不变性(Scalar Invariance)
# 4. 严格不变性(Strict Invariance)
# 使用semopy的多组分析功能
# model = """
# CFQ =~ CFQ1 + CFQ2 + CFQ3 + CFQ4 + CFQ5 + CFQ6 + CFQ7
# """
# 分组拟合
# groups = ['Male', 'Female']
# for group in groups:
# group_data = df_full[df_full['Gender'] == group]
# mod = sem.Model(model)
# mod.fit(group_data)
# 比较模型差异(ΔCFI < 0.01 表示不变性成立)
6.4 敏感性分析
# 检验分析结果的稳健性
# 1. 使用不同缺失值处理方法比较结果
methods = ['complete', 'mean', 'median', 'knn']
results = {}
for method in methods:
if method == 'complete':
df_method = df.dropna()
elif method == 'mean':
df_method = df.fillna(df.mean())
elif method == 'median':
df_method = df.fillna(df.median())
elif method == 'knn':
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
df_method = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
# 计算Alpha
alpha = pg.cronbach_alpha(data=df_method.iloc[:, :7])[0]
results[method] = alpha
print("不同缺失值处理方法的Alpha系数:")
for method, alpha in results.items():
print(f"{method}: {alpha:.3f}")
# 2. 使用不同异常值处理阈值
thresholds = [2.5, 3.0, 3.5]
for thresh in thresholds:
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > thresh).any(axis=1)
df_no_outliers = df_imputed[~outliers]
alpha = pg.cronbach_alpha(data=df_no_outliers.iloc[:, :7])[0]
print(f"Z阈值={thresh}时的Alpha: {alpha:.3f}")
第七部分:结果报告与解释
7.1 报告标准
根据APA和期刊要求,信效度报告应包括:
- 信度:Cronbach’s Alpha值、置信区间、条目-总分相关
- 效度:因子载荷、模型拟合指数(CFI, TLI, RMSEA, SRMR)
- 效标关联效度:与相关变量的相关系数
- 测量不变性:多组比较结果
7.2 结果解释示例
# 生成报告摘要
def generate_report(df, cfq_vars):
report = {}
# 信度
alpha = pg.cronbach_alpha(data=df[cfq_vars])[0]
report['Cronbach_alpha'] = alpha
# 描述统计
report['Mean'] = df[cfq_vars].mean().mean()
report['SD'] = df[cfq_vars].std().mean()
# 效度(假设已进行CFA)
# report['CFI'] = 0.95
# report['RMSEA'] = 0.04
return report
report = generate_report(df_winsorized, cfq_vars)
print("分析结果摘要:")
for key, value in report.items():
print(f"{key}: {value:.3f}")
7.3 可视化结果
# 创建发表质量的图表
plt.style.use('seaborn-v0_8-whitegrid')
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. 条目载荷图
loadings = fa.loadings_
axes[0, 0].bar(range(len(loadings)), loadings[:, 0])
axes[0, 0].set_title('因子载荷')
axes[0, 0].set_ylabel('载荷值')
axes[0, 0].set_xticks(range(len(loadings)))
axes[0, 0].set_xticklabels(cfq_vars, rotation=45)
# 2. 效标相关热图
corr_matrix = df_full[cfq_vars + criteria_vars].corr()
sns.heatmap(corr_matrix.loc[criteria_vars, cfq_vars], annot=True, cmap='coolwarm',
center=0, ax=axes[0, 1])
axes[0, 1].set_title('效标相关')
# 3. 组间差异
if 'Gender' in df_full.columns:
sns.boxplot(data=df_full, x='Gender', y='CFQ_Total', ax=axes[1, 0])
axes[1, 0].set_title('性别差异')
# 4. 回归系数
coef_df = pd.DataFrame({'变量': X.columns, '系数': lr.coef_})
sns.barplot(data=coef_df, x='系数', y='变量', ax=axes[1, 1])
axes[1, 1].set_title('回归系数')
plt.tight_layout()
plt.savefig('cognitive_fusion_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
第八部分:常见问题与解决方案
8.1 信度不达标
问题:Alpha < 0.7
解决方案:
- 检查反向计分是否正确
- 删除低相关条目(item-total correlation < 0.3)
- 增加样本量
- 考虑问卷是否适合当前人群
# 识别低相关条目
item_total_corr = []
for item in cfq_vars:
corr = pg.corr(df_winsorized[item], df_winsorized['CFQ_Total'])
item_total_corr.append(corr['r'].values[0])
low_corr_items = [item for i, item in enumerate(cfq_vars) if item_total_corr[i] < 0.3]
print("低相关条目(r < 0.3):", low_corr_items)
8.2 CFA模型拟合不佳
问题:CFI < 0.9 或 RMSEA > 0.08
解决方案:
- 检查因子载荷是否<0.4
- 考虑添加残差相关
- 检查数据是否有多维结构
- 考虑使用修正指数(Modification Indices)
# 识别低载荷条目
low_loadings = [item for i, item in enumerate(cfq_vars) if abs(loadings[i, 0]) < 0.4]
print("低载荷条目(<0.4):", low_loadings)
8.3 样本量不足
问题:样本量 < 100
解决方案:
- 使用Bootstrap重抽样
- 采用贝叶斯方法
- 报告置信区间而非仅p值
- 考虑使用简版问卷
8.4 数据非正态
问题:Shapiro-Wilk检验p < 0.05
解决方案:
- 使用非参数检验
- 数据转换(如对数、平方根)
- 使用稳健标准误
- 增加样本量(中心极限定理)
第九部分:完整分析流程示例
从原始数据到最终报告
# 完整流程封装
def analyze_cognitive_fusion_questionnaire(df, cfq_items, demographics=None):
"""
完整分析CFQ问卷的函数
参数:
df: 原始数据DataFrame
cfq_items: CFQ条目名称列表
demographics: 人口学变量列表
"""
print("="*60)
print("认知融合问卷完整分析流程")
print("="*60)
# 1. 数据清洗
print("\n1. 数据清洗...")
# 缺失值处理
missing_rate = df[cfq_items].isnull().mean().mean()
print(f" 平均缺失率: {missing_rate:.2%}")
if missing_rate > 0.05:
print(" → 使用多重插补")
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imputer = IterativeImputer(random_state=0)
df_imputed = pd.DataFrame(imputer.fit_transform(df[cfq_items]), columns=cfq_items)
else:
df_imputed = df[cfq_items].dropna()
# 异常值检测
z_scores = np.abs(stats.zscore(df_imputed))
outliers = (z_scores > 3).any(axis=1)
print(f" 异常值样本: {outliers.sum()} 个")
df_clean = df_imputed[~outliers]
# 2. 信度分析
print("\n2. 信度分析...")
alpha = pg.cronbach_alpha(data=df_clean)[0]
print(f" Cronbach's Alpha: {alpha:.3f}")
if alpha < 0.7:
print(" → 信度不达标,检查数据质量")
else:
print(" → 信度良好")
# 3. 效度分析(EFA)
print("\n3. 效度分析(探索性因子分析)...")
from factor_analyzer import FactorAnalyzer
fa = FactorAnalyzer(n_factors=1, rotation=None)
fa.fit(df_clean)
loadings = fa.loadings_
print(" 因子载荷:")
for i, item in enumerate(cfq_items):
print(f" {item}: {loadings[i,0]:.3f}")
# 4. 描述性统计
print("\n4. 描述性统计...")
desc = df_clean.describe()
print(f" 总分均值: {df_clean.sum(axis=1).mean():.2f} (SD={df_clean.sum(axis=1).std():.2f})")
# 5. 效标效度(如果有效标数据)
if demographics:
print("\n5. 效标效度分析...")
# 这里需要实际的效标数据
print(" (需提供效标变量数据)")
# 6. 生成报告
report = {
'样本量': len(df_clean),
'Cronbach_alpha': alpha,
'因子载荷范围': (loadings.min(), loadings.max()),
'总分均值': df_clean.sum(axis=1).mean(),
'总分标准差': df_clean.sum(axis=1).std()
}
return report
# 使用示例
# report = analyze_cognitive_fusion_questionnaire(df, cfq_items=['CFQ1', 'CFQ2', 'CFQ3', 'CFQ4', 'CFQ5', 'CFQ6', 'CFQ7'])
# print("\n最终报告:")
# print(report)
第十部分:总结与最佳实践
关键要点总结
- 数据质量是基础:严格的清洗流程确保分析结果的可靠性
- 信度先行:没有良好的信度,效度无从谈起
- 理论驱动:所有分析都应基于认知融合的理论框架
- 方法透明:详细报告分析过程,便于他人重复和验证
- 结果稳健:通过敏感性分析检验结果的稳定性
最佳实践清单
- [ ] 样本量至少200(EFA)或100(CFA)
- [ ] 报告完整的信效度指标
- [ ] 检查测量不变性(多组比较)
- [ ] 考虑共同方法偏差
- [ ] 使用多种方法交叉验证结果
- [ ] 可视化结果便于理解
- [ ] 保存完整代码和随机种子以便复现
进一步学习资源
- 书籍:《心理测量学》、《结构方程模型》
- 软件:R的lavaan包、Mplus、JASP
- 文献:Gil-lucas et al. (2014) CFQ开发论文
- 在线课程:Coursera心理测量学课程
通过本指南的系统学习,研究者应能独立完成认知融合问卷的完整分析流程,从数据清洗到高级建模,确保研究的科学性和严谨性。记住,好的分析不仅需要技术技能,更需要对理论和方法的深入理解。
