首先说的就是分词,对英语来说每个词与词之间是通过空格辨别的,例如I love natural language processing
,每个词之间都是有空格的,所以很容划分为[i, love, natural, language, processing]
但是中文的词并没有分开,而是全部连在一起的,例如我爱自然语言处理
,我们可以通过分词工具进行切分,我这里使用的jieba分词
import jieba
res = jieba.cut("我爱自然语言处理",cut_all=False)
print(list(res)) # ['我', '爱', '自然语言', '处理']
首先我们需要准备一段预料,一般情况下通常是一个非常大的语料库,这样才能覆盖更多的词语,训练的词向量也会更加准确,但是这里只是为了演示,所以随便搞一点就行。正好最近在看仙逆,截取前两章节作为训练语料。我们将其保存到一个txt中
首先我们需要对去除每一行的换行符,然后将每一行拼接在一起,送到jieba分词中
import jieba
def read_text_and_cut_word(cropus_path):
data = []
with open(cropus_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if line != '': # 过滤掉空白行
data.append(line)
sentences = "\n".join(data) # 将文本拼接成一个字符串
words = jieba.cut(sentences,cut_all=False)
with open("p_input.txt", "w") as f: # 将分词的结果保存到txt中
f.write(' '.join(words))
read_text_and_cut_word('news.txt')
原始的文本已经分好词保存下来了,可以看到分的词里面有很多中文的停用词和标点符号,。?、\n
等等,通常情况下,分词的时候需要加载我们自定义的停用词,例如啊,的,是
等等,不过为了简单,这里只去除标点和数字,
def handle_stopwords_and_whitesapce():
# 标点符号集
stopwords = '''~!@#$%^&*()_+`1234567890-={}[]::";'<>,.?/|\、·!()¥“”‘’《》,。?/—-【】….'''
stopwords_set = set([i for i in stopwords])
stopwords_set.add("br") # 异常词也加入此集,方便去除
with open("temp.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
data = []
for line in lines:
line = line.strip()
for s in stopwords_set:
line = line.strip().replace(s, "")
line = line.replace(" "," ").replace(" "," ")
if line != "" and line != " ":
data.append(line)
all_text = " ".join(data)
with open("train.txt", "w") as f:
f.write(all_text)
handle_stopwords_and_whitesapce()
很好,语聊基本就处理好了,现在每个词之间使用空格进行分割,我们就可以将切好的词输入到我们的网络中训练了。但是由于计算机只认识01,所以我们需要对词进行编码。
from collections import Counter
word2idx = {}
idx2word = {}
max_idx = 0
def build_vocab(cropus,unused_cnt=100):
with open(cropus, "r", encoding="utf-8") as f:
all_text = f.readline()
vocabs = all_text.split(" ") # 读出所有的词
vocab_dict = dict(Counter(vocabs).most_common()) # 统计每个词出现的频率
for i,w in enumerate(vocab_dict.keys()):
word2idx[w] = i + unused_cnt # 为每个词进行id编码
idx2word[i + unused_cnt] = w # id重新映射为词
build_vocab('train.txt')
words = ["铁柱", "坐在", "村内", "的", "小", "路边", "望", "着", "蔚蓝", "的", "天空"]
token_id = [word2idx.get(w, 0) for w in words]
print(' '.join(words)) # 铁柱 坐在 村内 的 小 路边 望 着 蔚蓝 的 天空
print(token_id) # [101, 317, 318, 100, 456, 457, 124, 107, 458, 100, 459]
newwords = [idx2word.get(i, '' ) for i in token_id]
print(newwords) # ['铁柱', '坐在', '村内', '的', '小', '路边', '望', '着', '蔚蓝', '的', '天空']