2017-11-07 4 views
0

私はユニグラムとバイグラムのカウントをしたいテキストファイルは、このPythonを使用してクラス変数とともにcsvにテキストファイルのユニグラムとバイグラムの数列を作成する方法は?

Text             Class 
I love the movie          Pos 
I hate the movie          Neg 

のように見える2つの列が含まれているPythonの を使用してCSVにクラス変数と一緒にテキストファイルのユニグラムとバイグラムカウントマトリックスを作成したいですテキスト列と出力用のCSVファイルに書き込まれるべき

I  hate  love  movie the  class 
1  0   1   1  1   Pos 
1  1   0   1  1   Neg 

バイグラム

I love  love the  the movie  I hate hate the   class 
1   1    1   0   0    Pos 
0   0    1   1   1    Neg 

誰も私が上記の出力形式に以下のコードを改善するのを助けることができますか?

>>> import nltk 
>>> from collections import Counter 
>>> fo = open("text.txt") 
>>> fo1 = fo.readlines() 
>>> for line in fo1: 
     bigm = list(nltk.bigrams(line.split())) 
     bigmC = Counter(bigm) 
     for key, value in bigmC.items(): 
      print(key, value) 

('love', 'the') 1 
('the', 'movie') 1 
('I', 'love') 1 
('I', 'hate') 1 
('hate', 'the') 1 
('the', 'movie') 1 

答えて

2

私はあなたがソリューションが動作することを信じることができるだけので、詳細はもう少しあなたの入力ファイルを作っています

I love the movie movie 
I hate the movie 
The movie was rubbish 
The movie was fantastic 

最初の行が二回そうでなければ、ということを伝えることができない原因となる単語が含まれていますカウンターは実際に正しくカウントしています。

ソリューション:

import csv 
import nltk 
from collections import Counter 
fo = open("text.txt") 
fo1 = fo.readlines() 
counter_sum = Counter() 
for line in fo1: 
     tokens = nltk.word_tokenize(line) 
     bigrams = list(nltk.bigrams(line.split())) 
     bigramsC = Counter(bigrams) 
     tokensC = Counter(tokens) 
     both_counters = bigramsC + tokensC 
     counter_sum += both_counters 
     # This basically collects the whole 'population' of words and bigrams in your document 

# now that we have the population can write a csv 

with open('unigrams_and_bigrams.csv', 'w', newline='') as csvfile: 
    header = sorted(counter_sum, key=lambda x: str(type(x))) 
    writer = csv.DictWriter(csvfile, fieldnames=header) 
    writer.writeheader() 
    for line in fo1: 
      tokens = nltk.word_tokenize(line) 
      bigrams = list(nltk.bigrams(line.split())) 
      bigramsC = Counter(bigrams) 
      tokensC = Counter(tokens) 
      both_counters = bigramsC + tokensC 
      cs = dict(counter_sum) 
      bc = dict(both_counters) 
      row = {} 
      for element in list(cs): 
       if element in list(bc): 
        row[element] = bc[element] 
       else: 
        row[element] = 0 
      writer.writerow(row) 

だから、私が使用して、あなたの最初のアプローチで構築されました。あなたはバイブラムとユニグラムが別々のCSVで欲しいと思っているかどうかは言いませんでした。あなたがそうでなければ再プログラムするのはそれほど難しいことではありません。この方法で人口を累積するには、NLPライブラリに既に組み込まれているツールを使用する方が良いでしょうが、もっと低レベルで行うことができるのが面白いです。 Python 3を使用していますが、listのようなものを変更する必要があるかもしれません。

いくつかの興味深いリファレンスはthis one on summing countersでした。また、私はask a questionにあなたのbigramsとユニグラムをCSVの別々の端でグループ化する必要がありました。

私はコードが繰り返し見えていることは知っていますが、あなたが書いてみる前に、すべての行を最初に実行してcsvのヘッダーを取得する必要があります。ここで

のLibreOfficeで出力

image of csv output

はあなたのcsvファイルは、それがすべてのユニグラムとバイグラムを集めるように非常に広い取得するつもりです。ヘッダーに角括弧やコンマを入れずにバイグラムを作成するのが本当に気になるなら、それを行うための何らかの機能を作ることができます。ただし、それらを何らかの点でPythonに再度解析する必要がある場合に備えて、それらをタプルとして残すほうが良いでしょう。

クラス列を生成したコードを含めなかったヘッダがその列を作成し、それを埋めるために、CSVに書き込まれる前に、行が書き込まれる前にそれは、あなたが最後から二番目の行に、ヘッダーに

row['Class'] = sentiment 

を文字列「クラス」を追加することができています。

関連する問題