Corpus
创建你自己的 corpus 还是使用默认或预先训练的 corpus 取决于几个因素,包括您的特定用例、数据的性质以及手头的任务。这里有一个详细的细分,可以帮助您决定何时创建自己的语料库,还是使用预先训练的嵌入或模型:
像 Word2Vec、GloVe、FastText 这样的预训练模型和像基于 transformer 的BERT或GPT都是在大规模的多样化的文本数据集,如谷歌新闻、维基百科、普通爬行和图书语料库,这些模型已经捕获了大量关于语言的一般知识。
When to Use Default/Pre-Trained Models:
通用任务:如果您的任务涉及通用语言理解,例如情感分析、文本分类或针对不同主题的主题建模,则预训练的嵌入就足够了。
特定领域:如果您的任务涉及特定术语、俚语、行话或行业特定词汇(例如,医疗报告、法律文档、技术手册),预训练的模型可能无法很好地捕捉到这一点。在你自己的语料库上训练有助于模型理解这些细微差别。
快速部署:使用预训练模型可以节省时间和资源,因为您不需要从头开始训练自己的单词嵌入。
强泛化:预训练模型是通用的,具有很强的泛化能力,在广泛的NLP任务中表现良好,即使不是专门针对您的领域定制的。
自定义需求:当您需要控制训练过程时(例如,调整超参数、调整标记化),创建自己的语料库为您提供了灵活性。
预训练模型的性能不佳:如果预训练的嵌入在您的特定领域任务中表现不佳,从头开始训练模型或在自定义语料库上进行微调可以改善结果。
等等...
这里我推荐使用pre-trained model, then fine-tune the pre-trained model on your own corpus. This approach combines the advantages of general knowledge form pre-trained models with domain-specific customization. 可以理解为transfer learning。
在创建corpus 之前,最好对数据进行下预处理,例如 lowercase, remove stopwords, etc. 这样做可以减少噪声(Noise Reduction), 还可以降低维数, 让数据更加规范化和标准化等等。
在执行文本预处理时,去除停用词、规范化大小写以及词形还原等步骤能够显著提高后续文本分析模型的性能。尤其在构建单词嵌入或处理自然语言任务时,减少数据中的噪声至关重要。下面的代码展示了一个文本预处理函数,它使用NLTK库来处理文本。该函数首先将输入的文本进行标记化,然后移除标点符号和停用词,最后通过词形还原将单词还原至其基本形式。此步骤不仅能提高模型的准确性,还能减少数据维度,为后续任务如词嵌入生成打下基础。
import nltkfrom nltk.corpus import stopwordsfrom nltk.tokenize import word_tokenizefrom nltk.stem import WordNetLemmatizernltk.download('stopwords')def preprocess_text(text):tokens = word_tokenize(text)tokens = [word.lower() for word in tokens]tokens = [word for word in tokens if word.isalnum()]# remove stop wordsstop_words = set(stopwords.words('english'))tokens = [word for word in tokens if word not in stop_words]# Lemmatizelemmatizer = WordNetLemmatizer()tokens = [lemmatizer.lemmatize(word) for word in tokens]return ' '.join(tokens)
Let's start introducing these methods:
One-hot Encoding
from tensorflow.keras.preprocessing.text import one_hotfrom tensorflow.keras.preprocessing.sequence import pad_sequencesdocuments = ["The quick brown fox jumps over the lazy dog","A journey of a thousand miles begins with a single step","To be or not to be that is the question"]vocab_size=50integer_encoded=[]for i,doc in enumerate(documents):integer_encoded.append(one_hot(doc,50))print("The encoding for text",i+1," is : ",one_hot(doc,50))
# length of maximum documentmaxlen = max([len(word_tokenize(text)) for text in documents])maxlen# OUTPUT11
# To create embeddings, all documents must have the same length. hence we can pad to ensure uniformity.pad_corp = pad_sequences(integer_encoded, maxlen=maxlen,padding='post',value=0.0)print("No of padded documents: ",len(pad_corp))# OUTPUTNo of padded documents:3
for i,doc in enumerate(pad_corp): print("The padded encoding for text",i+1," is : ",doc)TF-IDF (Term Frequency-Inverse Document Frequency)
TF-IDF是一种词袋方法,不捕获上下文或语义, 基于术语频率和文档频率计算权重,因此消除无信息的单词和标准化术语(通过词法化)有助于通过关注重要的标记使结果更有意义。删除停用词、标点符号和执行词法化特别有用。预处理将减少噪声并帮助识别有意义的术语。
from sklearn.feature_extraction.text import TfidfVectorizerpreprocessed_text = [preprocess_text(doc) for doc in documents]tfidf = TfidfVectorizer()tfidf_matrix = tfidf.fit_transform(preprocessed_text)print("Vocabulary:", tfidf.vocabulary_)tfidf_matrix.toarray()
Word2Vec
Word2Vec是一个上下文嵌入模型,它根据单词在文本中的共现来学习单词关系。因此,该模型可以捕捉单词之间的语义和关系,而无需大量预处理,保留停用词和其他形式的单词(如“running”和“run”)可以为模型提供更丰富的上下文。
Tokenization and lowercasing are still useful. Stopword removal and lemmatization are optional since Word2Vec can learn useful patterns even from stopwords, as context matters here.
from gensim.models import Word2Vecfrom nltk.tokenize import word_tokenizeimport numpy as nptokenized_docs = [word_tokenize(doc.lower()) for doc in documents]w2v_model = Word2Vec(sentences=tokenized_docs, vector_size=100, window=5, min_count=1, workers=4)def get_sentence_embedding(sentence, model):words = word_tokenize(sentence.lower())word_vectors = [model.wv[word] for word in words if word in model.wv]return np.mean(word_vectors, axis=0) if word_vectors else np.zeros(model.vector_size)print("Word2Vec Sentence Embeddings:")for doc in documents:sentence_embedding = get_sentence_embedding(doc, w2v_model)print(f"Sentence: {doc}.\n Embedding: {sentence_embedding}")
FastText
FastText是脸书人工智能开发的一种单词嵌入方法,它通过考虑子单词信息来扩展Word2Vec。它将每个单词表示为一个字符n元语法包,这使得它在处理罕见单词、拼写错误和形态复杂的语言方面更加强大。
需要的预处理不多,和 Word2Vec 很像。Works on subwords, so handles rare/misspelled words well.
from gensim.models import FastTextfasttext_model = FastText(sentences=tokenized_docs, vector_size=100, window=5, min_count=1, workers=4)def get_sentence_embedding_fasttext(sentence, model):words = word_tokenize(sentence.lower())word_vectors = [model.wv[word] for word in words if word in model.wv]return np.mean(word_vectors, axis=0) if word_vectors else np.zeros(model.vector_size)print("FastText Sentence Embeddings:")for doc in documents:sentence_embedding = get_sentence_embedding_fasttext(doc, fasttext_model)print(f"Sentence: {doc}. \nEmbedding: {sentence_embedding}")
Transformer-Based Embeddings
Transformer 依赖于理解单词的顺序和上下文。过多的预处理,如停用词删除或词法化,会扭曲上下文并降低模型捕捉语言细微差别的能力。Minimal Preprocessing is needed or often not recommended. Transformer models come with tokenizers that are specialized to break down text into subword units or tokens in a way that optimally aligns with the model's architecture.
from transformers import BertTokenizer, BertModelimport torch# Load pre-trained BERT tokenizer and modeltokenizer = BertTokenizer.from_pretrained('bert-base-uncased')model = BertModel.from_pretrained('bert-base-uncased')def get_sentence_embedding_bert(sentence, model, tokenizer):inputs = tokenizer(sentence, return_tensors='pt')outputs = model(**inputs)# Get sentence embedding by averaging token embeddingssentence_embedding = torch.mean(outputs.last_hidden_state, dim=1)return sentence_embedding.squeeze().detach().numpy()print("BERT Sentence Embeddings:")for doc in documents:sentence_embedding = get_sentence_embedding_bert(doc, model, tokenizer)print(f"Sentence: {doc}. \nEmbedding: {sentence_embedding}")
Conclusion
本文主要介绍了不同的 Word Embedding,并讨论了在创建和使用语料库时的考虑因素。文章提到可以选择使用预训练的模型(如Word2Vec、GloVe、FastText 和基于 Transformer 的模型如 BERT),或者根据具体任务需求创建自定义语料库。每种选择都有其优点,取决于任务的通用性或领域特异性。
在处理文本数据时,可以进行基础的文本预处理,如将文本转为小写、去除停用词、词形还原等操作,这些步骤有助于减少数据噪声,提高模型的表现。此外,预训练模型的使用可以帮助快速部署NLP任务,尤其是在面对特定领域或行业术语时,选择合适的模型进行微调也是提高效果的有效途径。
