五、Mind 模块

词嵌入中蕴含着人类的认知信息,以往的词嵌入大多是比较一个概念中两组反义词与某对象的距离计算认知信息。

  • 多个对象与某概念的语义远近,职业与性别,某个职业是否存在亲近男性,而排斥女性

  • 多个对象在某概念向量投影的大小, 人类语言中留存着对不同动物体积的认知记忆,如小鼠大象。动物词在词向量空间中是否能留存着这种大小的记忆

本模块主要是利用已训练出的 word2vec 模型,挖掘潜在的态度偏见、刻板印象等。 这部分难度较大, 建议有精力且电脑性能好的同学可以用 cntext 训练模型, 再来实验 Mind 模块。

模块

函数(类)

功能

mind

ct.semantic_centroid(wv, words)

计算多个词语的语义中心向量

mind

ct.generate_concept_axis(wv, words1, words2)

生成概念轴向量。

mind

ct.sematic_projection(wv, words, poswords, negwords)

测量语义投影

mind

ct.project_word(wv, a, b, cosine=False)

在向量空间中, 计算词语 a 在词语 b 上的投影。

mind

ct.sematic_distance(wv, words, c_words1, c_words2)

测量语义距离

mind

ct.divergent_association_task(wv, words)

测量发散思维(创造力)

mind

ct.discursive_diversity_score(wv, words)

测量语言差异性(认知差异性)

mind

ct.procrustes_align(base_wv, other_wv)

两个 word2vec 进行语义对齐,可反应随时间的社会语义变迁


5.1 semantic_centroid(wv, words)

计算多个词语的语义中心向量

import cntext as ct

# 获取词向量文件 https://cntext.readthedocs.io/zh-cn/latest/embeddings.html
w2v = ct.load_w2v('专利摘要-Word2Vec.200.15.bin')
semantic_centroid(wv=w2v, words=['创新', '颠覆'])

Run

array([ 0.15567462, -0.05117003, -0.18534171,  0.20808656, -0.01133028,
        0.10738188, -0.02571066,  0.06051835,  0.00107351,  0.08017981,
        0.08914138,  0.01845527,  0.06232869, -0.03851539, -0.17092938,
        0.02196799, -0.04136903,  0.11350462, -0.09539546,  0.04907424,
        0.01268489,  0.05294977,  0.08449743, -0.02762416,  0.02332745,
        0.08865491, -0.06260188, -0.0378293 ,  0.04771722,  0.05745243,
        0.04417403, -0.04126203, -0.02403288, -0.03834526,  0.08115771,
        0.01508994,  0.07678635,  0.01395652,  0.1360324 ,  0.03027042,
       -0.02819572,  0.02339242,  0.11504567,  0.02910597,  0.06149592,
        0.01126606, -0.10132807,  0.07762785, -0.01214836,  0.03780747,
        0.12758181, -0.03115267, -0.19343086, -0.21930983,  0.05253006,
       -0.01452067, -0.07067247, -0.04237257, -0.08911953,  0.08573315,
        0.02742999,  0.05392318,  0.02916237,  0.04465031, -0.0788566 ,
       -0.07088121,  0.03111146,  0.00387428, -0.04032568,  0.14935694,
       -0.03880607,  0.07259471,  0.01711774, -0.05551507,  0.01039889,
        0.00666137,  0.03313185,  0.03169986,  0.08127907,  0.0239668 ,
       -0.00991806, -0.04201584,  0.01199235, -0.08669737, -0.02087858,
       -0.03440931,  0.02360864,  0.06623896, -0.01020982,  0.01200165,
        0.01059455,  0.13041293,  0.01103112,  0.03814259, -0.01519256,
        0.02946554,  0.00593279,  0.08796389,  0.0198915 , -0.0569265 ,
       -0.14622693,  0.07680258, -0.02288322, -0.04959924,  0.03325186,
        0.11031196,  0.06893978,  0.04289736, -0.0307357 , -0.09662723,
        0.02554002,  0.05394766,  0.047071  , -0.09522557, -0.08160087,
       -0.01467315, -0.01304489,  0.07513782,  0.04484766, -0.0516454 ,
        0.00648148,  0.01093231, -0.00303798, -0.06217093,  0.02755075,
       -0.10749754, -0.05205868, -0.02562402,  0.09068517,  0.05208463,
       -0.11790312,  0.02881086, -0.02414756,  0.00192055,  0.03881926,
       -0.05390498,  0.06648378,  0.02055933, -0.07083403, -0.07248309,
       -0.12991821,  0.0603951 ,  0.14131376, -0.01507344, -0.06480791,
       -0.08994781, -0.03397571,  0.0108852 , -0.02777362,  0.01159309,
        0.00121858, -0.0690551 , -0.07747664,  0.03437752, -0.14576062,
        0.06320656, -0.10743124, -0.01910913,  0.15803815, -0.03027673,
       -0.02909171, -0.03350233, -0.0694584 , -0.09807504, -0.09133697,
       -0.01123043,  0.04894681, -0.01971908, -0.08290677, -0.00336836,
        0.09619438, -0.03496556,  0.09733834, -0.0421683 ,  0.01408717,
        0.03355598,  0.00748263,  0.011903  , -0.12909584,  0.01545653,
        0.07656407,  0.09496018,  0.0608537 ,  0.00597665, -0.01628997,
        0.06285962, -0.16796936, -0.0486528 ,  0.01525079, -0.03067709,
       -0.02952635, -0.02731965, -0.06351878,  0.03577968,  0.0457835 ,
        0.08370785, -0.03491699, -0.12606403, -0.08686454, -0.04782247])

5.2 generate_concept_axis(wv, c_words1, c_words2)

生成概念轴向量。

  • wv 生成概念轴向量。

  • c_words1 第一个词语列表,表示概念 1。

  • c_words2 第二个词语列表,表示概念 2。

需要注意, 概念 1 与 概念 2 是性质(方向)相反的两个概念, 如

  • 性别(男, 女)

  • 尺寸(大, 小)

  • 方向(高, 低)

  • 方向(前, 后)

  • 湿度(干, 湿)

  • 财富(贫, 富)

import cntext as ct

# 获取词向量文件 https://cntext.readthedocs.io/zh-cn/latest/embeddings.html
dm_w2v = ct.load_w2v('douban-movie-1000w-Word2Vec.200.15.bin')
gender_axis_vector = ct.generate_concept_axis(wv=dm_w2v,
                                              c_words1=['男', '男人', '父亲'],
                                              c_words2=['女', '女人', '母亲'])
gender_axis_vector

Run

array([-0.0118976 ,  0.03178174, -0.04656127,  0.00613294, -0.03692355,
       -0.06293361, -0.04739443,  0.01368712,  0.02603469, -0.02268519,
       -0.09925436,  0.05780286,  0.11218373,  0.07519485,  0.06885784,
        0.05505687, -0.04097392,  0.1737831 ,  0.05118835, -0.06879821,
        0.04762978,  0.02224233, -0.04891564, -0.08712718, -0.01432874,
       -0.07395219,  0.01229804,  0.06655715, -0.01864985, -0.04864848,
        0.00260787,  0.06843776,  0.00472286,  0.03623124,  0.11959086,
       -0.04683099, -0.11005358,  0.0271024 , -0.05976011,  0.12669185,
        0.03592191, -0.01125782, -0.02587771, -0.02719228,  0.0507662 ,
       -0.09198377,  0.09546432, -0.01937146,  0.06106697, -0.0405688 ,
       -0.1311393 ,  0.06090249,  0.03515694,  0.01364273, -0.02491697,
        0.03379048, -0.06635275,  0.01432849,  0.01212378, -0.0625283 ,
       -0.03481676, -0.0422427 , -0.17145215, -0.06323837,  0.02563147,
       -0.02371969,  0.01217621, -0.00346871,  0.07024875,  0.08295133,
        0.00731711, -0.01932047,  0.02165518, -0.09927654, -0.08531073,
        0.01949702,  0.00536061,  0.10426087, -0.02010326,  0.02297032,
       -0.10657956,  0.1035546 ,  0.00569263, -0.0849498 ,  0.1098236 ,
        0.05310893, -0.0802139 , -0.01034231, -0.12204715,  0.01407488,
       -0.01781198, -0.0134118 ,  0.09836894,  0.16098371,  0.00609895,
        0.05433145, -0.08940306,  0.00136946, -0.08455469, -0.08432727,
        0.04675778, -0.03415223, -0.18552355, -0.05219543, -0.01127822,
        0.02059881, -0.08120015, -0.15610164,  0.01439221,  0.01727759,
       -0.14516874,  0.01783531, -0.13099317,  0.03820422,  0.03033866,
       -0.01779634,  0.07759558,  0.15866944,  0.00191632, -0.00905253,
        0.0312649 , -0.05698524,  0.07270953, -0.00734233,  0.06289094,
        0.01014149, -0.0052088 ,  0.02478063, -0.0112649 , -0.0930789 ,
        0.14639418, -0.08183327, -0.08392337, -0.01458992, -0.0163887 ,
        0.06790476, -0.03252221,  0.08593727,  0.10469338, -0.01363467,
        0.00749907, -0.01320484,  0.08405331,  0.0489707 , -0.11343482,
       -0.10319041, -0.02415894,  0.13382405, -0.01983603, -0.00990637,
       -0.03335103,  0.11718886, -0.05802442, -0.18935862, -0.07409969,
       -0.08306517, -0.04423901,  0.11331058,  0.00588326,  0.06339834,
        0.04405889,  0.1263905 , -0.007273  , -0.02706875,  0.02325469,
       -0.13092995,  0.02056245, -0.0442118 , -0.01964739, -0.06501938,
        0.02196051, -0.1823353 ,  0.04273191,  0.01935809, -0.01464438,
       -0.02626805,  0.09194217,  0.02489716,  0.05376589, -0.00484252,
        0.02822759,  0.06744799, -0.14196248,  0.03016541, -0.05347864,
       -0.16907257,  0.05094757,  0.0721257 , -0.00421157,  0.03022675,
       -0.00047884,  0.07792547, -0.00209365,  0.0669208 ,  0.02009218,
        0.11358768, -0.05002993,  0.01760067,  0.03407429, -0.0893421 ],
      dtype=float32)

