Amazon MTurk调查版本分配不均:JS随机数问题排查与修复求助
排查与修复MTurk调查版本分配不均的问题
我帮你梳理下可能的问题根源,以及对应的修复方案:
可能的原因
1. localStorage键名冲突
你用了'i'作为localStorage的键名,这个名字太通用了。如果参与者之前做过其他使用相同键名的MTurk任务,localStorage里的旧值会被保留,导致新任务直接复用之前的版本分配。如果之前的任务中版本1的占比高,就会直接拉高原任务版本1的分配量。
2. 隐式类型转换的潜在风险
localStorage.getItem()返回的是字符串类型,但你直接用==和数字比较。虽然大多数情况下"0" == 0会成立,但如果存储的值被意外篡改(比如变成非数字字符串),可能导致匹配逻辑出错,不过这个概率相对较低。
3. 随机数生成本身无问题
你提到在线编辑器里分配正常,这点也能验证:Math.floor(3*Math.random())确实会生成0、1、2三个均等概率的整数,各占1/3的概率,本身没有逻辑漏洞。
修复方案
下面是修改后的完整代码,我标注了关键修改点:
<HTMLQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd"> <HTMLContent><![CDATA[ <!-- YOUR HTML BEGINS --> <!DOCTYPE html> <html> <head> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/> <script type='text/javascript' src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js'></script> <script> function test(){ document.getElementById('txt-field').value = "1"; } </script> </head> <body> <form name='mturk_form' method='post' id='mturk_form' action='https://www.mturk.com/mturk/externalSubmit'> <input type='hidden' value='' name='assignmentId' id='assignmentId'/> <span> <INPUT TYPE="text" NAME="link_click" id='txt-field' value="0" style="display: none"> <div><h3><a href="www.google.com" target="_blank" id='report420' onclick="test()" >link</a></h3> Instructions</div> <div><table border="1" style="height: 258px;" width="196"><tbody>Table</tbody></table></div> </span> <!-- 修改后的版本分配逻辑 --> <script> document.write("Miscellaneous question"); // 1. 使用唯一键名:结合assignment ID确保每个任务独立无冲突 const storageKey = `mturk_survey_version_${turkGetAssignmentID()}`; let version = localStorage.getItem(storageKey); // 2. 显式处理类型转换,确保版本是有效数字 version = parseInt(version, 10); if (isNaN(version)) { // 3. 生成随机版本,确保0/1/2均等概率 version = Math.floor(Math.random() * 3); localStorage.setItem(storageKey, version.toString()); } // 4. 使用严格相等===避免隐式转换问题,同时用if-else优化判断逻辑 if (version === 0) { document.write("Version 1"); } else if (version === 1) { document.write("Version 2"); } else if (version === 2) { document.write("Version 3"); } document.write("Miscellaneous question"); </script> <p><input type='submit' id='submitButton' value='Submit' /></p> </form> <script language='Javascript'>turkSetAssignmentID();</script> </body> </html> <!-- YOUR HTML ENDS --> ]]></HTMLContent> <FrameHeight>600</FrameHeight> </HTMLQuestion>
关键修改说明:
- 唯一键名:用
mturk_survey_version_${turkGetAssignmentID()}作为localStorage的键,每个MTurk任务的assignment ID都是唯一的,彻底避免和其他任务的键名冲突。 - 显式类型转换:把从localStorage取出的值转成整数,并用
isNaN()判断是否有效,无效则重新生成随机版本。 - 严格相等判断:用
===代替==,避免字符串和数字的隐式转换,确保逻辑严谨。 - 优化条件判断:用
if-else if-else代替三个独立的if,逻辑更清晰,也避免不必要的判断。
额外优化:添加localStorage可用性检测,防止某些浏览器禁用localStorage导致的问题
// 在生成版本前添加检测函数 function isLocalStorageAvailable() { try { const testKey = '__mturk_survey_test__'; localStorage.setItem(testKey, testKey); localStorage.removeItem(testKey); return true; } catch (e) { return false; } } // 然后在逻辑中使用: let version; if (isLocalStorageAvailable()) { // 执行上面的localStorage版本分配逻辑 } else { // 直接生成随机版本,无法持久化但不影响概率分布 version = Math.floor(Math.random() * 3); }
这样即使localStorage不可用,也能正常分配版本,只是页面刷新会重新分配,但不会影响整体的概率分布。
内容的提问来源于stack exchange,提问作者Mirko
相关产品推荐
相关产品推荐

