【问题标题】:Text Pre-processing with NLTK使用 NLTK 进行文本预处理
【发布时间】:2017-01-20 00:58:22
【问题描述】:

我正在练习使用 NLTK 从原始推文中删除某些功能,然后希望删除(对我而言)不相关的推文(例如空推文或单字推文)。但是,似乎某些单字推文没有被删除。我还面临无法删除句子开头或结尾的任何停用词的问题。

有什么建议吗?目前,我希望将一个句子作为输出而不是标记化的单词列表传回。

欢迎对改进代码(处理时间、优雅性)提出任何其他意见。

import string
import numpy as np
import nltk
from nltk.corpus import stopwords

cache_english_stopwords=stopwords.words('english')
cache_en_tweet_stopwords=stopwords.words('english_tweet')

# For clarity, df is a pandas dataframe with a column['text'] together with other headers.

def tweet_clean(df):
    temp_df = df.copy()
    # Remove hyperlinks
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('https?:\/\/.*\/\w*', '', regex=True)
    # Remove hashtags
    # temp_df.loc[:,"text"]=temp_df.loc[:,"text"].replace('#\w*', '', regex=True)
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('#', ' ', regex=True)
    # Remove citations
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('\@\w*', '', regex=True)
    # Remove tickers
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('\$\w*', '', regex=True)
    # Remove punctuation
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('[' + string.punctuation + ']+', '', regex=True)
    # Remove stopwords
    for tweet in temp_df.loc[:,"text"]:
        tweet_tokenized=nltk.word_tokenize(tweet)
        for w in tweet_tokenized:
            if (w.lower() in cache_english_stopwords) | (w.lower() in cache_en_tweet_stopwords):
                temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('[\W*\s?\n?]'+w+'[\W*\s?]', ' ', regex=True)
                #print("w in stopword")
    # Remove quotes
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('\&*[amp]*\;|gt+', '', regex=True)
    # Remove RT
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('\s+rt\s+', '', regex=True)
    # Remove linebreak, tab, return
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('[\n\t\r]+', ' ', regex=True)
    # Remove via with blank
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('via+\s', '', regex=True)
    # Remove multiple whitespace
    temp_df.loc[:, "text"] = temp_df.loc[:, "text"].replace('\s+\s+', ' ', regex=True)
    # Remove single word sentence
    for tweet_sw in temp_df.loc[:, "text"]:
        tweet_sw_tokenized = nltk.word_tokenize(tweet_sw)
        if len(tweet_sw_tokenized) <= 1:
            temp_df.loc["text"] = np.nan
    # Remove empty rows
    temp_df.loc[(temp_df["text"] == '') | (temp_df['text'] == ' ')] = np.nan
    temp_df = temp_df.dropna()
    return temp_df

【问题讨论】:

  • 请编辑 您的问题 以解释 df 是一个熊猫数据框(我从您的 cmets 收集)。理想情况下,您应该添加几行代码,以便在有人想为您提供更好的答案时运行完整的 sn-p。如果您认为自己的自我回答已经解决了您的问题,您最终应该将其标记为“已接受”。 (但首先我会解决您的问题,并等待更好的答案)。

标签: python twitter nltk


【解决方案1】:

什么是df?推文列表? 您可能应该考虑一个接一个地清理推文,而不是作为推文列表。有一个函数tweet_cleaner(single_tweet)会更容易。

nltk 提供TweetTokenizer 来清理推文。

"re" package 为使用正则表达式提供了很好的解决方案。

我建议您创建一个变量以便更轻松地使用temp_df.loc[:, "text"]

[此处] (Stopword removal with NLTK) 描述了删除句子中的停用词: clean_wordlist = [i for i in sentence.lower().split() if i not in stopwords]

如果你想使用正则表达式(带有 re 包),你可以

  1. 创建一个由所有停用词组成的正则表达式模式(在 tweet_clean 函数之外): stop_pattern = re.compile('|'.join(stoplist)(?siu))
    (?siu) 用于多行、忽略大小写、unicode

  2. 并使用此模式清理任何字符串 clean_string = stop_pattern.sub('', input_string)

(如果不需要单独的停止列表,您可以连接 2 个停止列表)

要删除 1 个单词的推文,您只能保留最长超过 1 个单词的推文:
if len(tweet_sw_tokenized) >= 1: kept_ones.append(tweet_sw)

【讨论】:

  • 从我乱七八糟的代码中复制过来的。 df 是一个 pandas.dataframe,其中有一个“文本”列。最好为不同类型的推文设置单独的停止列表,这样我就不会弄乱原始的 nltk 停止列表。
【解决方案2】:

在 mquantin 的建议下,我修改了我的代码,将推文单独清理为一个句子。这是我的业余尝试,我相信它涵盖了大多数情况(如果您遇到任何其他需要清理的情况,请告诉我):

import string
import re
from nltk.corpus import stopwords
from nltk.tokenize import TweetTokenizer


cache_english_stopwords=stopwords.words('english')



def tweet_clean(tweet):
    # Remove tickers
    sent_no_tickers=re.sub(r'\$\w*','',tweet)
    print('No tickers:')
    print(sent_no_tickers)
    tw_tknzr=TweetTokenizer(strip_handles=True, reduce_len=True)
    temp_tw_list = tw_tknzr.tokenize(sent_no_tickers)
    print('Temp_list:')
    print(temp_tw_list)
    # Remove stopwords
    list_no_stopwords=[i for i in temp_tw_list if i.lower() not in     cache_english_stopwords]
    print('No Stopwords:')
    print(list_no_stopwords)
    # Remove hyperlinks
    list_no_hyperlinks=[re.sub(r'https?:\/\/.*\/\w*','',i) for i in list_no_stopwords]
    print('No hyperlinks:')
    print(list_no_hyperlinks)
    # Remove hashtags
    list_no_hashtags=[re.sub(r'#', '', i) for i in list_no_hyperlinks]
    print('No hashtags:')
    print(list_no_hashtags)
    # Remove Punctuation and split 's, 't, 've with a space for filter
    list_no_punctuation=[re.sub(r'['+string.punctuation+']+', ' ', i) for i in list_no_hashtags]
    print('No punctuation:')
    print(list_no_punctuation)
    # Remove multiple whitespace
    new_sent = ' '.join(list_no_punctuation)
    # Remove any words with 2 or fewer letters
    filtered_list = tw_tknzr.tokenize(new_sent)
    list_filtered = [re.sub(r'^\w\w?$', '', i) for i in filtered_list]
    print('Clean list of words:')
    print(list_filtered)
    filtered_sent =' '.join(list_filtered)
    clean_sent=re.sub(r'\s\s+', ' ', filtered_sent)
    #Remove any whitespace at the front of the sentence
    clean_sent=clean_sent.lstrip(' ')
    print('Clean sentence:')
    print(clean_sent)

s0='    RT @Amila #Test\nTom\'s newly listed Co. &amp; Mary\'s unlisted     Group to supply tech for nlTK.\nh.. $TSLA $AAPL https:// t.co/x34afsfQsh'
tweet_clean(s0)

【讨论】:

  • 将cache_english_stopwords 更改为一组。它将以令人难以置信的因素加速您的代码。
  • 如何读取包含多行推文、project3.txt 或 .json 文件的文件
  • 我在玩这个代码,我注意到部分 URL 保留在最后一条推文中。我做了一些改变来解决这个问题,也改进了结构:pastebin.com/iHw1CHXM
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
相关资源
最近更新 更多