我正在研究一个不断学习的网络爬虫,以查找与世界各地发生的特定危机和悲剧事件相关的新闻文章。我正在努力使数据模型尽可能精益和高效,考虑到随着爬行的继续不断增长。
我将数据模型存储在列表中(与正在抓取的页面进行TFIDF比较)我希望减少列表的大小但不会丢失相对计数列表中的每个项目。
这是来自2个已抓取网页的示例模型:
[[u'remark', u'special', u'agent', u'richard', u'deslauri', u'press', u'investig', u'crime', u'terror', u'crime', u'inform', u'servic', u'inform', u'laboratori', u'servic', u'want', u'want', u'want', u'terror', u'crime', u'want', u'news', u'news', u'press', u'news', u'servic', u'crime', u'inform', u'servic', u'laboratori', u'servic', u'servic', u'crime', u'crime', u'crime', u'terror', u'boston', u'press', u'remark', u'special', u'agent', u'richard', u'deslauri', u'press', u'investig', u'remark', u'special', u'agent', u'richard', u'deslauri', u'press', u'investig', u'boston', u'special', u'agent', u'remark', u'richard', u'deslauri', u'boston', u'investig', u'time', u'time', u'investig', u'boston', u'terror', u'law', u'enforc', u'boston', u'polic', u'polic', u'alreadi', u'alreadi', u'law', u'enforc', u'around', u'evid', u'boston', u'polic', u'evid', u'laboratori', u'evid', u'laboratori', u'may', u'alreadi', u'laboratori', u'investig', u'boston', u'polic', u'law', u'enforc', u'investig', u'around', u'alreadi', u'around', u'investig', u'law', u'enforc', u'evid', u'may', u'time', u'may', u'may', u'investig', u'may', u'around', u'time', u'investig', u'investig', u'boston', u'boston', u'news', u'press', u'boston', u'want', u'boston', u'want', u'news', u'servic', u'inform'], [u'2011', u'request', u'inform', u'tamerlan', u'tsarnaev', u'foreign', u'govern', u'crime', u'crime', u'inform', u'servic', u'inform', u'servic', u'nation', u'want', u'ten', u'want', u'want', u'crime', u'want', u'news', u'news', u'press', u'releas', u'news', u'stori', u'servic', u'crime', u'inform', u'servic', u'servic', u'servic', u'crime', u'crime', u'crime', u'news', u'press', u'press', u'releas', u'2011', u'request', u'inform', u'tamerlan', u'tsarnaev', u'foreign', u'govern', u'2011', u'request', u'inform', u'tamerlan', u'tsarnaev', u'foreign', u'govern', u'2013', u'nation', u'press', u'tamerlan', u'tsarnaev', u'dzhokhar', u'tsarnaev', u'tamerlan', u'tsarnaev', u'dzhokhar', u'tsarnaev', u'dzhokhar', u'tsarnaev', u'tamerlan', u'tsarnaev', u'dzhokhar', u'tsarnaev', u'2011', u'foreign', u'govern', u'inform', u'tamerlan', u'tsarnaev', u'inform', u'2011', u'govern', u'inform', u'tamerlan', u'tsarnaev', u'foreign', u'foreign', u'govern', u'2011', u'inform', u'foreign', u'govern', u'nation', u'press', u'releas', u'crime', u'releas', u'ten', u'news', u'stori', u'2013', u'ten', u'news', u'stori', u'2013', u'ten', u'news', u'stori', u'2013', u'2011', u'request', u'inform', u'tamerlan', u'tsarnaev', u'foreign', u'govern', u'nation', u'press', u'releas', u'want', u'news', u'servic', u'inform', u'govern']]
我想维护单词列表,而不是将计数嵌入到列表本身。我希望列表来自:
[波士顿,波士顿,波士顿,Bombings,Bombings,Tsarnaev,Tsarnaev,时间]到[波士顿,波士顿,Bombings,Tsarnaev]基本上,如果我有一个列表[a,a,a,b,b,c],我想把它减少到[a,a,b]
编辑:很抱歉不清楚,但我会再试一次。 我不想要一套。出现次数非常重要,因为它是加权列表,因此“波士顿”应该出现的次数多于“时间”或其他类似术语。我想要实现的是最小化数据模型,同时从模型中删除无关紧要的术语。所以在上面的例子中,我故意省略了C,因为它增加了模型的“胖”。我希望保持相对性,A比B出现多1次,比C多出2次,但由于C只在原始模型中出现过一次,所以它正从瘦模型中删除。
答案 0 :(得分:3)
from collections import defaultdict
d = defaultdict(int)
for w in words[0]:
d[w] += 1
mmin = min(d[p] for p in d)
然后你可以从每个单词中减去这个mmin并创建一个新列表。但也许这个词很紧凑。要保留订单,您可以使用dict中的信息并设计一些智能方法来过滤您的初始单词列表。
例如,对于单词列表[a,a,a,b,b,c]
,字典将包含{a:3, b:2, c:1}
和mmin=1
。您可以使用此信息通过从所有项目中减去1来获得更加简洁的字典,以获得{a:2, b:1}
,并且c
0
已被删除。
完整代码:
from collections import defaultdict
d = defaultdict(int)
words = ['a','a','a','b','b','c']
for w in words:
d[w] += 1
mmin = min(d[p] for p in d)
slim=[]
for w in words:
if d[w] > mmin:
slim.append(w)
d[w] -= 1
print slim
答案 1 :(得分:2)
如果您的样本模型已分配给变量topics
,那么您可以使用collections.Counter
来维护所有主题及其计数的字典对象:
from collections import Counter
topic_count = [Counter(topic) for topic in topics]
# [Counter({u'boston': 11, u'investig': 11, u'crime': 7, u'servic': 7, u'want': 6, u'press': 6, u'laboratori': 5, u'may': 5, u'news': 5, u'agent': 4, u'alreadi': 4, u'deslauri': 4, u'special': 4, u'richard': 4, u'polic': 4, u'terror': 4, u'around': 4, u'evid': 4, u'law': 4, u'remark': 4, u'inform': 4, u'enforc': 4, u'time': 4}),
# Counter({u'tsarnaev': 13, u'inform': 12, u'govern': 9, u'tamerlan': 9, u'foreign': 8, u'news': 8, u'crime': 8, u'2011': 7, u'servic': 7, u'press': 6, u'releas': 5, u'want': 5, u'ten': 4, u'request': 4, u'stori': 4, u'nation': 4, u'2013': 4, u'dzhokhar': 4})]
答案 2 :(得分:1)
这对我来说似乎是一种“正常化”(而非“减少”)任务,虽然我不确定这是否是正确的术语。
我认为collections.Counter
确实是你想在这里使用的。它有几个方便的方法,可以改变项目的数量,并使结果非常容易。
可以直接从列表创建实例,计算每个项目的出现次数。 Counter.most_common()
给出了一个键/计数对列表,从最高频率到最低频率排序。然后最低计数是该列表中最后一个元组的第二个字段。
Counter.subtract()
是这里的关键:传递一个与现有Counter
实例具有相同关键元素的列表,它将每个键的计数减少它在新列表中出现的次数。要创建此列表,请使用列表推导使每个键的次数等于最不频繁键的计数(根据您的要求调整,如果该计数超过某个阈值,则最终结果应该有一次出现键)。嵌套列表理解只是我最喜欢的展平列表的方式 - 密钥的重复最初是作为自己的列表创建的。
最后,Counter.elements()
会为您提供一个与您开始时相似的列表:每个键的显示次数等于其次数。
from collections import Counter
def normalize_list(L, threshold):
cntr = Counter(L)
least_count = cntr.most_common()[-1][1]
if least_count > threshold:
least_count -= 1
cntr.subtract([item for k in cntr.keys() for item in [k] * least_count])
return list(cntr.elements())
>>> a, b, c, d, e = 'abcde'
>>> normalize_list([a, a, a, a, a, b, b, b, b, c, c, c, d, d], 10)
['a', 'a', 'a', 'c', 'b', 'b']
>>> normalize_list(your_list, 6)
[u'laboratori', u'releas', u'want', u'want', u'want', u'want', u'want', u'want', u'want', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'crime', u'boston', u'boston', u'boston', u'boston', u'boston', u'boston', u'boston', u'2011', u'2011', u'2011', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'tsarnaev', u'investig', u'investig', u'investig', u'investig', u'investig', u'investig', u'investig', u'may', u'govern', u'govern', u'govern', u'govern', u'govern', u'press', u'press', u'press', u'press', u'press', u'press', u'press', u'press', u'news', u'news', u'news', u'news', u'news', u'news', u'news', u'news', u'news', u'tamerlan', u'tamerlan', u'tamerlan', u'tamerlan', u'tamerlan', u'servic', u'servic', u'servic', u'servic', u'servic', u'servic', u'servic', u'servic', u'servic', u'servic', u'foreign', u'foreign', u'foreign', u'foreign', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform', u'inform']
当然,这并不保留原始列表的顺序。
答案 3 :(得分:1)
冒着过于简单化的风险,似乎leanmodel = model[::2]
通常会做大概你想做的事情(在这个例子中,它完全符合你的要求)。
编辑:现在知道排序不重要,我补充说:你应该首先对模型进行排序。这很容易封装在Python3或Python 2.7中 - leanmodel = sorted(model)[::2]
- 在早期版本的Python2中稍微简单一些。
一般来说,这是1d最近邻采样问题(这就是leanmodel = model[::2]
可能足够准确的原因。)