5.3 sematic_distance()

多个对象与某概念的语义远近,例如成功与性别,成功是否存在亲近男性,而排斥女性

ct.sematic_distance(wv, words, c_words1, c_words2)
  • wv 模型数据, 数据类型为 gensim.models.keyedvectors.KeyedVectors。

  • wordsc_words2c_words2 均为词语列表

分别计算 wordsc_words1c_words2 语义距离,返回距离差值。例如

import cntext as ct

# 获取词向量文件 https://cntext.readthedocs.io/zh-cn/latest/embeddings.html
dm_w2v = ct.load_w2v('douban-movie-1000w-Word2Vec.200.15.bin')

male_concept = ['male', 'man', 'he', 'him']
female_concept = ['female', 'woman', 'she', 'her']
software_engineer_concept  = ['engineer',  'programming',  'software']
d1 = distance(male_concept,  software_engineer_concept)
d2 = distance(female_concept,  software_engineer_concept)

如果 d1-d2<0,说明在语义空间中,software_engineer_concept 更接近 male_concept ,更远离 female_concept

换言之,在该语料中,人们对软件工程师这一类工作,对女性存在刻板印象(偏见)。

import cntext as ct

# glove_w2v.6B.100d.txt链接: https://pan.baidu.com/s/1MMfQ7M0YCzL9Klp4zrlHBw 提取码: 72l0
g_wv = ct.load_w2v('data/glove_w2v.6B.100d.txt')

engineer = ['program', 'software', 'computer']
man_words =  ["man", "he", "him"]
woman_words = ["woman", "she", "her"]

