文本預處理:數據清洗與標準化
在自然語言處理(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}')