python - 如何有效地使用 CountVectorizer 获取目录中所有文件的 ngram 计数?

标签 python python-3.x scikit-learn

我的目录中有大约 10k .bytes 文件,我想使用计数向量化器来获取 n_gram 计数(即适合训练并在测试集上进行转换)。 在这 10k 个文件中,我有 8k 个文件作为训练文件,2k 个文件作为测试文件。

files = 
['bfiles/GhHS0zL9cgNXFK6j1dIJ.bytes',
 'bfiles/8qCPkhNr1KJaGtZ35pBc.bytes',
 'bfiles/bLGq2tnA8CuxsF4Py9RO.bytes',
 'bfiles/C0uidNjwV8lrPgzt1JSG.bytes',
 'bfiles/IHiArX1xcBZgv69o4s0a.bytes',
    ...............................
    ...............................]

print(open(files[0]).read())
    'A4 AC 4A 00 AC 4F 00 00 51 EC 48 00 57 7F 45 00 2D 4B 42 45 E9 77 51 4D 89 1D 19 40 30 01 89 45 E7 D9 F6 47 E7 59 75 49 1F ....'

我无法执行如下操作并将所有内容传递给 CountVectorizer

file_content = []
for file in file:
    file_content.append(open(file).read())

我无法将每个文件文本附加到大型嵌套文件列表中,然后使用 CountVectorizer,因为所有合并的文本文件大小超过 150GB。我没有资源来执行此操作,因为 CountVectorizer 使用大量内存。

我需要一种更有效的方法来解决这个问题,是否有其他方法可以实现我想要的目标,而无需立即将所有内容加载到内存中。非常感谢任何帮助。

我所能实现的就是读取一个文件,然后使用 CountVectorizer 但我不知道如何实现我正在寻找的目标。

cv = CountVectorizer(ngram_range=(1, 4))
temp = cv.fit_transform([open(files[0]).read()])
temp
<1x451500 sparse matrix of type '<class 'numpy.int64'>'
    with 335961 stored elements in Compressed Sparse Row format>

最佳答案

您可以使用以下流程构建解决方案:

1) 循环遍历您的文件并在文件中创建一组所有标记。在下面的示例中,这是使用 Counter 完成的,但您可以使用 python 集来实现相同的结果。这里的好处是 Counter 还会为您提供每个术语出现的总数。

2) 将 CountVectorizer 与标记集/列表相匹配。您可以使用 ngram_range=(1, 4) 实例化 CountVectorizer。为了限制 df_new_data 中的特征数量,避免了下面的情况。

3)照常转换新数据。

下面的示例适用于小数据。我希望您可以调整代码以满足您的需求。

import glob
import pandas as pd
import numpy as np
from collections import Counter
from sklearn.feature_extraction.text import CountVectorizer

# Create a list of file names
pattern = 'C:\\Bytes\\*.csv'
csv_files = glob.glob(pattern)

# Instantiate Counter and loop through the files chunk by chunk 
# to create a dictionary of all tokens and their number of occurrence
counter = Counter()
c_size = 1000
for file in csv_files:
    for chunk in pd.read_csv(file, chunksize=c_size, index_col=0, header=None):
        counter.update(chunk[1])

# Fit the CountVectorizer to the counter keys
vectorizer = CountVectorizer(lowercase=False)
vectorizer.fit(list(counter.keys()))

# Loop through your files chunk by chunk and accummulate the counts
counts = np.zeros((1, len(vectorizer.get_feature_names())))
for file in csv_files:
    for chunk in pd.read_csv(file, chunksize=c_size,
                             index_col=0, header=None):
        new_counts = vectorizer.transform(chunk[1])
        counts += new_counts.A.sum(axis=0)

# Generate a data frame with the total counts
df_new_data = pd.DataFrame(counts, columns=vectorizer.get_feature_names())

df_new_data
Out[266]: 
      00     01     0A     0B     10     11     1A     1B     A0     A1  \
0  258.0  228.0  286.0  251.0  235.0  273.0  259.0  249.0  232.0  233.0   

      AA     AB     B0     B1     BA     BB  
0  248.0  227.0  251.0  254.0  255.0  261.0  

数据生成代码:

import numpy as np
import pandas as pd

def gen_data(n): 
    numbers = list('01')
    letters = list('AB')
    numlet = numbers + letters
    x = np.random.choice(numlet, size=n)
    y = np.random.choice(numlet, size=n)
    df = pd.DataFrame({'X': x, 'Y': y})
    return df.sum(axis=1)

n = 2000
df_1 = gen_data(n)
df_2 = gen_data(n)

df_1.to_csv('C:\\Bytes\\df_1.csv')
df_2.to_csv('C:\\Bytes\\df_2.csv')

df_1.head()
Out[218]: 
0    10
1    01
2    A1
3    AB
4    1A
dtype: object

关于python - 如何有效地使用 CountVectorizer 获取目录中所有文件的 ngram 计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57827842/

相关文章:

python - 您如何找到小部件的唯一且恒定的 ID?

python - 从另一个文件导入类变量Python

python - 如何在 pygame 中创建 "while mouse down"循环

python - FeatureUnion Sklearn 管道中的错误

python - 在 Python 中计算低阶近似

python - 如何为 PhantomJS 设置超时?

python - Pandas 不会将分类数据 [性别] 更改为数值 [0/1]

将字符串 "None"转换为适当的 None 的 Pythonic 方法

python - 匹配和弦的正则表达式,带有民族口音的问题

python - 在Windows上使用pip安装Scipy python包时出错