如何使用Python为文本文件以及类变量创建一个unigram和bigram计数矩阵到csv中?

如何使用Python为文本文件以及类变量创建一个unigram和bigram计数矩阵到csv中?,python,nltk,sentiment-analysis,Python,Nltk,Sentiment Analysis,我想使用Python为文本文件创建一个unigram和bigram计数矩阵,并将一个类变量转换为csv 文本文件包含两列,如下所示 Text Class I love the movie Pos I hate the movie Neg 我想要文本列的

我想使用Python为文本文件创建一个unigram和bigram计数矩阵,并将一个类变量转换为csv 文本文件包含两列,如下所示

Text                                                  Class
I love the movie                                      Pos
I hate the movie                                      Neg
我想要文本列的unigram和bigram计数,输出应该写入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

我将您的输入文件做得更详细一些,以便您相信解决方案是有效的:

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中使用Bigram和Unigram,所以假设你想要它们在一起。否则,你就不难重新编程了。使用NLP库中已经内置的工具以这种方式积累人口可能更好,但有趣的是,可以在较低的级别上完成。顺便说一下,我正在使用Python3,如果需要在Python2中工作,您可能需要更改一些东西,例如
list
的使用

使用的一些有趣的参考资料对我来说是新的。此外,我还必须将您的双元图和单元图分组在CSV的不同端

我知道代码看起来很重复,但在开始编写之前,您需要先运行所有行以获取csv的标题

这是libreoffice中的输出

你的csv将会变得非常广泛,因为它收集了所有的单图和双图。如果您真的希望在头中有没有括号和逗号的bigram,您可以制作某种函数来实现这一点。最好将它们保留为元组,以防您需要在某个时候再次将它们解析为Python,并且同样可读

您没有包含生成类列的代码,假设您有,您可以在头写入csv之前将字符串“class”附加到头上,以创建该列并填充它

row['Class'] = sentiment

在写入行之前的最后一行。

我将您的输入文件做得更详细一些,以便您相信解决方案是有效的:

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中使用Bigram和Unigram,所以假设你想要它们在一起。否则,你就不难重新编程了。使用NLP库中已经内置的工具以这种方式积累人口可能更好,但有趣的是,可以在较低的级别上完成。顺便说一下,我正在使用Python3,如果需要在Python2中工作,您可能需要更改一些东西,例如
list
的使用

使用的一些有趣的参考资料对我来说是新的。此外,我还必须将您的双元图和单元图分组在CSV的不同端

我知道代码看起来很重复,但在开始编写之前,您需要先运行所有行以获取csv的标题

这是libreoffice中的输出

你的csv将会变得非常广泛,因为它收集了所有的单图和双图。如果您真的希望在头中有没有括号和逗号的bigram,您可以制作某种函数来实现这一点。最好将它们保留为元组,以防您需要在某个时候再次将它们解析为Python,并且同样可读

您没有包含生成类列的代码,假设您有,您可以在头写入csv之前将字符串“class”附加到头上,以创建该列并填充它

row['Class'] = sentiment
在写入行之前的最后一行的第二行