2017-01-13 3 views
0

У меня есть файл, содержащий некоторые строки. Каждая строка содержит персидское предложение, вкладку и затем английское слово, которое показывает класс каждого предложения. Мне нужно извлечь 1000 наиболее часто встречающихся слов из этого файла, а затем я хочу создать матрицу. Столбцы этой матрицы являются классами файла (некоторые файлы имеют 2 класса, некоторые 3 и некоторые более), а строки - это 1000 слов (как показано на рисунке ниже (это небольшой образец с английскими словами, но мои Персидский. D1 - d5 - классы)). Я должен проверять каждый 1000 слов в каждом классе, если он существует, добавьте 1 к матрице (в своем собственном месте), а если нет, добавьте 0. Как я могу сделать такую ​​матрицу?Как сделать матрицу из 0 и 1?

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

ли она быть матрицей? Было бы проще сделать 'dict', со словами как ключи, и каждый элемент, содержащий список классов, к которому принадлежит слово. –

+0

Взгляните на [numpy] (https://docs.scipy.org/doc/numpy-dev/user/quickstart.html). – pylang

ответ

0

Несколько иная структура данных, вероятно, будет лучше подходит, по крайней мере первоначально ,

Я предлагаю использовать dict со словами в виде ключей и набором классов в качестве значения.

Обратите внимание, что я не могу читать персидский язык, поэтому я понятия не имею, что означают слова, и при копировании результатов из IPython в этот ответ могут возникнуть проблемы с левым правым. Мои извинения заранее.

Во-первых, мы читаем файл.

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

Импортируйте некоторые типы, которые нам нужны, создайте data-dict и частотомер.

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) 
+0

спасибо за ваш ответ, но мне нужна ровно матрица, потому что тогда я должен передать эту матрицу SVD. Фактически, это часть алгоритма LSA (латентный семантический анализ). – sara

+0

Что такое SVD в этом контексте и какая форма должна иметь матрица? Массив numpy или вложенный список? –

+0

@sara См. Обновленный ответ. –

Смежные вопросы