Python文本处理:NLTK和pandas

IVR*_*IVR 9 python machine-learning nltk pandas

我正在寻找一种有效的方法来构建Python中的术语文档矩阵,可以与额外的数据一起使用.

我有一些带有一些其他属性的文本数据.我想对文本进行一些分析,我希望能够将从文本中提取的特征(例如单个字标记或LDA主题)与其他属性相关联.

我的计划是将数据加载为pandas数据框,然后每个响应都代表一个文档.不幸的是,我遇到了一个问题:

import pandas as pd
import nltk

pd.options.display.max_colwidth = 10000

txt_data = pd.read_csv("data_file.csv",sep="|")
txt = str(txt_data.comment)
len(txt)
Out[7]: 71581 

txt = nltk.word_tokenize(txt)
txt = nltk.Text(txt)
txt.count("the")
Out[10]: 45

txt_lines = []
f = open("txt_lines_only.txt")
for line in f:
    txt_lines.append(line)

txt = str(txt_lines)
len(txt)
Out[14]: 1668813

txt = nltk.word_tokenize(txt)
txt = nltk.Text(txt)
txt.count("the")
Out[17]: 10086
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,文本的处理方式只有空格,字母和.?!被删除(为简单起见).

如您所见,转换为字符串的pandas字段返回的匹配项更少,字符串的长度也更短.

有没有办法改进上面的代码?

此外,str(x)在注释中[str(x) for x in txt_data.comment]创建一个大字符串,同时创建一个列表对象,该列表对象无法分解成一堆单词.生成nltk.Text保留文档索引的对象的最佳方法是什么?换句话说,我正在寻找一种方法来创建一个术语文档矩阵,R等同TermDocumentMatrix()tm包.

非常感谢.

Ste*_*fan 11

使用a的好处是pandas DataFramenltk功能应用于每个,row如下所示:

word_file = "/usr/share/dict/words"
words = open(word_file).read().splitlines()[10:50]
random_word_list = [[' '.join(np.random.choice(words, size=1000, replace=True))] for i in range(50)]

df = pd.DataFrame(random_word_list, columns=['text'])
df.head()

                                                text
0  Aaru Aaronic abandonable abandonedly abaction ...
1  abampere abampere abacus aback abalone abactor...
2  abaisance abalienate abandonedly abaff abacina...
3  Ababdeh abalone abac abaiser abandonable abact...
4  abandonable abandon aba abaiser abaft Abama ab...

len(df)

50

txt = df.text.apply(word_tokenize)
txt.head()

0    [Aaru, Aaronic, abandonable, abandonedly, abac...
1    [abampere, abampere, abacus, aback, abalone, a...
2    [abaisance, abalienate, abandonedly, abaff, ab...
3    [Ababdeh, abalone, abac, abaiser, abandonable,...
4    [abandonable, abandon, aba, abaiser, abaft, Ab...

txt.apply(len)

0     1000
1     1000
2     1000
3     1000
4     1000
....
44    1000
45    1000
46    1000
47    1000
48    1000
49    1000
Name: text, dtype: int64
Run Code Online (Sandbox Code Playgroud)

因此,您可以获得.count()每个row条目:

txt = txt.apply(lambda x: nltk.Text(x).count('abac'))
txt.head()

0    27
1    24
2    17
3    25
4    32
Run Code Online (Sandbox Code Playgroud)

然后可以使用以下结果对结果求和:

txt.sum()

1239
Run Code Online (Sandbox Code Playgroud)