Word2vec Skipgram 代码
Word2vec Skipgram codes
我构建了一个程序,我的程序的一部分具有使用 window_size = 2
查找 windowData 的功能
我的代码:
string = [['I', 'have', 'a', 'pen', 'to', 'use']]
window_size = 2
windowData = []
for lines in string:
for index,word in enumerate(lines):
for words in lines[max(index-window_size,0):min(index+window_size,len(string)+1)]:
if words != word:
windowData.append([word,words])
print(windowData)
当前输出:
[['I', 'have'], ['have', 'I'], ['a', 'I'], ['a', 'have'], ['pen', 'have']]
根据我对skip-gram的理解应该是这样的吧? (如有错误请指正)
预期输出:
[['I', 'have'], ['I', 'a'], ['have', 'I'], ['have', 'a'], ['have', 'pen'], ['a', 'have'], ['a', 'I'], ['a', 'pen'],['a', 'to'], ['pen', 'a'], ['pen', 'have'], ['pen', 'to'], ['pen', 'use'], ['to', 'pen'], ['to', 'a'],['to', 'use'], ['use', 'pen'],['use', 'to']]
我明白仅仅学习编程语言是不够的,我应该更专注于解决问题。如果可能的话,也请给我推荐一些网站。谢谢你。
使用 itertools:
from itertools import combinations
string = ['I', 'have', 'a', 'pen', 'to', 'use']
window_size = 2
print(list(combinations(string, window_size)))
输出:
[('I', 'have'), ('I', 'a'), ('I', 'pen'), ('I', 'to'), ('I', 'use'), ('have', 'a'), ('have', 'pen'), ('have', 'to'), ('have', 'use'), ('a', 'pen'), ('a', 'to'), ('a', 'use'), ('pen', 'to'), ('pen', 'use'), ('to', 'use')]
几点观察:
用变量名'string'调用一个list-of-lists-of-strings是个坏主意;如果实际上这里是 Word2Vec
中常用的那种标记化文本列表,那么像 'sentences' 或 'texts' 这样的名称就更清楚了。
您不想重新枚举 lines
每个嵌套循环,而是处理外循环的当前项。因此 sentences
的循环将给出 sentence
。您将遍历 sentence
以获得每个 word
。
这些上下文词到目标词对实际上是使用 Python 的 元组 的好地方,创建的本质上是微小的不可变列表在需要的时候 - 只需使用括号而不是方括号。
切出截尾的window时不需要在sentence
的长度上加一,因为长度已经是实际计数元素,比最后一个位置高一个。但是你确实需要在 index + window_size
上加一,因为切片操作 ([x:y]
) exclusive 第二个值 (y).
如果您实际上打算让这个循环处理许多文本,您可能不希望 return 所有文本对作为一个巨大的文本对列表。相反,您可能希望 return 输入中每个单词列表都有一个对列表。
当刚开始和难以理解时,使用非常具有描述性的变量名称会有所帮助,并且为了清楚起见,将中间结果分解为命名变量中的分隔行。
试试这个反映这些变化的最小改动版本:
sentences = [['I', 'have', 'a', 'pen', 'to', 'use']]
window_size = 2
pairs_for_all_sentences = []
for sentence in sentences:
this_sentence_pairs = []
for index, target_word in enumerate(sentence):
window_words = sentence[max(index - window_size, 0) : min(index + window_size + 1, len(sentence))]
for window_word in window_words:
if window_word != target_word:
this_sentence_pairs.append((window_word, target_word))
pairs_for_all_sentences.append(this_sentence_pairs)
print(pairs_for_all_sentences)
最后一点:与创建真正的 skip-gram 对的方式相比,这并不完全正确。虽然不会为单词本身生成对,但如果相同的单词出现在 window 中,则会创建一个单词对。所以在句子"I am very very happy"中,实际上会训练出两个('very', 'very')
对。
我构建了一个程序,我的程序的一部分具有使用 window_size = 2
我的代码:
string = [['I', 'have', 'a', 'pen', 'to', 'use']]
window_size = 2
windowData = []
for lines in string:
for index,word in enumerate(lines):
for words in lines[max(index-window_size,0):min(index+window_size,len(string)+1)]:
if words != word:
windowData.append([word,words])
print(windowData)
当前输出:
[['I', 'have'], ['have', 'I'], ['a', 'I'], ['a', 'have'], ['pen', 'have']]
根据我对skip-gram的理解应该是这样的吧? (如有错误请指正)
预期输出:
[['I', 'have'], ['I', 'a'], ['have', 'I'], ['have', 'a'], ['have', 'pen'], ['a', 'have'], ['a', 'I'], ['a', 'pen'],['a', 'to'], ['pen', 'a'], ['pen', 'have'], ['pen', 'to'], ['pen', 'use'], ['to', 'pen'], ['to', 'a'],['to', 'use'], ['use', 'pen'],['use', 'to']]
我明白仅仅学习编程语言是不够的,我应该更专注于解决问题。如果可能的话,也请给我推荐一些网站。谢谢你。
使用 itertools:
from itertools import combinations
string = ['I', 'have', 'a', 'pen', 'to', 'use']
window_size = 2
print(list(combinations(string, window_size)))
输出:
[('I', 'have'), ('I', 'a'), ('I', 'pen'), ('I', 'to'), ('I', 'use'), ('have', 'a'), ('have', 'pen'), ('have', 'to'), ('have', 'use'), ('a', 'pen'), ('a', 'to'), ('a', 'use'), ('pen', 'to'), ('pen', 'use'), ('to', 'use')]
几点观察:
用变量名'string'调用一个list-of-lists-of-strings是个坏主意;如果实际上这里是
Word2Vec
中常用的那种标记化文本列表,那么像 'sentences' 或 'texts' 这样的名称就更清楚了。您不想重新枚举
lines
每个嵌套循环,而是处理外循环的当前项。因此sentences
的循环将给出sentence
。您将遍历sentence
以获得每个word
。这些上下文词到目标词对实际上是使用 Python 的 元组 的好地方,创建的本质上是微小的不可变列表在需要的时候 - 只需使用括号而不是方括号。
切出截尾的window时不需要在
sentence
的长度上加一,因为长度已经是实际计数元素,比最后一个位置高一个。但是你确实需要在index + window_size
上加一,因为切片操作 ([x:y]
) exclusive 第二个值 (y).如果您实际上打算让这个循环处理许多文本,您可能不希望 return 所有文本对作为一个巨大的文本对列表。相反,您可能希望 return 输入中每个单词列表都有一个对列表。
当刚开始和难以理解时,使用非常具有描述性的变量名称会有所帮助,并且为了清楚起见,将中间结果分解为命名变量中的分隔行。
试试这个反映这些变化的最小改动版本:
sentences = [['I', 'have', 'a', 'pen', 'to', 'use']]
window_size = 2
pairs_for_all_sentences = []
for sentence in sentences:
this_sentence_pairs = []
for index, target_word in enumerate(sentence):
window_words = sentence[max(index - window_size, 0) : min(index + window_size + 1, len(sentence))]
for window_word in window_words:
if window_word != target_word:
this_sentence_pairs.append((window_word, target_word))
pairs_for_all_sentences.append(this_sentence_pairs)
print(pairs_for_all_sentences)
最后一点:与创建真正的 skip-gram 对的方式相比,这并不完全正确。虽然不会为单词本身生成对,但如果相同的单词出现在 window 中,则会创建一个单词对。所以在句子"I am very very happy"中,实际上会训练出两个('very', 'very')
对。