6

我有一个包含 1600000 条推文的训练数据集。我该如何训练这种类型的海量数据。

我尝试过使用nltk.NaiveBayesClassifier. 如果我跑步,需要5天以上的时间来训练。

def extract_features(tweet):

    tweet_words = set(tweet)
    features = {}
    for word in featureList:
        features['contains(%s)' % word] = (word in tweet_words)

    return features


training_set = nltk.classify.util.apply_features(extract_features, tweets)

NBClassifier = nltk.NaiveBayesClassifier.train(training_set)  # This takes lots of time  

我应该怎么办?

我需要使用 SVM 和朴素贝叶斯对我的数据集进行分类。

我想使用的数据集:链接

样本(训练数据集):

Label     Tweet
0         url aww bummer you shoulda got david carr third day
4         thankyou for your reply are you coming england again anytime soon

样本(测试数据集):

Label     Tweet
4         love lebron url
0         lebron beast but still cheering the til the end
^
I have to predict Label 0/4 only

如何有效地训练这个庞大的数据集?

4

3 回答 3

4

按照关于特征提取的出色建议,您可以使用 scikit 库中的 tfidvectorizer 从推文中提取重要单词。使用默认配置,再加上一个简单的 LogisticRegression,它给了我 0.8 的准确度。希望有帮助。这是一个关于如何为您解决问题的示例:

    train_df_raw = pd.read_csv('train.csv',header=None, names=['label','tweet'])
test_df_raw = pd.read_csv('test.csv',header=None, names=['label','tweet'])
train_df_raw =  train_df_raw[train_df_raw['tweet'].notnull()]
test_df_raw =  test_df_raw[test_df_raw['tweet'].notnull()]
test_df_raw =  test_df_raw[test_df_raw['label']!=2]

y_train = [x if x==0 else 1 for x in train_df_raw['label'].tolist()]
y_test = [x if x==0 else 1 for x in test_df_raw['label'].tolist()]
X_train = train_df_raw['tweet'].tolist()
X_test = test_df_raw['tweet'].tolist()

print('At vectorizer')
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train)
print('At vectorizer for test data')
X_test = vectorizer.transform(X_test)

print('at Classifier')
classifier = LogisticRegression()
classifier.fit(X_train, y_train)

predictions = classifier.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, predictions)

confusion_matrix = confusion_matrix(y_test, predictions)
print(confusion_matrix)

Accuracy: 0.8
[[135  42]
 [ 30 153]]
于 2015-02-01T21:11:47.787 回答
4

在加快培训速度之前,我会亲自确保您确实需要这样做。虽然不是对您的问题的直接回答,但我会尝试提供一个您可能会或可能不会错过的不同角度(很难从您的初始帖子中看出)。

以例如精湛的实施作为基线。1.6Mio 训练和 500 个具有 3 个特征的测试样本产生 0.35 的准确度。

使用完全相同的设置,您可以低至 50k 训练样本而不会损失准确性,实际上准确度会略有上升- 可能是因为您过度拟合了这么多示例(您可以使用较小的样本大小运行他的代码来检查这个)。我很确定在这个阶段使用神经网络会在这个设置中提供可怕的准确性(SVM 可以稍微调整以克服过度拟合,尽管这不是我的观点)。

您在最初的帖子中写道,您有 55k 个功能(您出于某种原因删除了这些功能?)。这个数字应该与您的训练集大小相关。由于您没有指定功能列表,因此实际上不可能为您提供适当的工作模型或测试我的假设。

但是,我强烈建议您首先减少训练数据,并查看 a)您的表现如何以及 b)在什么时候可能发生过度拟合。我还会将测试大小调整为更大的大小。500-1.6Mio 是一种奇怪的组合拆分。尝试 80/20% 进行训练/测试。作为第三步,检查您的功能列表大小。它是否代表了您的需求?如果该列表中有不必要/重复的功能,您应该考虑修剪。

作为最后的想法,如果你回到更长的训练规模(例如,因为你决定你确实需要比现在提供的更多的数据),请考虑慢学习是否真的是一个问题(除了测试你的模型)。许多最先进的分类器使用 GPU 计算训练数天/数周。在这种情况下,训练时间无关紧要,因为它们只接受过一次训练,并且可能只在“上线”时使用小批量数据进行更新。

于 2015-02-01T15:10:08.200 回答
3

我在这里有一个选择。在我的机器上花了 3 分钟(我真的应该买一个新的:P)。

macbook 2006
2 GHz Intel Core 2 Duo
2 GB DDR2 SDRAM

达到的精度为:0.355421686747

我敢肯定,如果您调整向量机,您可以获得更好的结果。

首先,我更改了 csv 文件的格式,以便更容易导入。我只是用逗号替换了第一个空格,它可以在导入期间用作分隔符。

cat testing.csv | sed 's/\ /,/' > test.csv
cat training.csv | sed 's/\ /,/' > train.csv

在 python 中,我使用 pandas 读取 csv 文件和列表理解来提取特征。这比 for 循环快得多。之后我用 sklearn 训练了一个支持向量机。

import pandas
from sklearn import svm
from sklearn.metrics import accuracy_score

featureList = ['obama','usa','bieber']

train_df = pandas.read_csv('train.csv',sep=',',dtype={'label':int, 'tweet':str})
test_df = pandas.read_csv('test.csv',sep=',',dtype={'label':int, 'tweet':str})

train_features = [[w in str(tweet) for w in featureList] for tweet in train_df.values[:,1]]
test_features = [[w in str(tweet) for w in featureList] for tweet in test_df.values[:,1]]
train_labels = train_df.values[:,0]
test_labels = test_df.values[:,0]

clf = svm.SVC(max_iter=1000)
clf.fit(train_features, train_labels)
prediction = clf.predict(test_features)

print 'accuracy: ',accuracy_score(test_labels.tolist(), prediction.tolist())
于 2015-01-31T19:09:28.080 回答