2016-09-23 12 views
3

私はScikit-Learnで複数のテキスト分類を行います。データセットは、数百のラベルを有する多項式Naive Bayes分類器を使用して訓練されている。ここでScikitからの抽出物がMNBモデル​​scikitは出力のメトリックを分類します。分類は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、It結果を1つにまとめる列。このように見える:

enter image description here

ヘルプは大歓迎しました。ありがとう!

+0

私は私がこれを入力すると、結果を再作成しようとしている、しかし、uはパンダを使用してデータフレームの中にテーブルを回し、その後、データフレームを送信しようとしていることでしょう'dataframe_name_here.to_csv()'を使ってcsvに? 結果をcsvに書き込むコードも表示できますか? – MattR

+0

@MattR質問を編集し、完全なPythonコードを提供しました...私はスクリプトの出力をLinuxのコマンドラインからCSVファイルに渡していました。$ python3 script.py> result.csv –

答えて

-1

出力の問題を常に解決してきたのは、以前のコメントで述べたようなもので、出力をDataFrameに変換しました。ファイル(see here)に送信するのは非常に簡単ですが、Pandasはデータ構造を操作するのが簡単です。私がこれを解決したもう1つの方法は、CSVを使用して、特にwriterowを使用して出力を行ごとに書き込むことです。

あなたがデータフレームに出力を得るために管理している場合、それは、彼らがCSVリンクに提供例のようになりCSVを使用して

dataframe_name_here.to_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関数から取得し、データフレームに入れることができます。 以下のコードは同じ結果を返しますが、今はpandas 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) 

パンダのデータフレームに回動することができ、または単に、CSVファイルとして保存することがnumpyの配列を返します。

1

以前の回答はおそらくすべて動作していましたが、少し冗長であることがわかりました。次の例では、個々のクラス結果と、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 
関連する問題