<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>质量控制 - tag - 沐木</title><link>https://oldletter.cn/tags/%E8%B4%A8%E9%87%8F%E6%8E%A7%E5%88%B6/</link><description>质量控制 - tag - 沐木</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 15 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://oldletter.cn/tags/%E8%B4%A8%E9%87%8F%E6%8E%A7%E5%88%B6/" rel="self" type="application/rss+xml"/><item><title>问卷考试系统设计（四）：质量控制——测谎题、Z3 组卷验证与异常检测</title><link>https://oldletter.cn/posts/qnr-04-quality-control/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/qnr-04-quality-control/</guid><description><![CDATA[<p><strong>上一篇：<a href="/posts/qnr-03-scoring-engine/" rel="">问卷考试系统设计（三）：评分引擎</a></strong></p>
<p>问卷收上来一堆答案，怎么判断哪些是认真填的、哪些是随便糊弄的？另外，在出卷阶段，怎么保证组出来的试卷在分数分布上是合理的？这两个问题分别对应<strong>答题后质量检测</strong>和<strong>出卷时约束验证</strong>。</p>
<p>三道防线：<strong>测谎题</strong>检测被试是否在刻意美化，<strong>Z3 约束求解器</strong>在组卷阶段验证分数区间无冲突，<strong>异常模式检测</strong>抓全选、极端值、过快作答等刷卷行为。</p>
<p>质量控制分成卷前验证和卷后检测，两条链路末尾汇总成答卷可信度：</p>
<div class="mermaid" id="id-2" data-mermaid-definition="Zmxvd2NoYXJ0IFRCCiAgICAgICAgICAgICAgICAgICAgQVsi5Y&#43;R5biD5YmNIl0gLS0&#43;IEJbIlozIOe6puadn&#43;mqjOivgSJdCiAgICAgICAgICAgICAgICAgICAgQiAtLT4gQ1si6aKY6YeP44CB57u05bqm44CB5LqS5pal6KeE5YiZ5qOA5p&#43;lIl0KICAgICAgICAgICAgICAgICAgICBDIC0tPiBEeyLlj6/lj5HluIMifQogICAgICAgICAgICAgICAgICAgIEVbIuaPkOS6pOWQjiJdIC0tPiBGWyLmtYvosI7popjmo4DmtYsiXQogICAgICAgICAgICAgICAgICAgIEUgLS0&#43;IEdbIuS4gOiHtOaAp&#43;ajgOa1iyJdCiAgICAgICAgICAgICAgICAgICAgRSAtLT4gSFsi5L2c562U5qih5byP5qOA5rWLIl0KICAgICAgICAgICAgICAgICAgICBGIC0tPiBJWyLotKjph4/liIYiXQogICAgICAgICAgICAgICAgICAgIEcgLS0&#43;IEkKICAgICAgICAgICAgICAgICAgICBIIC0tPiBJCiAgICAgICAgICAgICAgICAgICAgRCAtLT4gSlsi6Zeu5Y2354mI5pys5Y&#43;v5L&#43;hIl0KICAgICAgICAgICAgICAgICAgICBJIC0tPiBLWyLnrZTljbfmnInmlYjmgKfnrYnnuqciXQ==">flowchart TB
                    A[&#34;发布前&#34;] --&gt; B[&#34;Z3 约束验证&#34;]
                    B --&gt; C[&#34;题量、维度、互斥规则检查&#34;]
                    C --&gt; D{&#34;可发布&#34;}
                    E[&#34;提交后&#34;] --&gt; F[&#34;测谎题检测&#34;]
                    E --&gt; G[&#34;一致性检测&#34;]
                    E --&gt; H[&#34;作答模式检测&#34;]
                    F --&gt; I[&#34;质量分&#34;]
                    G --&gt; I
                    H --&gt; I
                    D --&gt; J[&#34;问卷版本可信&#34;]
                    I --&gt; K[&#34;答卷有效性等级&#34;]</div><hr>
<h2 id="第一道防线测谎题检测装好人">第一道防线：测谎题，检测&quot;装好人&quot;</h2>
<h3 id="设计原理">设计原理</h3>
<p>测谎题的逻辑很简单：<strong>大多数人不太可能在所有测谎题上都选“完美”的那一端</strong>。</p>
<p>MMPI 的 L（Lie）效度量表是经典案例。它会放一些社会称许性很强、但现实中很难完全做到的题目，例如：</p>
<ul>
<li>“我从来没有说过谎”，大多数人都说过谎，全选“是”反而可疑</li>
<li>“我从不背后说人坏话”，太完美了，不真实</li>
<li>“我从来不会迟到”，现实里很难完全做到</li>
</ul>
<p>这些题目不计入心理维度的分数，唯一的用途就是检测被试的作答态度。</p>
<h3 id="评分逻辑">评分逻辑</h3>
<p>每道测谎题都有一个或多个&quot;可疑答案&quot;。被试选中了可疑答案，就记 1 分；否则记 0 分。末尾把所有测谎题的可疑分加起来，和阈值做比较。</p>
<p>阈值不要写死，更稳妥按量表手册和人群配置。下面只是工程示例：</p>
<ul>
<li><strong>VALID</strong>（有效）：可疑比例 ≤ 50%</li>
<li><strong>SUSPICIOUS</strong>（可疑）：50% &lt; 可疑比例 ≤ 80%</li>
<li><strong>INVALID</strong>（无效）：可疑比例 &gt; 80%</li>
</ul>
<h3 id="实现">实现</h3>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-java">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title=""><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="n">LieScaleResult</span><span class="w"> </span><span class="nf">calculate</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="n">Question</span><span class="o">&gt;</span><span class="w"> </span><span class="n">lieScaleQuestions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                 </span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span><span class="w"> </span><span class="n">Answer</span><span class="o">&gt;</span><span class="w"> </span><span class="n">answers</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kt">int</span><span class="w"> </span><span class="n">totalLieScore</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">Question</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">lieScaleQuestions</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Answer</span><span class="w"> </span><span class="n">answer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answers</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="na">getId</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">answer</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answer</span><span class="p">.</span><span class="na">getSelectedValue</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">q</span><span class="p">.</span><span class="na">getLieAnswerValues</span><span class="p">().</span><span class="na">contains</span><span class="p">(</span><span class="n">value</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">totalLieScore</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kt">double</span><span class="w"> </span><span class="n">lieRatio</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="w"> </span><span class="n">totalLieScore</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">lieScaleQuestions</span><span class="p">.</span><span class="na">size</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">String</span><span class="w"> </span><span class="n">verdict</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">lieRatio</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">8</span><span class="p">)</span><span class="w"> </span><span class="n">verdict</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;INVALID&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">lieRatio</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">0</span><span class="p">.</span><span class="na">5</span><span class="p">)</span><span class="w"> </span><span class="n">verdict</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;SUSPICIOUS&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">else</span><span class="w"> </span><span class="n">verdict</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;VALID&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">LieScaleResult</span><span class="p">(</span><span class="n">totalLieScore</span><span class="p">,</span><span class="w"> </span><span class="n">lieScaleQuestions</span><span class="p">.</span><span class="na">size</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                               </span><span class="n">lieRatio</span><span class="p">,</span><span class="w"> </span><span class="n">verdict</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span></span></span></code></pre></div></div>
<blockquote>
<p><strong>注意</strong>：测谎题的可疑答案不一定总是更高分。有些题是&quot;选低分才可疑&quot;，有些还可能有多个可疑选项。稳妥做法是在题目配置里显式声明 <code>lieAnswerValues</code>。</p>]]></description></item></channel></rss>