2016-09-23 750 views
3

我正在Scikit-Learn中进行多类文本分类。该数据集正在使用具有数百个标签的Multinomial朴素贝叶斯分类器进行训练。下面是来自Scikit提取了解脚本用于安装MNB模型scikit将输出metrics metrics.classification_report转换为CSV /制表符分隔格式

from __future__ import print_function 

# Read **`file.csv`** into a pandas DataFrame 

import pandas as pd 
path = 'data/file.csv' 
merged = pd.read_csv(path, error_bad_lines=False, low_memory=False) 

# define X and y using the original DataFrame 
X = merged.text 
y = merged.grid 

# split X and y into training and testing sets; 
from sklearn.cross_validation import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1) 

# import and instantiate CountVectorizer 
from sklearn.feature_extraction.text import CountVectorizer 
vect = CountVectorizer() 

# create document-term matrices using CountVectorizer 
X_train_dtm = vect.fit_transform(X_train) 
X_test_dtm = vect.transform(X_test) 

# import and instantiate MultinomialNB 
from sklearn.naive_bayes import MultinomialNB 
nb = MultinomialNB() 

# fit a Multinomial Naive Bayes model 
nb.fit(X_train_dtm, y_train) 

# make class predictions 
y_pred_class = nb.predict(X_test_dtm) 

# generate classification report 
from sklearn import metrics 
print(metrics.classification_report(y_test, y_pred_class)) 

和命令行屏幕上的metrics.classification_report的简化输出如下:

   precision recall f1-score support 
    12  0.84  0.48  0.61  2843 
    13  0.00  0.00  0.00  69 
    15  1.00  0.19  0.32  232 
    16  0.75  0.02  0.05  965 
    33  1.00  0.04  0.07  155 
     4  0.59  0.34  0.43  5600 
    41  0.63  0.49  0.55  6218 
    42  0.00  0.00  0.00  102 
    49  0.00  0.00  0.00  11 
     5  0.90  0.06  0.12  2010 
    50  0.00  0.00  0.00   5 
    51  0.96  0.07  0.13  1267 
    58  1.00  0.01  0.02  180 
    59  0.37  0.80  0.51  8127 
     7  0.91  0.05  0.10  579 
     8  0.50  0.56  0.53  7555  
    avg/total 0.59  0.48  0.45  35919 

我在想,如果有任何将报表输出转换为标准csv文件并使用常规列标题的方法

当我将命令行输出发送到csv文件或试图将屏幕输出复制/粘贴到电子表格中时 - OpenOffice Calc或Excel,将结果归因于一个列。这样看:

enter image description here

帮助表示赞赏。谢谢!

+0

我会试图重新的结果,因为我键入此,但具有u尝试使用熊猫旋转工作台成数据帧,然后发送数据帧到csv使用'dataframe_name_here.to_csv()'? 您是否也可以显示将结果写入csv的代码? – MattR

+0

@MattR我编辑了这个问题,并提供了完整的Python代码...我将脚本的输出从Linux命令行传递给一个CSV文件:$ python3 script.py> result.csv –

回答

-1

我总是解决输出问题的方式就像我在之前的评论中提到的,我已将输出转换为DataFrame。不仅难以置信地发送到文件(see here),而且Pandas真的很容易操作数据结构。我解决这个问题的另一种方法是使用CSV逐行编写输出,特别是使用writerow

如果你能得到的输出入数据帧这将是

dataframe_name_here.to_csv() 

,或者使用CSV它会像他们在CSV链接提供的例子。

+0

谢谢我试图使用数据框; 'Result = metrics.classification_report(y_test,y_pred_class); df = pd.DataFrame(结果); df.to_csv(results.csv,sep ='\ t')'但出现错误_pandas.core.common.PandasError:未正确调用DataFrame构造函数!_ –

+3

这并不真正回答这个问题。 classification_report的输出不能直接转换为DataFrame。 – CentAu

4

如果你想要个人成绩,这应该做的工作就好了。

import pandas as pd 

def classifaction_report_csv(report): 
    report_data = [] 
    lines = report.split('\n') 
    for line in lines[2:-3]: 
     row = {} 
     row_data = line.split('  ') 
     row['class'] = row_data[0] 
     row['precision'] = float(row_data[1]) 
     row['recall'] = float(row_data[2]) 
     row['f1_score'] = float(row_data[3]) 
     row['support'] = float(row_data[4]) 
     report_data.append(row) 
    dataframe = pd.DataFrame.from_dict(report_data) 
    dataframe.to_csv('classification_report.csv', index = False) 

report = classification_report(y_true, y_pred) 
classifaction_report_csv(report) 
+0

row ['precision'] = float(row_data [1]) ValueError:无法将字符串转换为float: – user3806649

3

我们可以从precision_recall_fscore_support函数获取实际值,然后将它们放入数据框中。 下面的代码会给出相同的结果,但现在在熊猫df :)。

clf_rep = metrics.precision_recall_fscore_support(true, pred) 
out_dict = { 
      "precision" :clf_rep[0].round(2) 
      ,"recall" : clf_rep[1].round(2) 
      ,"f1-score" : clf_rep[2].round(2) 
      ,"support" : clf_rep[3] 
      } 
out_df = pd.DataFrame(out_dict, index = nb.classes_) 
avg_tot = (out_df.apply(lambda x: round(x.mean(), 2) if x.name!="support" else round(x.sum(), 2)).to_frame().T) 
avg_tot.index = ["avg/total"] 
out_df = out_df.append(avg_tot) 
print out_df 
0
def to_table(report): 
    report = report.splitlines() 
    res = [] 
    res.append(['']+report[0].split()) 
    for row in report[2:-2]: 
     res.append(row.split()) 
    lr = report[-1].split() 
    res.append([' '.join(lr[:3])]+lr[3:]) 
    return np.array(res) 

返回numpy的阵列,其可以被转动以大熊猫数据帧或仅被保存为csv文件。

1

虽然以前的答案可能都在工作,但我发现它们有点冗长。以下内容将单独的课程结果以及摘要行存储在一个数据框中。对报告中的变化不太敏感,但为我做了诀窍。

#init snippet and fake data 
from io import StringIO 
import re 
import pandas as pd 
from sklearn import metrics 
true_label = [1,1,2,2,3,3] 
pred_label = [1,2,2,3,3,1] 

def report_to_df(report): 
    report = re.sub(r" +", " ", report).replace("avg/total", "avg/total").replace("\n ", "\n") 
    report_df = pd.read_csv(StringIO("Classes" + report), sep=' ', index_col=0)   
    return(report_df) 

#txt report to df 
report = metrics.classification_report(true_label, pred_label) 
report_df = report_to_df(report) 

#store, print, copy... 
print (report_df) 

这给所需的输出:

Classes precision recall f1-score support 
1 0.5 0.5 0.5 2 
2 0.5 0.5 0.5 2 
3 0.5 0.5 0.5 2 
avg/total 0.5 0.5 0.5 6