Selama hampir tiga tahun sekarang, saya telah dengan cermat mencatat semua pendapatan dan pengeluaran saya di hledger . Kenapa tepatnya dia? Itu terjadi secara historis. Pada awal 2018, saya mulai menulis semuanya di Google, dan pada bulan April saya pergi ke Jepang. Saya sedang duduk di hotel dan mencoba mencari cara untuk menghitung harga dengan benar dalam berbagai mata uang, dan memutuskan untuk menulis sesuatu di Lisp. Dan dia menulis . Dan dia menunjukkannya kepada orang-orang di obrolan email. Yang saya terima jawabannya "tapi sudah ada yang siap pakai" dan link ke hledger. Lalu saya menyeret semua entri saya dari pelat google ke hledger.
Yang saya sukai dari cara menghitung pengeluaran ini adalah kemampuannya untuk keluar dan menulis ulang sejarah. Jadi saya memutuskan bahwa headphone yang dibeli tahun lalu untuk istri saya harus ditulis bukan sebagai "teknik", tetapi sebagai "hadiah" - tidak masalah.
Dan ketika belajar di beberapa titik cek dari Platipus, saya berpikir, berapa banyak yang saya habiskan untuk cokelat? Spoiler - banyak. Saya memeriksa riwayat pesanan, menemukan tanda terima lama di sana, menulis ulang entri berdasarkan kategori. Tadinya hanya "pengeluaran: makanan", tapi sekarang "pengeluaran: makanan: buah-buahan" dan lain-lain. Bersamaan dengan itu, beberapa barang rumah tangga juga ditemukan di sana.
Pertama kali saya melakukan penulisan ulang ini sepenuhnya dengan tangan. Artinya, dia pulang dari toko, melihat cek dan menuliskan banyak baris. Kemudian saya mengotomatiskan sedikit - saya membuat template untuk piring di emacs, di mana baris berisi produk dengan kategori dan harganya, dan di kolom terakhir, filter menurut kategori langsung memberikan jumlahnya.
Tapi jaringan saraf dan penyatan data lainnya.
Sebuah gagasan muncul di kepala saya bahwa jaringan saraf cukup dapat memahami bahwa "GL.VIL.Oranges SELECT.fas.1kg" adalah buah seperti itu, tidak seperti "BOTTOM.HL.aton PODMOSKOVNY 400g" (roti, tetapi untuk ini saya harus menyalin ini adalah nama di google).
Masalah yang harus dipecahkan jelas adalah klasifikasi. Nama baris dikirimkan ke input, dan kategori diharapkan pada output. Awalnya, saya akan menempatkan kategori ini secara manual, lalu hanya mengedit prediksi. Oleh karena itu, program harus menganalisis teks cek terlebih dahulu, memilih nama produk dan harganya dari sana, memprediksi kategori untuk setiap nama. Tunjukkan prediksi agar saya bisa memperbaikinya. Jika semuanya sudah beres, buatlah garis untuk hledger.
, . , .
def parse_utk(lines):
while lines:
if lines[0].startswith(' '):
break
lines.pop(0)
else:
return
lines.pop(0)
result = []
while lines:
data = lines[0:6]
name, price, lines = lines[0], lines[3], lines[6:]
if name.startswith(''):
break
assert price.startswith('= ')
result.append((name, Decimal(price[2:]))
return result, . .
, . , character-level , flair. – . – . , , .
, . " ", . . . 23 21. – .
hledger.
$ hledger bal -b thisyear -% -S
100.0 % expenses:
20.6 % <unsorted>
15.3 %
7.9 %
7.1 %
6.9 %
6.3 %
5.2 %
4.8 %
4.0 %
3.8 %
2.7 %
2.7 %
2.0 %
2.0 %
1.7 %
1.6 %
1.3 %
1.2 %
0.9 %
0.9 %
0.5 %
0.4 %
0.2 % , . . , ( ) .
. , . , ?
– , . rule-based . ( - ) , ? , .
– NER. flair, ( ? ). . , IOB- … , .
rule-based , . . , "" . , . , , , . -, rule-based .
, . , . , . flair SpaceTokenizer, , . " ". , .
- - : " , , , ". , "1 107 99" , 107 99 . , ( ). ? , , .
, . . – " ", " " " ". NER . " " "".
. , (, , NewlineTokenizer), . , ColumnCorpus . \r, , . vertical tab (\x0b), RS US.
- , . , O, . , , . , , , .
, 'entry' 'entry'. – . 'O', , 'O\n', .
, . – flair.
. – , "" . .
rule-based , "" . , , rule-based . , , , rule-based .
Satu cek sudah cukup untuk melatih pemberi tag. Benar, pertama-tama saya harus menyelesaikan skrip untuk mengedit hasil antara, dan kemudian menyimpannya dalam format yang benar (saya berhasil melupakan pemisah kolom khusus dan tidak mengerti selama satu jam mengapa tidak ada yang berhasil). Tetap hanya untuk mengencangkan partisi "jaringan saraf" ke parser utama.
Kemudian sisir kode dan publikasikan.
Sumber PS