2017-05-05 53 views
0

我有一個大的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一起工作,並有一個積極的語料庫(一個沒有任何亂碼),一個負面的語料庫(只有亂碼的文本),並用它訓練我的模型。但我該如何去實施它?請幫忙!!

回答

0

您可以使用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,可能還有很多其他地方。當然,如果您有權訪問城市,州,道路等列表,則可以始終使用上述邏輯。

如果任何一個單詞是False,它會失敗嗎?

這是您決定的代碼。如果文本中x%的單詞是錯誤的,也許你可以標記爲亂碼?

如何確定語法是否正確?

這是一個較大的話題,更深入的解釋可以在以下鏈接找到: Checking Grammar。但是,上面的答案只是檢查單詞是否在nltk語料庫中,而不是這個句子在語法上是否正確。

+0

非常感謝!但是,我將如何讓它接受號碼和街道地址?另外,如果整個句子在英語單詞下面,除了說一個/兩個單詞,它會返回錯誤嗎? – Arman

+0

此外,從樣本數據(最後一行)中,「質量」屬於英文單詞,但對我們來說,它是無用的,因爲它沒有意義。但是用你的建議english_words,我認爲它會返回true – Arman

+0

好問題,你是對的。確定所有句子是否在句法上是正確的與確定單詞是否是真實的非常不同。我會更新答案以提供更多信息。 – user2263572

0

將好文本與'gibber'分開並不是一項簡單的任務,尤其是在處理文本消息/聊天時(這就是我看起來的樣子)。

拼寫錯誤的單詞不會使樣本不可用,甚至語法錯誤的句子也不應使整個文本不合格。這是您可以用於報紙文本的標準,但不適用於原始的,用戶生成的內容。

我會註釋一個語料庫,您可以將好樣本與壞樣本分開,並在其上訓練一個簡單的分類器。註釋不一定非常費功夫,因爲這些亂碼文本比好的文本短,應該很容易識別(至少有一些)。此外,您可以嘗試從大約100個數據點(50個好/ 50個壞點)的語料庫開始,並在第一個模型或多或少工作時擴展它。

這是我總是用於文本分類的示例代碼。你需要安裝scikit學習和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'類別中,而文本中含有大量常見句子的典型單詞(想想這裏的所有停用詞:'I ','你','是'...)更容易成爲一個好文本。

如果此方法適用於您,您還應該嘗試其他分類器並使用第一個模型半自動註釋更大的訓練語料庫。

+0

「註釋不一定非常努力,因爲這些亂碼文本比較好的文本短,應該很容易識別」。上面的例子「下雨很多包可能會損壞」有效的文本,「我怎麼知道我是否」無效的文本。即使在這個小樣本中,區分這兩者也不是微不足道的。基於標籤invalids作爲主要是「短文本」的領域的監督學習算法將非常容易過度擬合。我同意你的總體方法,但我認爲牽涉其中的努力量相當大/困難。 – user2263572

+0

試圖理解這段代碼。 test_data = [#TODO ...那麼在這裏我需要做什麼?將在這裏手動添加標籤到測試數據? – Arman

+0

@Arman以與訓練集中相同的格式添加數據點。分類器的性能將在這些示例中進行評估,因此重要的是它們不會與訓練數據重複。 – jgontrum

相關問題