0

私の問題は次のとおりです。次のようなURLの長いリストがあります。

www.foo.com/davidbobmike1joe
www.foo.com/mikejoe2bobkarl
www.foo.com/joemikebob
www.foo.com/bobjoe

そのリスト内のすべてのエントリ(URL)を相互に比較し、それらのURLのサブドメイン(この場合はdavid、joe、bob、mike、karl)のキーワードを抽出し、頻度で並べ替える必要があります。私はnltkのようないくつかのライブラリについて読んでいます。ただし、ここでの問題は、各単語を個別にトークン化するスペースがないことです。仕事を成し遂げる方法について何かアドバイスはありますか?

4

2 に答える 2

1

概要

このコードを使用して名前を抽出し、[david、bobなど]のリストを渡すことができます。

Pythonでスペースのない文から単語の可能性のあるリストを生成する簡単な方法はありますか?

そして、collections.Counter周波数を取得するために使用します。

コード

from Bio import trie
import string
from collections import Counter


def get_trie(words):
    tr = trie.trie()
    for word in words:
        tr[word] = len(word)
    return tr

def get_trie_word(tr, s):
    for end in reversed(range(len(s))):
        word = s[:end + 1]
        if tr.has_key(word): 
            return word, s[end + 1: ]
    return None, s

def get_trie_words(s):
    names = ['david', 'bob', 'karl', 'joe', 'mike']
    tr = get_trie(names)
    while s:
        word, s = get_trie_word(tr, s)
        yield word

def main(urls):
    d = Counter()
    for url in urls:
        url = "".join(a for a in url if a in string.lowercase)
        for word in get_trie_words(url):
            d[word] += 1
    return d

if __name__ == '__main__':
    urls = [
        "davidbobmike1joe",
        "mikejoe2bobkarl",
        "joemikebob",
        "bobjoe",
    ]
    print main(urls)

結果

Counter({'bob': 4, 'joe': 4, 'mike': 3, 'karl': 1, 'david': 1})
于 2013-03-12T21:41:09.220 に答える
1

制限事項

辞書の使用を拒否した場合、アルゴリズムには多くの計算が必要になります。その上では、1回だけ出現するキーワード(例: "karl")とくだらないシーケンス(例: "e2bo")を区別することはできません。私の解決策は最善の努力であり、URLのリストにキーワードが複数回含まれている場合にのみ機能します。

基本的な考え方

単語は、少なくとも3文字の頻繁に出現する文字のシーケンスであると想定しています。これにより、文字「o」が最も人気のある単語になるのを防ぎます。

基本的な考え方は次のとおりです。

  • n文字のシーケンスをすべてカウントし、複数回発生する1つを選択します。
  • より大きなシーケンスの一部であるすべてのシーケンスをカットします。
  • 人気順に並べると、問題の解決に近い解決策が得られます。(読者への演習として残します)

コード内

import operator

sentences = ["davidbobmike1joe" , "mikejoe2bobkarl", "joemikebob", "bobjoe", "bobbyisawesome", "david", "bobbyjoe"];
dict = {}

def countWords(n):
    """Count all possible character sequences/words of length n occuring in all given sentences"""
    for sentence in sentences:
        countWordsSentence(sentence, n);

def countWordsSentence(sentence, n):
    """Count all possible character sequence/words of length n occuring in a sentence"""
    for i in range(0,len(sentence)-n+1):
        word = sentence[i:i+n]
        if word not in dict:
            dict[word] = 1;
        else:
            dict[word] = dict[word] +1;

def cropDictionary():
    """Removes all words that occur only once."""
    for key in dict.keys():
        if(dict[key]==1):
            dict.pop(key);

def removePartials(word):
    """Removes all the partial occurences of a given word from the dictionary."""
    for i in range(3,len(word)):
        for j in range(0,len(word)-i+1):
            for key in dict.keys():
               if key==word[j:j+i] and dict[key]==dict[word]:
                   dict.pop(key);

def removeAllPartials():
    """Removes all partial words in the dictionary"""
    for word in dict.keys():
        removePartials(word);

for i in range(3,max(map(lambda x: len(x), sentences))):
    countWords(i);
    cropDictionary();
    removeAllPartials();

print dict;

出力

>>> print dict;
{'mike': 3, 'bobby': 2, 'david': 2, 'joe': 5, 'bob': 6}

読者へのいくつかの課題

  • 印刷する前に、辞書を値で並べ替えます。(Python辞書を値で並べ替えます
  • この例では、「bob」は6回出現し、2回は「bobby」の部分的な単語です。これに問題があるかどうかを判断し、必要に応じて修正します。
  • キャピタライゼーションを考慮に入れてください。
于 2013-03-12T23:42:08.807 に答える