【问题标题】:How to extract rows with only meaningful text in a column如何提取列中只有有意义的文本的行
【发布时间】:2017-05-05 17:10:03
【问题描述】:

我有一个大的 excel 文件,如下所示:

Timestamp       Text                                Work        Id
5/4/16 17:52    rain a lot the packs maybe damage.  Delivery    XYZ
5/4/16 18:29    wh. screen                          Other       ABC
5/4/16 14:54    15107 Lane Pflugerville, 
                TX customer called me and his phone 
                number and my phone numbers were not 
                masked. thank you customer has had a 
                stroke and items were missing from his 
                delivery the cleaning supplies for his 
                wet vacuum steam cleaner.  he needs a 
                call back from customer support     Delivery    YYY
5/6/16 13:05    How will I know if I                Signing up  ASX
5/4/16 23:07    an quality                          Delivery    DFC

我只想在“文本”列上工作,然后消除那些在“文本”列中基本上只有乱码的行(上例中的第 2、4、5 行)。

我只阅读第二列如下:

import xlrd
book = xlrd.open_workbook("excel.xlsx")
sheet = book.sheet_by_index(0)
for row_index in xrange(1, sheet.nrows): # skip heading row
    timestamp, text = sheet.row_values(row_index, end_colx=2)
    text)
    print (text)

如何删除乱码行?我有一个想法,我需要使用 nltk 并拥有一个正语料库(一个没有任何乱码的语料库),一个负语料库(只有乱码文本),并用它训练我的模型。但是我该如何实施呢?请帮忙!!

