用Scikit学习Unigram分析

时间:2014-12-06 22:44:20

标签: python machine-learning nlp scikit-learn

我正在尝试对Sci Kit Learn中的unigrams做一些分析。我以svmlight格式创建了文件,并尝试运行MultinomialNB() KNeighborsClassifier() and SVC()。我首先尝试用unigrams做到这一点我得到了X训练维度错误,大概是因为在给定的例子中包含的唯一的unigrams是那些在训练中出现的那些。我尝试创建svmlight格式训练文件,其中包括语料库中每个看到的单字组的占位符,即使那些不在给定示例中的也是如此。

问题是将培训文件从3 MB扩展到300 MB。这导致sklearn加载文件时出现内存错误。有没有办法解决维度不匹配或内存溢出问题。

X_train, y_train= load_svmlight_file(trainFile)
x_test, y_test = load_svmlight_file(testFile)
try:
    clf = MultinomialNB()
    clf.fit(X_train, y_train)
    preds = clf.predict(x_test)
    print('Input data:  ' + trainFile.split('.')[0])
    print('naive_bayes')
    print('accuracy: ' + str(accuracy_score(y_test, preds)))
    if 1 in preds:
        print('precision: ' + str(precision_score(y_test, preds)))
        print('recall: ' + str(recall_score(y_test, preds)))
except Exception as inst:
    print 'fail in NB  ' + 'Input data:  ' + trainFile.split('.')[0]
    print str(inst)
    pass

2828个测试实例和1212个具有18000个不同的unigrams的测试实例

编辑我试图使用sklearn CountVectorizer,但我仍然遇到内存问题。这是最好的方法吗?

def fileLoadForPipeline(trainSetFile, valSetFile):
    with open(trainSetFile) as json_file:
    tdata = json.load(json_file)
with open(valSetFile) as json_file:
    vdata = json.load(json_file)
x_train = []
x_val = []
y_train = []
y_val = []
for t in tdata:
    x_train.append(t['request_text'])
    y_train.append(t['requester_received_pizza'])
for v in vdata:
    x_val.append(t['request_text'])
    y_val.append(t['requester_received_pizza'])
return x_train, y_train, x_val, y_val

def buildPipeline(trainset, valset, norm):
x_train, y_train, x_val, y_val = fileLoadForPipeline(trainset, valset)
bigram_vectorizer = CountVectorizer(ngram_range=(1, 2), token_pattern=ur'\b\w+\b', min_df=1)
xT = bigram_vectorizer.fit_transform(x_train).toarray()
xV = bigram_vectorizer.fit_transform(x_val).toarray()
if norm:
    transformer = TfidfTransformer()
    xT = transformer.fit_transform(xT)
    xV = transformer.fit_transform(xV)
results = []
for clf, name in ((Perceptron(n_iter=50), "Perceptron"),
              (KNeighborsClassifier(n_neighbors=40), "kNN"), (MultinomialNB), (MultinomialNB(alpha=.01),'MultinomialNB'),
              (BernoulliNB(alpha=.1),'BernoulliNB'),(svm.SVC(class_weight='auto'),'svc')):
    print 80 * '='
    print name
    results.append(benchmark(clf))

1 个答案:

答案 0 :(得分:1)

尝试使用scikit-learn CountVectorizer,它将为您提供原始文本的特征提取。最重要的是,调用一组训练样例的方法fit_transform会自动执行Bag of Words单字组转换,它会跟踪训练语料库中找到的所有n个唯一单词,并转换每个文档到长度为n的数组,其特征可以是离散字数或二进制存在特征(取决于binary选项)。关于CountVectorizer的好处是它以numpy稀疏矩阵格式存储数据,这使得它非常节省内存,并且应该能够解决您所拥有的任何内存问题。

然后,您可以在将来的测试示例中调用transform,它将像平常一样进行转换。

这也应该有助于解决任何维度问题,因为CountVectorizer的工作是规范一切。有关使用的具体信息:

http://scikit-learn.org/stable/modules/feature_extraction.html#common-vectorizer-usage

这样做的另一个好处是,您可以使用Pipeline将此矢量图与分类器相结合,以使拟合和测试更加方便。