Несколько иная структура данных, вероятно, будет лучше подходит, по крайней мере первоначально ,
Я предлагаю использовать 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)
ли она быть матрицей? Было бы проще сделать 'dict', со словами как ключи, и каждый элемент, содержащий список классов, к которому принадлежит слово. –
Взгляните на [numpy] (https://docs.scipy.org/doc/numpy-dev/user/quickstart.html). – pylang