【问题讨论】:

    标签: python excel nlp nltk


    【解决方案1】:

    您可以使用 nltk 执行以下操作。

    import nltk
    english_words = set(w.lower() for w in nltk.corpus.words.words())
    
    'a' in english_words
    True
    
    'dog' in english_words
    True
    
    'asdasdase' in english_words
    False
    

    如何从字符串中获取 nltk 中的单个单词:

    individual_words_front_string = nltk.word_tokenize('This is my text from text column')
    
    individual_words_front_string
    ['This', 'is,' 'my', 'text', 'from', 'text', 'column']
    

    对于每一行文本列,测试各个单词以查看它们是否在英语词典中。如果它们都是,你知道行文本列我们不是胡言乱语。

    如果您对乱码与非乱码的定义与 nltk 中找到的英文单词不同,您可以使用上述相同的过程,只是使用不同的可接受单词列表。

    如何接受号码和街道地址?

    判断某事物是否为数字的简单方法。

    word = '32423432' 
    word.isdigit()
    True
    
    word = '32423432ds' 
    word.isdigit()
    False
    

    地址更难。你可以在这里找到相关信息:Parsing Addresses,可能还有很多其他地方。当然,如果您可以访问城市、州、道路等的列表,您始终可以使用上述逻辑。

    如果任何一个词是假的,它会失败吗?

    代码由您决定。如果文本中 x% 的单词是错误的,也许您可​​以将某些内容标记为乱码?

    如何判断语法是否正确?

    这是一个更大的话题,更深入的解释可以在以下链接中找到: Checking Grammar。但是上面的答案只会检查单词是否在 nltk 语料库中,而不是句子在语法上是否正确。

    【讨论】:

    • 非常感谢!但是我如何让它接受数字和街道地址?另外,如果整个句子都属于英语单词,除了说一个/两个单词,它会返回 false 吗?
    • 另外,从样本数据(在最后一行)来看,“质量”属于英文单词,但对我们来说这是胡言乱语,因为它没有意义。但是根据您建议的english_words,我认为它会返回true
    • 好问题,你是对的。确定所有句子在句法上是否正确与确定单词是否真实有很大不同。我会更新答案以提供更多信息。
    • 已更新答案以反映 cmets 中的其他问题。
    【解决方案2】:

    从“gibber”中分离出好的文本并不是一件容易的事,尤其是当您处理短信/聊天时(这对我来说就是这样)。

    拼写错误的单词不会使样本无法使用,即使是句法错误的句子也不应该取消整个文本的资格。这是可以用于报纸文本的标准,但不适用于用户生成的原始内容。

    我会注释一个语料库,您可以在其中将好样本与坏样本分开,并在其中训练一个简单的分类器。注释不必费很大力气,因为这些乱码文本比好的文本短,应该是易于识别(至少是一些)。此外,您可以尝试从大约 100 个数据点(50 个好/50 个坏)的语料库大小开始,并在第一个模型或多或少工作时对其进行扩展。

    这是我一直用于文本分类的示例代码。您需要安装 scikit-learn 和 numpy:

    import re
    import random
    import numpy as np
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.linear_model import LogisticRegression
    from sklearn import metrics
    
    # Prepare data
    
    def prepare_data(data):
        """
        data is expected to be a list of tuples of category and texts.
        Returns a tuple of a list of lables and a list of texts
        """
        random.shuffle(data)
        return zip(*data)
    
    # Format training data
    
    training_data = [
        ("good", "rain a lot the packs maybe damage."),
        ("good", "15107 Lane Pflugerville, TX customer called me and his phone number and my phone numbers were not masked. thank you customer has had a stroke and items were missing from his delivery the cleaning supplies for his wet vacuum steam cleaner.  he needs a call back from customer support "),
        ("gibber", "wh. screen"),
        ("gibber", "How will I know if I")
    ]
    training_labels, training_texts = prepare_data(training_data)
    
    
    # Format test set
    test_data = [
        ("gibber", "an quality"),
        ("good", "<datapoint with valid text>",
        # ...
    ]
    test_labels, test_texts = prepare_data(test_data)
    
    
    # Create feature vectors
    
    """
    Convert a collection of text documents to a matrix of token counts.
    See: http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html
    """
    vectorizer = CountVectorizer()
    X = vectorizer.fit_transform(training_texts)
    y = training_labels
    
    
    # Train the classifier
    
    clf = LogisticRegression()
    clf.fit(X, y)
    
    
    # Test performance
    
    X_test = vectorizer.transform(test_texts)
    y_test = test_labels
    
    # Generates a list of labels corresponding to the samples
    test_predictions = clf.predict(X_test)
    
    # Convert back to the usual format
    annotated_test_data = list(zip(test_predictions, test_texts))
    
    # evaluate predictions
    y_test = np.array(test_labels)
    print(metrics.classification_report(y_test, test_predictions))
    print("Accuracy: %0.4f" % metrics.accuracy_score(y_test, test_predictions))
    
    # predict labels for unknown texts
    data = ["text1", "text2",]
    # Important: use the same vectorizer you used for the training.
    # When saving the model (e.g. via pickle) always serialize
    # classifier & vectorizer
    X = vectorizer.transform(data)
    # Now predict the labels for the texts in 'data'
    labels = clf.predict(X)
    # And put them back together 
    result = list(zip(labels, data))
    # result = [("good", "text1"), ("gibber", "text2")]
    

    简单介绍一下它的工作原理:计数向量器对文本进行标记并创建包含语料库中所有单词计数的向量。基于这些向量,分类器尝试识别模式以区分这两个类别。只有少数不常见(b/c 拼写错误)单词的文本宁愿属于“gibber”类别,而包含很多常见句子典型单词的文本(想想这里的所有停用词:“我', 'you', 'is'... ) 更容易成为好文本。

    如果此方法适合您,您还应该尝试其他分类器并使用第一个模型来半自动注释更大的训练语料库。

    【讨论】:

    • “注释不必费很大力气,因为这些乱七八糟的文本比好的文本要短,而且应该很容易识别”。上面的例子“下雨很多包可能会损坏”有效文本,“我怎么知道我”无效文本。即使在这个小样本中,区分这两者也并非易事。基于将无效标记为主要具有“短文本”的字段的监督学习算法将非常容易过度拟合。我同意你的整体方法,但我认为实现它所涉及的工作量将相当大/困难。
    • 试图理解这段代码。 test_data = [ #TODO ... 那么在这里我需要做什么?会在此处手动为测试数据添加标签吗?
    • @Arman 添加与训练集中格式相同的数据点。分类器的性能将在这些示例上进行评估,因此重要的是它们不能与训练数据重复。
    • @user2263572 我同意在这种情况下很有可能过度拟合。但是,当我遇到这样的问题时,我会注释一个小型语料库(在这种情况下应该不会花费很长时间),以查看分类器是否可以从数据中获取任何意义。如果失败了,是时候寻找更复杂的结果了。
    • 嗯,我明白了。但是,这样做的全部目的不应该是它应该能够准确地预测哪些文本是好的,哪些是坏的吗?如果我自己在测试文本中添加标签,那么模型将如何告诉我文本的好坏?
    猜你喜欢
    • 1970-01-01
    • 2011-04-27
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多