簡體   English   中英

基於 NLTK 的詞干提取和詞形還原

[英]NLTK-based stemming and lemmatization

我正在嘗試使用lemmatizer預處理字符串,然后刪除標點符號和數字。 我正在使用下面的代碼來做到這一點。 我沒有收到任何錯誤,但文本沒有經過適當的預處理。 只有停用詞被刪除,但詞形還原不起作用,標點符號和數字也保留了下來。

from nltk.stem import WordNetLemmatizer
import string
import nltk
tweets = "This is a beautiful day16~. I am; working on an exercise45.^^^45 text34."
lemmatizer = WordNetLemmatizer()
tweets = lemmatizer.lemmatize(tweets)
data=[]
stop_words = set(nltk.corpus.stopwords.words('english'))
words = nltk.word_tokenize(tweets)
words = [i for i in words if i not in stop_words]
data.append(' '.join(words))
corpus = " ".join(str(x) for x in data)
p = string.punctuation
d = string.digits
table = str.maketrans(p, len(p) * " ")
corpus.translate(table)
table = str.maketrans(d, len(d) * " ")
corpus.translate(table)
print(corpus)

我得到的最終輸出是:

This beautiful day16~ . I ; working exercise45.^^^45 text34 .

預期輸出應如下所示:

This beautiful day I work exercise text

不,您當前的方法不起作用,因為您必須一次將一個單詞傳遞給詞形還原器/詞干提取器,否則,這些函數將不知道將您的字符串解釋為一個句子(它們需要單詞)。

import re

__stop_words = set(nltk.corpus.stopwords.words('english'))

def clean(tweet):
    cleaned_tweet = re.sub(r'([^\w\s]|\d)+', '', tweets.lower())
    return ' '.join([lemmatizer.lemmatize(i, 'v') 
                for i in cleaned_tweet.split() if i not in __stop_words])

或者,您可以使用PorterStemmer ,它的作用與詞形還原相同,但沒有上下文。

from nltk.stem.porter import PorterStemmer  
stemmer = PorterStemmer() 

並且,像這樣調用詞干分析器:

stemmer.stem(i)

我認為這就是您要查找的內容,但是在調用 lemmatizer 之前執行此操作,正如評論者所指出的那樣。

>>>import re
>>>s = "This is a beautiful day16~. I am; working on an exercise45.^^^45text34."
>>>s = re.sub(r'[^A-Za-z ]', '', s)
This is a beautiful day I am working on an exercise text

要正確處理推文,您可以使用以下代碼:

import re
import nltk
def process(text, lemmatizer=nltk.stem.wordnet.WordNetLemmatizer()):
""" Normalizes case and handles punctuation
Inputs:
    text: str: raw text
    lemmatizer: an instance of a class implementing the lemmatize() method
                (the default argument is of type nltk.stem.wordnet.WordNetLemmatizer)
Outputs:
    list(str): tokenized text
"""
bcd=[]
pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
text1= text.lower()
text1= re.sub(pattern,"", text1)
text1= text1.replace("'s "," ")
text1= text1.replace("'","")
text1= text1.replace("—", " ")
table= str.maketrans(string.punctuation,32*" ")
text1= text1.translate(table)
geek= nltk.word_tokenize(text1)



abc=nltk.pos_tag(geek)
output = []
for value in abc:
    value = list(value)
    if value[1][0] =="N":
        value[1] = 'n'
    elif value[1][0] =="V":
        value[1] = 'v'
    elif value[1][0] =="J":
        value[1] = 'a'
    elif value[1][0] =="R":
        value[1] = 'r'
    else:
        value[1]='n'
    output.append(value)
abc=output
for value in abc:
    bcd.append(lemmatizer.lemmatize(value[0],pos=value[1]))
return bcd

在這里,我使用了 post_tag(僅 N、V、J、R 並將其余全部轉換為名詞)。 這將返回一個標記化和詞形化的單詞列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM