1

これは私が長い間頭を悩ませてきた問題なので、どんな助けでも素晴らしいでしょう。次の形式の複数の行を含むファイルがあります(単語、単語が出現した時間、および特定のインスタンス内の特定の単語を含むドキュメントの頻度)。以下は、inputfileがどのように見えるかの例です。

#inputfile
<word, time, frequency>
apple, 1, 3
banana, 1, 2
apple, 2, 1
banana, 2, 4
orange, 3, 1

以下にPythonクラスがあり、キーとして使用し、値として頻度を使用して上記のファイルを格納するための2次元辞書を作成するために使用しました。

class Ddict(dict):
    '''
    2D dictionary class
    '''
    def __init__(self, default=None):
            self.default = default

    def __getitem__(self, key):
            if not self.has_key(key):
                self[key] = self.default()
            return dict.__getitem__(self, key)


wordtime=Ddict(dict) # Store each inputfile entry with a <word,time> key
timeword=Ddict(dict) # Store each inputfile entry with a <time,word> key

# Loop over every line of the inputfile
for line in open('inputfile'):
    word,time,count=line.split(',')

    # If <word,time> already a key, increment count
    try:
        wordtime[word][time]+=count
    # Otherwise, create the key
    except KeyError:
        wordtime[word][time]=count

    # If <time,word> already a key, increment count     
    try:
        timeword[time][word]+=count
    # Otherwise, create the key
    except KeyError:
        timeword[time][word]=count

私が持っている質問は、この2D辞書のエントリを反復処理しながら特定のものを計算することに関するものです。各時間「t」での各単語「w」について、以下を計算します。

  1. 時間「t」 の単語「w」を含むドキュメントの数。(a)
  2. 時間「t」に 単語「w」がないドキュメントの数。(b)
  3. 時間「t」以外 の単語「w」を含むドキュメントの数。(c)
  4. 時間't'以外 の単語'w'のないドキュメントの数。(d)

上記の各項目は、各単語と時間のカイ2乗分割表のセルの1つを表しています。これらすべてを単一のループ内で計算できますか、それとも一度に1つずつ実行する必要がありますか?

理想的には、出力を以下のようにしたいと思います。ここで、a、b、c、dは、上記で計算されたすべての項目です。

print "%s, %s, %s, %s" %(a,b,c,d)

上記の入力ファイルの場合、時間「1」で単語「apple」の分割表を見つけようとした結果は、になります(3,2,1,6)。各セルの計算方法を説明します。

  • 「3」ドキュメントには、時間「1」内に「apple」が含まれています。
  • 時間「1」内に「apple」を含まない「2」ドキュメントがあります。
  • 時間「1」の外に「apple」を含む「1」ドキュメントがあります。
  • 「apple」(1 + 4 + 1)という単語を含まない「1」以外の6つのドキュメントがあります。
4

1 に答える 1

2

apple / 1の4つの数値を合計すると、観測の総数(11)よりも12になります。「apple」という単語を含まない「1」以外のドキュメントは5つだけです。

観測値を4つの互いに素なサブセットに分割する必要があります。a
:リンゴと1 => 3
b:リンゴではなく1 => 2
c:リンゴとnot-1 => 1
d:リンゴではなく-1 => 5

これを行う1つの方法を示すコードを次に示します。

from collections import defaultdict

class Crosstab(object):

    def __init__(self):
        self.count = defaultdict(lambda: defaultdict(int))
        self.row_tot = defaultdict(int)
        self.col_tot = defaultdict(int)
        self.grand_tot = 0

    def add(self, r, c, n):
        self.count[r][c] += n
        self.row_tot[r] += n
        self.col_tot[c] += n
        self.grand_tot += n

def load_data(line_iterator, conv_funcs):
    ct = Crosstab()
    for line in line_iterator:
        r, c, n = [func(s) for func, s in zip(conv_funcs, line.split(','))]
        ct.add(r, c, n)
    return ct

def display_all_2x2_tables(crosstab):
    for rx in crosstab.row_tot:
        for cx in crosstab.col_tot:
            a = crosstab.count[rx][cx]
            b = crosstab.col_tot[cx] - a
            c = crosstab.row_tot[rx] - a
            d = crosstab.grand_tot - a - b - c
            assert all(x >= 0 for x in (a, b, c, d))
            print ",".join(str(x) for x in (rx, cx, a, b, c, d))

if __name__ == "__main__":

    # inputfile
    # <word, time, frequency>
    lines = """\
    apple, 1, 3
    banana, 1, 2
    apple, 2, 1
    banana, 2, 4
    orange, 3, 1""".splitlines()

    ct = load_data(lines, (str.strip, int, int))
    display_all_2x2_tables(ct)

そしてここに出力があります:

orange,1,0,5,1,5
orange,2,0,5,1,5
orange,3,1,0,0,10
apple,1,3,2,1,5
apple,2,1,4,3,3
apple,3,0,1,4,6
banana,1,2,3,4,2
banana,2,4,1,2,4
banana,3,0,1,6,4
于 2010-06-13T00:49:12.970 に答える