ct.sematic_distance(wv=g_wv,
                    words=engineer,
                    c_words1=man_words,
                    c_words2=woman_words)

Run

-0.5

数值小于 0,在语义空间中,工程师更接近于男人,而不是女人。


5.4 sematic_projection()

多个对象在某概念向量投影的大小

sematic_projection(wv, words, poswords, negwords, cosine=False, return_full=True)
  • wv 模型数据, 数据类型为 gensim.models.keyedvectors.KeyedVectors。

  • wordsposwordsnegwords 均为词语列表

  • cosine: 是否使用余弦相似度,默认为False,返回投影值;True时返回余弦相似度

  • return_full: 是否返回完整元组列表,默认为True


为了解释词向量模型的语义投影,我使用了 2022 年 Nature 论文中的图片[@Grand2022SemanticPR]。 关于动物的名字,人类对动物大小的认知信息隐藏在语料库文本中。 通过将LARGE WORDSSMALL WORDS的含义用不同的animals的向量投影,动物在size 向量上的投影(就像下图中的红线 ) 得到,因此可以通过计算比较动物的大小。

根据两组反义词 poswords , negwords 构建一个概念(认知)向量, words 中的每个词向量在概念向量中投影,即可得到认知信息。

分值越大,words 越位于 poswords 一侧。

Grand, G., Blank, I.A., Pereira, F. and Fedorenko, E., 2022. Semantic projection recovers rich human knowledge of multiple object features from word embeddings. Nature Human Behaviour, pp.1-13."

例如,人类的语言中,存在尺寸、性别、年龄、政治、速度、财富等不同的概念。每个概念可以由两组反义词确定概念的向量方向。

以运动项目为例,在人类认知中, 开展不同运动的人所处于的财富水平是有差异的。

import cntext as ct

# 获取词向量文件 https://cntext.readthedocs.io/zh-cn/latest/embeddings.html
dm_w2v = ct.load_w2v('douban-movie-1000w-Word2Vec.200.15.bin')

# 定义词语列表
phy_words = ['游泳', '跑步', '篮球', '羽毛球', '马拉松', '马术', '徒步']

rich_words = [
    '富裕', '财富', '金钱', '豪宅', '豪车',
    '奢侈品', '投资', '股票', '基金', '黄金',
    '钻石', '游艇', '私人飞机', '企业家', '富豪',
    '成功', '繁荣', '奢华', '贵族', '高收入'
]

poor_words = [
    '贫穷', '贫困', '饥饿', '失业', '低收入',
    '简陋', '破旧', '乞丐', '流浪', '欠债',
    '破产', '困境', '艰难', '挣扎', '匮乏',
    '落后', '无助', '绝望', '赤贫', '温饱'
]

phy_project_on_fortune = ct.sematic_projection(wv = dm_w2v,
                                               words = phy_words,
                                               poswords =rich_words,
                                               negwords = poor_words)

phy_project_on_fortune

Run

[('跑步', -1.82),
 ('徒步', -0.82),
 ('游泳', -0.19),
 ('羽毛球', 0.57),
 ('马拉松', 0.62),
 ('马术', 1.15),
 ('篮球', 4.0)]

关于运动的财富水平, 大体上还是准的。数值越大, 语义越接近 poswords, 即越富裕。


5.4 project_word

在向量空间中, 计算词语a在词语b上的投影(余弦相似度)。默认返回的是投影值。 如果 cosine=True,返回词语a与词语b的余弦相似度。

project_word(wv, a, b, cosine=False)
  • wv 语料 txt 文件路径

  • a 词语 a 字符串或列表

  • b 词语字符串、词语列表、或某概念向量

  • cosine: 是否使用余弦相似度, 默认为False,返回a在b上的投影值; True时,返回a与b的余弦相似度。

b='苗条'
for a in ['性感','美丽', '可爱', '丑陋']:
    proj = ct.project_word(dm_w2v, a, b)
    print(f'[{a}]在[{b}]投影值: {proj}')


