自从我发了我的初始问题,我已经成功地应用了TextBlob中的朴素贝叶斯和决策树分类器,以及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])
我还有很多微调需要做,但这已经开始返回一些有意义的结果,并且似乎比尝试猜测每个可能的模式并将其构建成一些复杂的关键字搜索要高效得多。