【问题标题】:How to train large Dataset for classification如何训练大型数据集进行分类
【发布时间】:2015-03-13 06:55:06
【问题描述】:

我有一个包含 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

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

【问题讨论】:

  • 使用scikit-learn 并试用panda。 160万不算多。鉴于词汇量约为 100 万。并删除单例
  • 您也可以尝试dimension reduction 来捕获数据方差的高百分比。不确定它对于像这样的大型稀疏特征向量的效果如何。
  • 您能否将数据发布到 gdrive 上的某个地方或其他地方,然后我们可以尝试为您找到解决方案。
  • 您要预测哪些类?和推文开头的数字有关系吗?
  • 是否一定要使用朴素贝叶斯,还是只要训练好的模型足够准确就可以了?

标签: python classification nltk svm naivebayes


【解决方案1】:

按照关于特征提取的出色建议,您可以使用 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]]

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 如果忽略标签为 2 的测试推文,准确度是多少?
    • 谢谢,我会尝试将 80/20% 用于训练/测试,并会通知您。
    • 如果我这样做,它会从 0.36 上升到 0.5(测试大小 369,训练 50k,3 个特征,SVM,0 类和 4 类拆分为 50/50)。使用 6k 的训练大小,它仍然是 0.5,表明我谈到的问题。您还应该绝对“测试”您的训练数据,看看您在哪个点达到 100% 或误差收敛 - 在该点停止训练,因为任何更多的训练都会产生相同或更差的结果。
    • 您是如何选择这 3 个功能的..?我认为所有独特的词都会成为特征
    • 能否告诉我,如果将训练数据集 80/20% 分成训练集和测试集,准确率会是多少?
    【解决方案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())
    

    【讨论】:

    • 这很有帮助。我需要调整我的训练和测试数据集
    • featureList = ['obama','usa','bieber'] 为什么有这三个功能?我尝试了所有独特的词。但它给出了内存错误..任何技术?
    • 这三个功能只是我对测试的猜测。我看到这三个词出现在一些推文中。我以为你有自己的清单。如果你想使用所有唯一的词,我认为这个实现是行不通的。大多数情况下,您不想使用所有唯一的词,尽管许多词可能只出现在一条推文中。也许最好使用出现次数最多的词。我也不太清楚你想预测什么。
    • 是否有可能以某种方式获得 80% 的准确率?
    • 我非常同意。使用所有单词可能比需要的数据更多(如我的回答中所说,您可能需要修剪功能列表)。真的很难说,因为你从来没有告诉我们你到底想用这些数据预测什么。我认为您需要在除您之外的其他人计算更多数字之前正确地表述您的问题。
    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 2019-10-07
    • 2018-03-25
    • 2020-10-26
    • 2020-08-15
    • 2018-05-06
    • 2016-07-03
    • 2021-12-07
    相关资源
    最近更新 更多