文本预处理:数据清洗与标准化
在自然语言处理(NLP)的旅程中,文本预处理是至关重要的第一步。原始文本数据往往包含噪声、不一致性以及各种格式问题,直接影响后续模型的性能。文本预处理旨在将文本转化为统一、规范的格式,便于计算机理解和处理。
1. 文本清洗
文本清洗涉及去除无关字符、标点符号、数字、HTML标签等。例如,使用Python的re
库进行正则表达式匹配,可以有效移除不需要的字符。
import redef clean_text(text):# 移除HTML标签text = re.sub(r'<.*?>', '', text)# 移除非字母字符text = re.sub(r'[^a-zA-Z\s]', '', text)# 转换为小写text = text.lower()return textsample_text = "<p>Hello, World! 123</p>"
cleaned_text = clean_text(sample_text)
print(cleaned_text) # 输出: hello world
2. 分词与词干提取
分词是将连续文本分割成单词或术语的过程。对于英文,可以使用nltk
库的word_tokenize
函数。词干提取则是将词汇还原为其基本形式,如将“running”转换为“run”。
from nltk.tokenize import word_tokenize
from nltk.stem import PorterStemmerdef tokenize_and_stem(text):tokens = word_tokenize(text)stemmer = PorterStemmer()stems = [stemmer.stem(token) for token in tokens]return stemstokens = tokenize_and_stem("running quickly")
print(tokens) # 输出: ['run', 'quickli']
3. 停用词过滤
停用词是指在文本处理中常被忽略的高频词汇,如“the”、“is”等。过滤停用词可以减少数据维度,提高处理效率。
from nltk.corpus import stopwordsdef remove_stopwords(tokens):stop_words = set(stopwords.words('english'))filtered_tokens = [token for token in tokens if token not in stop_words]return filtered_tokensfiltered_tokens = remove_stopwords(tokens)
print(filtered_tokens) # 输出: ['run', 'quickli']
词向量表示:从文本到数值空间
为了使计算机能够处理文本数据,需要将文本转换为数值形式。词向量表示是一种将词语映射到多维空间的方法,其中每个词由一个实数向量表示,向量之间的距离反映了词之间的语义相似度。
1. 词袋模型(Bag of Words)
词袋模型是一种简单且广泛使用的文本表示方法,它忽略了文本中的顺序和语法结构,仅考虑词汇的出现频率。
from sklearn.feature_extraction.text import CountVectorizerdocuments = ["I love programming", "Python is awesome"]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(documents)
print(X.toarray())
# 输出: [[0 1 1] [1 0 1]] 对应词汇表 ['awesome', 'programming', 'python']
2. TF-IDF加权
TF-IDF(Term Frequency-Inverse Document Frequency)是一种统计方法,用于评估一个词语对于一个文档集或一个语料库中的其中一份文档的重要程度。
from sklearn.feature_extraction.text import TfidfVectorizertfidf_vectorizer = TfidfVectorizer()
X_tfidf = tfidf_vectorizer.fit_transform(documents)
print(X_tfidf.toarray())
# 输出: TF-IDF权重矩阵,反映每个词在文档中的重要性
3. Word2Vec与GloVe
Word2Vec和GloVe是两种流行的词嵌入技术,它们能够捕捉词语之间的语义关系。Word2Vec通过神经网络训练得到词向量,而GloVe则基于全局词共现统计信息。
from gensim.models import Word2Vecsentences = [["i", "love", "programming"], ["python", "is", "awesome"]]
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
word_vector = model.wv['programming']
print(word_vector) # 输出: 100维的词向量
文本分类:情感分析实战
文本分类是NLP中的一个重要任务,它涉及将文本分配到预定义的类别中。情感分析作为文本分类的一个典型应用,旨在判断文本的情感倾向(正面、负面或中性)。
1. 数据集准备与探索
以IMDb电影评论数据集为例,该数据集包含大量带标签的电影评论,适合用于训练情感分析模型。
import pandas as pd# 假设已下载并解压IMDb数据集
df = pd.read_csv('imdb_reviews.csv')
print(df.head())
# 输出: 包含评论文本和相应情感标签的数据框
2. 数据预处理与特征提取
对评论文本进行预处理,包括清洗、分词、去除停用词等步骤,然后使用TF-IDF向量化文本。
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer# 数据清洗函数(前文已定义)
df['cleaned_text'] = df['review'].apply(clean_text)# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(df['cleaned_text'], df['sentiment'], test_size=0.2, random_state=42)# 特征提取
tfidf = TfidfVectorizer(max_features=5000)
X_train_tfidf = tfidf.fit_transform(X_train)
X_test_tfidf = tfidf.transform(X_test)
3. 模型训练与评估
使用逻辑回归模型进行训练,并评估其在测试集上的表现。
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report# 模型训练
model = LogisticRegression()
model.fit(X_train_tfidf, y_train)# 预测与评估
y_pred = model.predict(X_test_tfidf)
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')
print(classification_report(y_test, y_pred))
命名实体识别(NER):提取关键信息
命名实体识别(NER)是NLP中的一项任务,旨在从文本中识别出具有特定意义的实体,如人名、地名、组织机构名等。这对于信息提取、知识图谱构建等应用至关重要。
1. 使用预训练模型进行NER
利用spaCy
库提供的预训练模型,可以方便地进行命名实体识别。
import spacy# 加载预训练模型
nlp = spacy.load('en_core_web_sm')# 处理文本
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
for ent in doc.ents:print(ent.text, ent.start_char, ent.end_char, ent.label_)
# 输出: Apple 0 5 ORG, U.K. 25 28 GPE, $1 billion 36 46 MONEY
2. 自定义NER模型训练
对于特定领域的NER任务,可能需要训练自定义模型。以下是使用spaCy
进行自定义NER的示例。
from spacy.training import Example
from spacy.util import minibatch, compounding# 准备训练数据(标注的实体)
TRAINING_DATA = [("Barack Obama was born in Hawaii.", {'entities': [(0, 12, 'PERSON')]}),# 更多标注数据...
]# 创建空白模型
nlp = spacy.blank('en')
ner = nlp.create_pipe('ner')
nlp.add_pipe(ner)# 添加标注数据到模型
for _, annotations in TRAINING_DATA:for ent in annotations['entities']:ner.add_label(ent[2])# 训练模型
optimizer = nlp.begin_training()
for itn in range(10):random.shuffle(TRAINING_DATA)losses = {}for text, annotations in TRAINING_DATA:doc = nlp.make_doc(text)example = Example.from_dict(doc, annotations)nlp.update([example], drop=0.5)print(f'Loss after iteration {itn}: {losses}')