机器学习/ NLP与关键字搜索将非结构化数据转换为结构化数据

时间:2017-04-30 13:33:38

标签: python machine-learning nlp

我监督一个研究项目,在那里我们汇总有关非洲政治暴力的报纸文章,然后识别和编码事件。我们会记录事件发生的地点和时间,涉及的参与者,遇害人数等。您可以在此处查看数据集:

https://docs.google.com/spreadsheets/d/1_QYl4xhMu5nZVluprOgRs6rUzgkkBemapdsg5lFzKU/pubhtml

这是一个劳动密集型过程,我认为机器学习可能会有所帮助。我正试图找出最好的方法。

我的问题:我最好使用一组关键字来决定如何编写每篇文章的代码吗?即

if "boko haram" in article:
     code Boko Haram

or 

if [list of locations] in article:
    code location

或者我可以使用现有数据集和文章中的文本并应用机器学习来进行特征提取吗?

有些功能很简单:如果文章描述了暴力事件并且提到了Boko Haram,我们会对Boko Haram进行编码。或者如果提到炸弹,我们会对炸弹进行编码。

有些更复杂。为了确定该事件是否是“宗派”,我们寻找引用种族群体之间冲突的暴力事件('富拉尼','伊博'等)

我们根据774个区的列表编码位置。这里的挑战是同一个地方经常有多个拼写。时间也很复杂,因为该事件通常被描述为“上周二”或“周三晚上”。

我之前尝试使用TextBlob的Naive Bayes分类器试图找出位置。我碰到了两个问题。我的程序要么永远不会完成。我假设在两千个500字的文章上执行nlp需要比我的Macbook Air可以处理更多的果汁。另一个是文章文本的编码问题。我希望切换到python 3有助于解决这个问题。

如果我要花一些时间,我会喜欢一些关于最佳路径的建议。如果它确实是机器学习,也许我应该使用除了天真的贝叶斯以外的东西?也许我应该在云中运行这个,所以我有更多的权力?与TextBlob不同的包?

非常感谢指导!

1 个答案:

答案 0 :(得分:1)

自从发布我的初步问题以来,我已经成功地应用了TextBlob中的Naive Bayes和DecisionTree分类器,以及来自Sklearn的朴素贝叶斯和支持向量机。我还应该补充一点,Python3和正确的编码(对于我的数据集' latin1')已经消除了我之前的字符串编码和解码问题。

TextBlob的关键是构建自定义特征提取器:

def simple_define_features(tokens):
    lga_state = pd.read_csv('lgas.csv')

    lga_state = lga_state[['State', 'LGA']]
    states = list(set(lga_state['State']))

    state_lga = {}
    for state in states:
        lgas = lga_state[lga_state['State']==state]
        lga_list = list(lgas['LGA'])
        state_lga[state.strip('State').rstrip()] = lga_list

    features = {}
    for state in list(state_lga.keys()):
        features['count({})'.format(state)] = tokens.count(state)
        features['has({})'.format(state)] = (state in tokens)
    for lga in lga_list:
        features['count({})'.format(lga)] = tokens.count(lga)
        features['has({})'.format(lga)] = (lga in tokens)

    return features

此功能根据一组关键字检查每篇文章,在本例中为位置,并构建一个特征字典。请参阅NLTK手册中功能提取器的工作原理说明:http://www.nltk.org/book/ch06.html

目前,使用下面的功能,我已经能够以75%的准确率来猜测州级别的位置。请记住,我的训练集很小,只有大约4000行。

功能是:

def tb_dt_classifier(json_file, feature_function, test_text, test_label):
    with open(json_file, 'r') as f:
        cl = DecisionTreeClassifier(f, format='json', feature_extractor=feature_function)
    test_text['guess'] = test_text.apply(lambda x: cl.classify(x))
    return test_text['guess']

然而,TextBlob非常慢。

事实证明,Sklearn的速度要快得多。据我所知,差异在于,Sklearn必须将所有东西都转换为前期的向量。在这种情况下,对于标签,我创建了虚拟变量,当有两个以上的变量时,我已经为pd.get_dummies()astype('category').cat.codes的二进制变量做了这些变量。从那里,Sklearn的计数向量化器创建向量。

以下是我一直在使用的功能:

def text_classifier_SVM(df,train_text,train_output, test_text, test_output):
    text_clf = Pipeline([('vect', CountVectorizer()),
                     ('tfidf', TfidfTransformer()),
                     ('clf', SGDClassifier(loss='hinge', penalty='l2',
                                           alpha=1e-3, n_iter=5, random_state=42)),
    ])
    _ = text_clf.fit(df[train_text], df[train_output])
    predicted = text_clf.predict(df[test_text])
    return np.mean(predicted == df[test_output])

我仍然需要做很多调整,但这已经开始返回一些有意义的结果,并且似乎比尝试猜测每个可能的模式并将其构建成一些复杂的关键字搜索要高效得多。