b='修长'
for a in ['性感','美丽', '可爱', '丑陋']:
    proj = ct.project_word(dm_w2v, a, b)
    print(f'[{a}]在[{b}]投影值: {proj}')

Run

[性感][苗条]投影值: 14.172947883605957
[美丽][苗条]投影值: 7.0944623947143555
[可爱][苗条]投影值: 6.935092926025391
[丑陋][苗条]投影值: 1.235807180404663

[性感][修长]投影值: 14.599699974060059
[美丽][修长]投影值: 9.360642433166504
[可爱][修长]投影值: 4.740543842315674
[丑陋][修长]投影值: 4.010622501373291

可以看到, 在豆瓣电影语料中, 在[苗条、修长]维度的认知中,都认为

  • [性感]意味着身材最瘦长

  • [美丽]次之、[可爱]略显不那么修长苗条

  • [丑陋]意味着基本与[苗条、修长]无关,数值最小。


为了让投影值更稳定,可以选择词组,确定[苗条、修长]这个概念的概念轴向量

for a in ['性感','美丽', '可爱', '丑陋']:
    proj = ct.project_word(wv=dm_w2v, a=a, b=['修长', '苗条'])
    print(f'[{a}]在[修长,苗条]投影值: {proj}')

Run

[性感]在[修长,苗条]投影值: 15.807487487792969
[美丽]在[修长,苗条]投影值: 9.040315628051758
[可爱]在[修长,苗条]投影值: 6.414511203765869
[丑陋]在[修长,苗条]投影值: 2.882350444793701

5.5 divergent_association_task()

PNAS | 使用语义距离测量一个人的创新力(发散思维)得分。一些理论认为,有 创造力 的人能够产生更多 发散性 的想法。如果这是正确的,简单地让被试写 N 个不相关的单词,然后测量这 N 个词的语义距离, 作为发散思维的客观衡量标准。

ct.divergent_association_task(wv, words)
  • wv 模型数据, 数据类型为 gensim.models.keyedvectors.KeyedVectors。

  • **words**词语列表


low_words = ["arm", "eyes", "feet", "hand", "head", "leg", "body"]
average_words = ["bag", "bee", "burger", "feast", "office", "shoes", "tree"]
high_words = ["hippo", "jumper", "machinery", "prickle", "tickets", "tomato", "violin"]

# 导入模型,得到wv。
# wv = ct.load_w2v('wiki的word2vec模型文件路径')


print(ct.divergent_association_task(wv, low_words)) # 50
print(ct.divergent_association_task(wv, average_words)) # 78
print(ct.divergent_association_task(wv, high_words)) # 95

Run

50
78
95

5.6 discursive_diversity_score()

MS2022 | 使用语言差异性测量团队认知差异性

ct.discursive_diversity_score(wv, words)
  • wv 模型数据, 数据类型为 gensim.models.keyedvectors.KeyedVectors。

  • **words**词语列表

  • 返回一个数值

高绩效团队是那些具有调节共享认知以适应不断变化的任务要求的集体能力的团队:在进行构思任务时,它们表现出更高的话语多样性,在执行协调任务时,表现出较低的话语多样性。


5.7 procrustes_align()

该函数主要用于反映同一研究对象随着时间推进的社会文化变迁,或者同一时间范围内两个被研究主体间的差异。

ct.procrustes_align(base_wv, other_wv, words=None)
  • base_wv (gensim.models.keyedvectors.KeyedVectors): 基准语言模型

  • other_wv (gensim.models.keyedvectors.KeyedVectors): 其他语言模型

  • words (list, optional): 是否根据词典 words 对模型进行对齐, 对齐结束后的模型中含有的词不会超出 words 的范围; 默认 None.

由于不同语料训练的 Word2Vec 模型无法直接比较, 需要先选定一个基准模型 base_embed, 之后根据 base_embed 对其他模型 other_embed 进行调整,调整后的模型就可以使用前面的语义距离函数或者语义投影函数。 这一过程用到的算法叫做 procrustes 正交算法。

这里推荐一篇 可视化 | 人民日报语料反映七十年文化演变