2014-12-06 291 views
2

我想对Sci Kit Learn中的unigrams做一些分析。我创建了svmlight格式的文件并试图运行MultinomialNB() KNeighborsClassifier() and SVC()。我们首先试图用unigrams做到这一点,但我得到了X培训维度错误,可能是因为在给定示例中包含的唯一unigrams是在那里的培训中出现的唯一unigrams。我试图创建svmlight格式的培训文件,其中包括每个在语料库中查看的每个单元的占位符,即使那些不在该给出的示例中。用Scikit学习Unigram分析

问题是将训练文件从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测试实例,并与18000个不同unigram进行

编辑1212个测试的例子,我试图用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)) 
+0

你可以发布X_train,y_train,x_test和y_test的长度和尺寸以及你得到的错误吗? – user823743 2014-12-07 01:23:20

+0

@ user823743添加了 – 2014-12-07 01:28:17

+0

我的意思是如果您可以在代码中打印尺寸并将其张贴在这里?或者在分配这些数组时遇到错误?和控制台上的错误是什么? – user823743 2014-12-07 01:34:36

回答

1

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

然后您可以在未来的测试示例中调用transform,并且它会像正常一样进行转换。

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

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

一个额外的这样的好处是,你可以在这个矢量化与分类使用Pipeline进行装配和测试更方便结合起来。

+0

我试过这个,试图在上面的代码中修复它。我做对了吗? – 2014-12-08 08:15:12