外观
内部一致性信度分析
检查同一量表或维度的题项是否具有一致性。
计算口径
题项应测量同一构念,反向题先完成反向计分。每个维度使用全部所属题项均有效的记录。不能用高信度代替结构效度。
可以直接勾选整体题项,也可添加维度并为每个维度勾选题项。“附题项信度明细”增加CITC与删除该题后的α;标准化α基于相关矩阵。
同时考虑系数、题项数量和题项内容。负系数应检查编码及题目方向。删题后的系数仅供判断,不自动删除题项。
同源实现
以下片段来自 core/statistical/measurement.py 的 reliability,由镜像脚本按语法树提取。共享辅助函数和分发逻辑包含在完整下载包中。
py
def reliability(data, options, split=False):
rows, item_rows, details = [], [], {}
for label, selected in dimension_sets(data, options):
frame = enough(numeric_frame(data, selected).dropna(), 3)
values = frame.values
for name in selected:
varying(frame[name].values, name)
coefficient = alpha_coefficient(values)
if coefficient is None:
raise ValueError(_('维度“%(name)s”的总分没有有效变异', name=label))
correlation = np.corrcoef(values, rowvar=False)
count = len(selected)
standardized = count/(count-1)*(1-count/np.sum(correlation)) if np.sum(correlation) > 0 else None
row = {'dimension': label, 'n': len(frame), 'items': count, 'alpha': coefficient, 'standard_alpha': standardized}
detail = {'n': len(frame), 'items': selected, 'alpha': coefficient, 'standardized_alpha': standardized,
'covariance': np.cov(values, rowvar=False), 'correlation': correlation}
if split:
split_method = choice(options, 'split_method', 'odd_even', ('odd_even', 'first_last'))
indexes_a = np.arange(0, count, 2) if split_method == 'odd_even' else np.arange((count+1)//2)
indexes_b = np.array([i for i in range(count) if i not in indexes_a])
first, second = values[:, indexes_a].sum(axis=1), values[:, indexes_b].sum(axis=1)
varying(first, label)
varying(second, label)
r = float(stats.pearsonr(first, second)[0])
if r <= -1+1e-12:
raise ValueError(_('两个半量表完全负相关,请检查反向计分'))
proportion = len(indexes_a)/count
equal_sb = 2*r/(1+r)
# 不等长校正使用题项数比例,等长时退化为常规Spearman–Brown公式。
unequal_sb = 2*r/(r+np.sqrt(r*r+4*proportion*(1-proportion)*(1-r*r)))
total_var = np.var(first+second, ddof=1)
guttman = 2*(1-(np.var(first, ddof=1)+np.var(second, ddof=1))/total_var)
row.update(first_items=len(indexes_a), second_items=len(indexes_b), half_r=r,
equal_sb=equal_sb, unequal_sb=unequal_sb, guttman=guttman)
detail.update(split_method=split_method, first_items=[selected[i] for i in indexes_a],
second_items=[selected[i] for i in indexes_b], half_r=r, equal_sb=equal_sb,
unequal_sb=unequal_sb, guttman=guttman)
else:
items = item_statistics(values, selected)
item_rows.extend({'dimension': label, **item} for item in items)
detail['item_statistics'] = items
rows.append(row)
details[label] = detail
headers = [Column('dimension', _('量表或维度'), 'text'), Column('n', 'N', 'integer'), Column('items', _('题项数'), 'integer')]
if split:
headers += [Column('first_items', _('前半题项数'), 'integer'), Column('second_items', _('后半题项数'), 'integer'),
Column('half_r', _('两半相关')), Column('equal_sb', _('等长Spearman–Brown')),
Column('unequal_sb', _('不等长Spearman–Brown')), Column('guttman', _('Guttman分半系数'))]
else:
headers += [Column('alpha', "Cronbach's α"), Column('standard_alpha', _('标准化α'))]
tables = [PaperTable(_('分半信度分析') if split else _('内部一致性信度分析'), headers, rows)]
if not split and boolean(options, 'item_details', False):
tables.append(PaperTable(_('题项信度明细'), [Column('dimension', _('维度'), 'text'), Column('item', _('题项'), 'text'),
Column('mean', _('均值')), Column('sd', _('标准差')), Column('citc', 'CITC'),
Column('alpha_deleted', _('删除该题项后的α'))], item_rows))
return StatisticalResult(tables, details)复现本方法
在解压目录安装 requirements.txt 后执行。样例为固定种子的模拟数据,仅供验证;输出不得冒充真实研究结果。
python
import examples._bootstrap
from examples.statistics_cases import build_data, method_cases
from core.statistical.runner import analyze
method = "stat_reliability_alpha"
options = dict(method_cases())[method]
result = analyze(build_data(), method, options)
print(result.tables[0].html())