如何训练大型数据集进行分类
How to train large Dataset for classification
我有一个包含 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 和朴素贝叶斯对我的数据集进行分类。
我想使用的数据集:Link
样本(训练数据集):
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
如何有效地训练这个庞大的数据集?
我这里有一个选项。在我的机器上花了 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())
在加快训练速度之前,我会亲自确保您确实需要这样做。虽然不是您问题的直接答案,但我会尝试提供一个您可能会或可能不会错过的不同角度(很难从您最初的 post 判断)。
举个例子superbly 的实施作为基线。 1.6Mio 训练和 500 个具有 3 个特征的测试样本产生 0.35 的准确度。
使用完全相同的设置,您可以在不损失准确性的情况下使用低至 50k 的训练样本,事实上,准确性会 略微上升 - 可能是因为您过度拟合了许多示例(您可以使用较小的样本量检查此 运行 他的代码)。我很确定在这个阶段使用神经网络会给这个设置带来可怕的准确性(虽然这不是我的观点,但可以调整 SVM 以克服过度拟合)。
您在初始 post 中写道您拥有 55k 个功能(您出于某种原因删除了这些功能?)。这个数字应该与你的训练集大小相关。由于您没有指定功能列表,因此实际上不可能为您提供合适的工作模型或测试我的假设。
但是,我强烈建议您首先减少训练数据,然后查看 a) 您的表现如何以及 b) 何时可能发生过拟合。我还会将测试大小调整为更大的大小。 500-1.6Mio 有点奇怪。 train/test 尝试 80/20%。
第三步检查您的功能列表大小。它能代表您的需求吗?如果该列表中有 unnecessary/duplicate 个特征,您应该考虑修剪。
作为最后的想法,如果你回到更长的训练规模(例如,因为你决定你 确实 实际上需要比现在提供的更多的数据),请考虑是否慢学习确实是一个问题(除了测试你的模型)。许多最先进的分类器都使用 GPU 计算针对 days/weeks 进行了训练。在这种情况下,训练时间并不重要,因为它们只训练一次,并且可能只在 "go online".
时用小批量数据更新
根据关于特征提取的出色建议,您可以使用 scikit 库中的 tfidvectorizer 从推文中提取重要单词。使用默认配置,再加上一个简单的 LogisticRegression,它给了我 0.8 accuracy.Hope 的帮助。
这是一个关于如何使用它来解决你的问题的例子:
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]]
我有一个包含 1600000 条推文的训练数据集。我该如何训练这种庞大的数据。
我已经尝试使用 nltk.NaiveBayesClassifier
进行一些操作。如果我 运行.
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 和朴素贝叶斯对我的数据集进行分类。
我想使用的数据集:Link
样本(训练数据集):
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
如何有效地训练这个庞大的数据集?
我这里有一个选项。在我的机器上花了 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())
在加快训练速度之前,我会亲自确保您确实需要这样做。虽然不是您问题的直接答案,但我会尝试提供一个您可能会或可能不会错过的不同角度(很难从您最初的 post 判断)。
举个例子superbly 的实施作为基线。 1.6Mio 训练和 500 个具有 3 个特征的测试样本产生 0.35 的准确度。
使用完全相同的设置,您可以在不损失准确性的情况下使用低至 50k 的训练样本,事实上,准确性会 略微上升 - 可能是因为您过度拟合了许多示例(您可以使用较小的样本量检查此 运行 他的代码)。我很确定在这个阶段使用神经网络会给这个设置带来可怕的准确性(虽然这不是我的观点,但可以调整 SVM 以克服过度拟合)。
您在初始 post 中写道您拥有 55k 个功能(您出于某种原因删除了这些功能?)。这个数字应该与你的训练集大小相关。由于您没有指定功能列表,因此实际上不可能为您提供合适的工作模型或测试我的假设。
但是,我强烈建议您首先减少训练数据,然后查看 a) 您的表现如何以及 b) 何时可能发生过拟合。我还会将测试大小调整为更大的大小。 500-1.6Mio 有点奇怪。 train/test 尝试 80/20%。 第三步检查您的功能列表大小。它能代表您的需求吗?如果该列表中有 unnecessary/duplicate 个特征,您应该考虑修剪。
作为最后的想法,如果你回到更长的训练规模(例如,因为你决定你 确实 实际上需要比现在提供的更多的数据),请考虑是否慢学习确实是一个问题(除了测试你的模型)。许多最先进的分类器都使用 GPU 计算针对 days/weeks 进行了训练。在这种情况下,训练时间并不重要,因为它们只训练一次,并且可能只在 "go online".
时用小批量数据更新根据关于特征提取的出色建议,您可以使用 scikit 库中的 tfidvectorizer 从推文中提取重要单词。使用默认配置,再加上一个简单的 LogisticRegression,它给了我 0.8 accuracy.Hope 的帮助。 这是一个关于如何使用它来解决你的问题的例子:
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]]