如何制作0和1的矩阵?

时间:2017-01-13 21:53:07

标签: python-3.x matrix

我有一个包含一些行的文件。每行包含一个波斯语句子,一个标签,然后是一个英语单词,显示每个句子的类。我必须从这个文件中提取1000个最常用的单词,然后我想制作一个矩阵。这个矩阵的列是文件的类(有些文件有2个类,有的是3个,有些是更多),行是1000个单词(如下图所示(它是一个带有英文单词的小样本)但我的是波斯语.d1到d5是班级))。我必须检查每个类中的每1000个单词,如果它存在,则在矩阵中添加1(在它自己的位置),如果不是,则添加0.如何制作这样的矩阵?

def makeMatrix(file):
    with open (file, encoding = "utf-8") as f1:
        for line in f1:
            line = line.strip().split("\t")
            lin = line[0].split()
            for word in lin:
             ????????????

样本矩阵:

enter image description here

示例文件: https://www.dropbox.com/s/fx33cac3qemizmj/train1.txt?dl=0 enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

稍微不同的数据结构可能是更好的匹配,至少在最初阶段。

我建议使用dict,将单词作为键,将一组类作为值。

请注意,我无法阅读波斯语,因此我不知道这些词的含义,将IPython中的结果复制到此答案时可能会出现左右问题。我提前道歉。

首先,我们阅读文件。

In [1]: with open('train1.txt', encoding = "utf-8") as f1:
   ...:     lines = f1.readlines()
   ...:     

导入我们需要的一些类型,创建数据字典和频率计数器。

In [2]: from collections import defaultdict

In [3]: from collections import Counter

In [4]: data = defaultdict(set)

In [5]: freq = Counter()

将每一行拆分为句子和分类。 接下来,将每行分成单词。将单词的分类添加到数据中,将单词添加到计数器中。

In [6]: for ln in lines:
   ...:     sentence, classification = ln.strip().split('\t')
   ...:     for word in sentence.split():
   ...:         data[word].add(classification)
   ...:         freq.update([word])
   ...:         

让我们看看(例如)五个最常见的单词是什么。

In [7]: freq.most_common(5)
Out[7]: [('پر', 53), ('اوقات', 3), ('فراغت', 3), ('زمین', 3), ('لطافت', 2)]

(这里有一个LTR / RTL问题,它在IPython中看起来非常不同。)

现在查看数据以查看它们属于哪个类。

In [8]: for word in [t[0] for t in freq.most_common(5)]:
   ...:     print(word, data[word])
   ...:     
پر {'full', 'fill'}
اوقات {'fill'}
فراغت {'fill'}
زمین {'full', 'fill'}
لطافت {'full'}

使用这种方法,您可以轻松检查数据中是否有单词:

In [9]: 'اوقات' in data
Out[9]: True

您可以轻松查看它属于哪个类:

In [10]: data['اوقات']
Out[10]: {'fill'}

修改

现在把它变成一个矩阵。如果没有numpy,我会告诉你如何做到这一点。

首先,没有numpy。矩阵可以表示为嵌套列表。我使用较小的(10x5)矩阵而不是1000x5,因为train1数据集不是那么大。初始矩阵用零填充,相应的项目将设置为1。

In [11]: m = [[0,0,0,0,0] for j in range(10)]

注意:请勿使用[[0,0,0,0]]*10,因为这会生成内部列表的浅层副本

对于第一个索引,我们将使用十个最常出现的词:

In [12]: J = [p[0] for p in freq.most_common(10)]

对于第二个索引,我们使用类别:

In [14]: K = ['fill', 'full', 'foo', 'bar', 'baz']

现在设置项目。

In [16]: for j, word in enumerate(J):
    ...:     for cat in data[word]:
    ...:         m[j][K.index(cat)] = 1
    ...: 

结果矩阵:

In [17]: m
Out[17]: 
[[1, 1, 0, 0, 0],
 [1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 1, 0, 0, 0]]

对于numpy来说,它大致相同:

In [18]: import numpy as np

In [21]: m2 = np.zeros((10,5), dtype=np.uint8)

In [22]: for j, word in enumerate(J):
    ...:     for cat in data[word]:
    ...:         m2[j, K.index(cat)] = 1
    ...: 

In [23]: m2
Out[23]: 
array([[1, 1, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 1, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [1, 1, 0, 0, 0],
       [1, 1, 0, 0, 0],
       [1, 1, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0]], dtype=uint8)