Normalizer¶
This tutorial is available as an IPython notebook at Malaya/example/normalizer.
[1]:
%%time
import malaya
CPU times: user 4.85 s, sys: 667 ms, total: 5.51 s
Wall time: 4.51 s
[2]:
string1 = 'xjdi ke, y u xsuke makan HUSEIN kt situ tmpt, i hate it. pelikle, pada'
string2 = 'i mmg2 xske mknn HUSEIN kampng tmpat, i love them. pelikle saye'
string3 = 'perdana menteri ke11 sgt suka makn ayam, harganya cuma rm15.50'
string4 = 'pada 10/4, kementerian mengumumkan, 1/100'
string5 = 'Husein Zolkepli dapat tempat ke-12 lumba lari hari ni'
string6 = 'Husein Zolkepli (2011 - 2019) adalah ketua kampng di kedah sekolah King Edward ke-IV'
string7 = '2jam 30 minit aku tunggu kau, 60.1 kg kau ni, suhu harini 31.2c, aku dahaga minum 600ml'
Load normalizer¶
This normalizer can load any spelling correction model, eg, malaya.spell.probability
, or malaya.spell.transformer
.
[3]:
corrector = malaya.spell.probability()
normalizer = malaya.normalize.normalizer(corrector)
normalize¶
def normalize(
self,
string: str,
check_english: bool = True,
normalize_text: bool = True,
normalize_entity: bool = True,
normalize_url: bool = False,
normalize_email: bool = False,
normalize_year: bool = True,
normalize_telephone: bool = True,
logging: bool = False,
):
"""
Normalize a string.
Parameters
----------
string : str
check_english: bool, (default=True)
check a word in english dictionary.
normalize_text: bool, (default=True)
if True, will try to replace shortforms with internal corpus.
normalize_entity: bool, (default=True)
normalize entities, only effect `date`, `datetime`, `time` and `money` patterns string only.
normalize_url: bool, (default=False)
if True, replace `://` with empty and `.` with `dot`.
`https://huseinhouse.com` -> `https huseinhouse dot com`.
normalize_email: bool, (default=False)
if True, replace `@` with `di`, `.` with `dot`.
`husein.zol05@gmail.com` -> `husein dot zol kosong lima di gmail dot com`.
normalize_year: bool, (default=True)
if True, `tahun 1987` -> `tahun sembilan belas lapan puluh tujuh`.
if True, `1970-an` -> `sembilan belas tujuh puluh an`.
if False, `tahun 1987` -> `tahun seribu sembilan ratus lapan puluh tujuh`.
normalize_telephone: bool, (default=True)
if True, `no 012-1234567` -> `no kosong satu dua, satu dua tiga empat lima enam tujuh`
logging: bool, (default=False)
if True, will log index and token queue using `logging.warn`.
Returns
-------
string: normalized string
"""
[4]:
string = 'boleh dtg 8pagi esok tak atau minggu depan? 2 oktober 2019 2pm, tlong bayar rm 3.2k sekali tau'
[5]:
normalizer.normalize(string)
[5]:
{'normalize': 'boleh datang lapan pagi esok tidak atau minggu depan ? 02/10/2019 14:00:00 , tolong bayar tiga ribu dua ratus ringgit sekali tahu',
'date': {'8 AM esok': datetime.datetime(2021, 1, 1, 8, 0),
'2 oktober 2019 2pm': datetime.datetime(2019, 10, 2, 14, 0),
'minggu depan': datetime.datetime(2021, 1, 7, 19, 33, 47, 65094)},
'money': {'rm 3.2k': 'RM3200.0'}}
[6]:
normalizer.normalize(string, normalize_entity = False)
[6]:
{'normalize': 'boleh datang lapan pagi esok tidak atau minggu depan ? 02/10/2019 14:00:00 , tolong bayar tiga ribu dua ratus ringgit sekali tahu',
'date': {},
'money': {}}
Here you can see, Malaya normalizer will normalize minggu depan
to datetime object, also 3.2k ringgit
to RM3200
[7]:
print(normalizer.normalize(string1))
print(normalizer.normalize(string2))
print(normalizer.normalize(string3))
print(normalizer.normalize(string4))
print(normalizer.normalize(string5))
print(normalizer.normalize(string6))
print(normalizer.normalize(string7))
{'normalize': 'tak jadi ke , kenapa awak tak suka makan HUSEIN kat situ tempat , saya hate it . pelik lah , pada', 'date': {}, 'money': {}}
{'normalize': 'saya memang-memang tak suka makan HUSEIN kampung tempat , saya love them . pelik lah saya', 'date': {}, 'money': {}}
{'normalize': 'perdana menteri kesebelas sangat suka makan ayam , harganya cuma lima belas ringgit lima puluh sen', 'date': {}, 'money': {'rm15.50': 'RM15.50'}}
{'normalize': 'pada sepuluh hari bulan empat , kementerian mengumumkan , satu per seratus', 'date': {}, 'money': {}}
{'normalize': 'Husein Zolkepli dapat tempat kedua belas lumba lari hari ini', 'date': {}, 'money': {}}
{'normalize': 'Husein Zolkepli ( dua ribu sebelas hingga dua ribu sembilan belas ) adalah ketua kampung di kedah sekolah King Edward keempat', 'date': {}, 'money': {}}
{'normalize': 'dua jam tiga puluh minit aku tunggu kamu , enam puluh perpuluhan satu kilogram kamu ini , suhu hari ini tiga puluh satu perpuluhan dua celsius , aku dahaga minum enam ratus milliliter', 'date': {}, 'money': {}}
Skip spelling correction¶
Simply pass None
to speller
to normalizer = malaya.normalize.normalizer
. By default it is None
.
[8]:
normalizer = malaya.normalize.normalizer(corrector)
without_corrector_normalizer = malaya.normalize.normalizer(None)
[9]:
normalizer.normalize(string2)
[9]:
{'normalize': 'saya memang-memang tak suka makan HUSEIN kampung tempat , saya love them . pelik lah saya',
'date': {},
'money': {}}
[10]:
without_corrector_normalizer.normalize(string2)
[10]:
{'normalize': 'saya memang-memang tak suka mknn HUSEIN kampng tmpat , saya love them . pelik lah saya',
'date': {},
'money': {}}
Pass kwargs preprocessing¶
Let say you want to skip to normalize date pattern, you can pass kwargs to normalizer, check original tokenizer implementation at https://github.com/huseinzol05/Malaya/blob/master/malaya/preprocessing.py#L103
[11]:
normalizer = malaya.normalize.normalizer(corrector)
skip_date_normalizer = malaya.normalize.normalizer(corrector, date = False)
[12]:
normalizer.normalize('tarikh program tersebut 14 mei')
[12]:
{'normalize': 'tarikh program tersebut 14/05/2020',
'date': {'14 mei': datetime.datetime(2020, 5, 14, 0, 0)},
'money': {}}
[13]:
skip_date_normalizer.normalize('tarikh program tersebut 14 mei')
[13]:
{'normalize': 'tarikh program tersebut empat belas mei',
'date': {'14 mei': datetime.datetime(2020, 5, 14, 0, 0)},
'money': {}}
Normalize url¶
Let say you have an url
word, example, https://huseinhouse.com
, this parameter going to,
replace
://
with empty string.replace
.
withdot
.replace digits with string representation.
Simply normalizer.normalize(string, normalize_url = True)
, default is False
.
[14]:
normalizer = malaya.normalize.normalizer()
normalizer.normalize('web saya ialah https://huseinhouse.com')
[14]:
{'normalize': 'web saya ialah https://huseinhouse.com',
'date': {},
'money': {}}
[15]:
normalizer.normalize('web saya ialah https://huseinhouse.com', normalize_url = True)
[15]:
{'normalize': 'web saya ialah https huseinhouse dot com',
'date': {},
'money': {}}
[16]:
normalizer.normalize('web saya ialah https://huseinhouse02934.com', normalize_url = True)
[16]:
{'normalize': 'web saya ialah https huseinhouse kosong dua sembilan tiga empat dot com',
'date': {},
'money': {}}
Normalize email¶
Let say you have an email
word, example, husein.zol05@gmail.com
, this parameter going to,
replace
://
with empty string.replace
.
withdot
.replace
@
withdi
.replace digits with string representation.
Simply normalizer.normalize(string, normalize_email = True)
, default is False
.
[17]:
normalizer = malaya.normalize.normalizer()
normalizer.normalize('email saya ialah husein.zol05@gmail.com')
[17]:
{'normalize': 'email saya ialah husein.zol05@gmail.com',
'date': {},
'money': {}}
[18]:
normalizer = malaya.normalize.normalizer()
normalizer.normalize('email saya ialah husein.zol05@gmail.com', normalize_email = True)
[18]:
{'normalize': 'email saya ialah husein dot zol kosong lima di gmail dot com',
'date': {},
'money': {}}
Normalize year¶
if True,
tahun 1987
->tahun sembilan belas lapan puluh tujuh
.if True,
1970-an
->sembilan belas tujuh puluh an
.if False,
tahun 1987
->tahun seribu sembilan ratus lapan puluh tujuh
.
Simply normalizer.normalize(string, normalize_year = True)
, default is True
.
[19]:
normalizer = malaya.normalize.normalizer()
[20]:
normalizer.normalize('$400 pada tahun 1998 berbanding lebih $1000')
[20]:
{'normalize': 'empat ratus dollar pada tahun sembilan belas sembilan puluh lapan berbanding lebih seribu dollar',
'date': {},
'money': {'$400': '$400', '$1000': '$1000'}}
[21]:
normalizer.normalize('$400 pada 1970-an berbanding lebih $1000')
[21]:
{'normalize': 'empat ratus dollar pada sembilan belas tujuh puluhan berbanding lebih seribu dollar',
'date': {},
'money': {'$400': '$400', '$1000': '$1000'}}
[22]:
normalizer.normalize('$400 pada tahun 1970-an berbanding lebih $1000')
[22]:
{'normalize': 'empat ratus dollar pada tahun sembilan belas tujuh puluhan berbanding lebih seribu dollar',
'date': {},
'money': {'$400': '$400', '$1000': '$1000'}}
[23]:
normalizer.normalize('$400 pada tahun 1998 berbanding lebih $1000', normalize_year = False)
[23]:
{'normalize': 'empat ratus dollar pada tahun seribu sembilan ratus sembilan puluh lapan berbanding lebih seribu dollar',
'date': {},
'money': {'$400': '$400', '$1000': '$1000'}}
Normalize telephone¶
if True,
no 012-1234567
->no kosong satu dua, satu dua tiga empat lima enam tujuh
.
Simply normalizer.normalize(string, normalize_telephone = True)
, default is True
.
[24]:
normalizer = malaya.normalize.normalizer()
[25]:
normalizer.normalize('no saya 012-1234567')
[25]:
{'normalize': 'no saya kosong satu dua, satu dua tiga empat lima enam tujuh',
'date': {},
'money': {}}
[26]:
normalizer.normalize('no saya 012-1234567', normalize_telephone = False)
[26]:
{'normalize': 'no saya 012-1234567', 'date': {}, 'money': {}}
Ignore normalize money¶
Let say I have a text contains RM 77 juta
and I wish to maintain it like that.
[27]:
text = 'Suatu ketika rakyat Malaysia dikejutkan dengan kontrak pelantikan sebanyak hampir RM 77 juta setahun yang hanya terdedah apabila diasak oleh Datuk Seri Anwar Ibrahim.'
[28]:
normalizer = malaya.normalize.normalizer()
[29]:
normalizer.normalize(text)
[29]:
{'normalize': 'Suatu ketika rakyat Malaysia dikejutkan dengan kontrak pelantikan sebanyak hampir tujuh puluh tujuh ringgit juta setahun yang hanya terdedah apabila diasak oleh Datuk Seri Anwar Ibrahim .',
'date': {},
'money': {'rm 77': 'RM77'}}
[30]:
normalizer = malaya.normalize.normalizer(money = False)
normalizer.normalize(text, normalize_text = False, check_english = False)
[30]:
{'normalize': 'Suatu ketika rakyat Malaysia dikejutkan dengan kontrak pelantikan sebanyak hampir RM tujuh puluh tujuh juta setahun yang hanya terdedah apabila diasak oleh Datuk Seri Anwar Ibrahim .',
'date': {},
'money': {}}
[31]:
normalizer.normalize(text, normalize_text = False, check_english = False)
[31]:
{'normalize': 'Suatu ketika rakyat Malaysia dikejutkan dengan kontrak pelantikan sebanyak hampir RM tujuh puluh tujuh juta setahun yang hanya terdedah apabila diasak oleh Datuk Seri Anwar Ibrahim .',
'date': {},
'money': {}}
Normalizing rules¶
All these rules will ignore if first letter is capital except for normalizing titles.
1. Normalize title,¶
{
'dr': 'Doktor',
'yb': 'Yang Berhormat',
'hj': 'Haji',
'ybm': 'Yang Berhormat Mulia',
'tyt': 'Tuan Yang Terutama',
'yab': 'Yang Berhormat',
'ybm': 'Yang Berhormat Mulia',
'yabhg': 'Yang Amat Berbahagia',
'ybhg': 'Yang Berbahagia',
'miss': 'Cik',
}
[32]:
normalizer = malaya.normalize.normalizer()
[33]:
normalizer.normalize('Dr yahaya')
[33]:
{'normalize': 'Doktor yahaya', 'date': {}, 'money': {}}
2. expand x
¶
[34]:
normalizer.normalize('xtahu')
[34]:
{'normalize': 'tak tahu', 'date': {}, 'money': {}}
3. normalize ke -
¶
[35]:
normalizer.normalize('ke-12')
[35]:
{'normalize': 'kedua belas', 'date': {}, 'money': {}}
[36]:
normalizer.normalize('ke - 12')
[36]:
{'normalize': 'kedua belas', 'date': {}, 'money': {}}
4. normalize ke - roman
¶
[37]:
normalizer.normalize('ke-XXI')
[37]:
{'normalize': 'kedua puluh satu', 'date': {}, 'money': {}}
[38]:
normalizer.normalize('ke - XXI')
[38]:
{'normalize': 'kedua puluh satu', 'date': {}, 'money': {}}
5. normalize NUM - NUM
¶
[39]:
normalizer.normalize('2011 - 2019')
[39]:
{'normalize': 'dua ribu sebelas hingga dua ribu sembilan belas',
'date': {},
'money': {}}
[40]:
normalizer.normalize('2011.01-2019')
[40]:
{'normalize': 'dua ribu sebelas perpuluhan kosong satu hingga dua ribu sembilan belas',
'date': {},
'money': {}}
6. normalize pada NUM (/ | -) NUM
¶
[41]:
normalizer.normalize('pada 10/4')
[41]:
{'normalize': 'pada sepuluh hari bulan empat', 'date': {}, 'money': {}}
[42]:
normalizer.normalize('PADA 10 -4')
[42]:
{'normalize': 'pada sepuluh hari bulan empat', 'date': {}, 'money': {}}
7. normalize NUM / NUM
¶
[43]:
normalizer.normalize('10 /4')
[43]:
{'normalize': 'sepuluh per empat', 'date': {}, 'money': {}}
8. normalize rm NUM
¶
[44]:
normalizer.normalize('RM10.5')
[44]:
{'normalize': 'sepuluh ringgit lima puluh sen',
'date': {},
'money': {'rm10.5': 'RM10.5'}}
9. normalize rm NUM sen
¶
[45]:
normalizer.normalize('rm 10.5 sen')
[45]:
{'normalize': 'sepuluh ringgit lima puluh sen',
'date': {},
'money': {'rm 10.5': 'RM10.5'}}
10. normalize NUM sen
¶
[46]:
normalizer.normalize('1015 sen')
[46]:
{'normalize': 'sepuluh ringgit lima belas sen',
'date': {},
'money': {'1015 sen': 'RM10.15'}}
11. normalize money¶
[47]:
normalizer.normalize('rm10.4m')
[47]:
{'normalize': 'sepuluh juta empat ratus ribu ringgit',
'date': {},
'money': {'rm10.4m': 'RM10400000.0'}}
[48]:
normalizer.normalize('$10.4K')
[48]:
{'normalize': 'sepuluh ribu empat ratus dollar',
'date': {},
'money': {'$10.4k': '$10400.0'}}
12. normalize cardinal¶
[49]:
normalizer.normalize('123')
[49]:
{'normalize': 'seratus dua puluh tiga', 'date': {}, 'money': {}}
13. normalize ordinal¶
[50]:
normalizer.normalize('ke123')
[50]:
{'normalize': 'keseratus dua puluh tiga', 'date': {}, 'money': {}}
14. normalize date / time / datetime string to datetime.datetime¶
[51]:
normalizer.normalize('2 hari lepas')
[51]:
{'normalize': 'dua hari lepas',
'date': {'2 hari lalu': datetime.datetime(2020, 12, 29, 19, 33, 47, 507552)},
'money': {}}
[52]:
normalizer.normalize('esok')
[52]:
{'normalize': 'esok',
'date': {'esok': datetime.datetime(2021, 1, 1, 19, 33, 47, 514754)},
'money': {}}
[53]:
normalizer.normalize('okt 2019')
[53]:
{'normalize': '31/10/2019',
'date': {'okt 2019': datetime.datetime(2019, 10, 31, 0, 0)},
'money': {}}
[54]:
normalizer.normalize('2pgi')
[54]:
{'normalize': 'dua pagi',
'date': {'2 AM': datetime.datetime(2020, 12, 31, 2, 0)},
'money': {}}
[55]:
normalizer.normalize('pukul 8 malam')
[55]:
{'normalize': 'pukul lapan malam',
'date': {'pukul 8': datetime.datetime(2020, 12, 8, 0, 0)},
'money': {}}
[56]:
normalizer.normalize('jan 2 2019 12:01pm')
[56]:
{'normalize': '02/01/2019 12:01:00',
'date': {'jan 2 2019 12:01pm': datetime.datetime(2019, 1, 2, 12, 1)},
'money': {}}
[57]:
normalizer.normalize('2 ptg jan 2 2019')
[57]:
{'normalize': 'dua ptg 02/01/2019',
'date': {'2 PM jan 2 2019': datetime.datetime(2019, 1, 2, 14, 0)},
'money': {}}
15. normalize money string to string number representation¶
[58]:
normalizer.normalize('50 sen')
[58]:
{'normalize': 'lima puluh sen', 'date': {}, 'money': {'50 sen': 'RM0.5'}}
[59]:
normalizer.normalize('20.5 ringgit')
[59]:
{'normalize': 'dua puluh ringgit lima puluh sen',
'date': {},
'money': {'20.5 ringgit': 'RM20.5'}}
[60]:
normalizer.normalize('20m ringgit')
[60]:
{'normalize': 'dua puluh juta ringgit',
'date': {},
'money': {'20m ringgit': 'RM20000000.0'}}
[61]:
normalizer.normalize('22.5123334k ringgit')
[61]:
{'normalize': 'dua puluh dua ribu lima ratus dua belas ringgit tiga ratus tiga puluh empat sen',
'date': {},
'money': {'22.512334k ringgit': 'RM22512.334'}}
16. normalize date string to %d/%m/%y¶
[62]:
normalizer.normalize('1 nov 2019')
[62]:
{'normalize': '01/11/2019',
'date': {'1 nov 2019': datetime.datetime(2019, 11, 1, 0, 0)},
'money': {}}
[63]:
normalizer.normalize('januari 1 1996')
[63]:
{'normalize': '01/01/1996',
'date': {'januari 1 1996': datetime.datetime(1996, 1, 1, 0, 0)},
'money': {}}
[64]:
normalizer.normalize('januari 2019')
[64]:
{'normalize': '31/01/2019',
'date': {'januari 2019': datetime.datetime(2019, 1, 31, 0, 0)},
'money': {}}
17. normalize time string to %H:%M:%S¶
[65]:
normalizer.normalize('2pm')
[65]:
{'normalize': '14:00:00',
'date': {'2pm': datetime.datetime(2020, 12, 31, 14, 0)},
'money': {}}
[66]:
normalizer.normalize('2:01pm')
[66]:
{'normalize': '14:01:00',
'date': {'2:01pm': datetime.datetime(2020, 12, 31, 14, 1)},
'money': {}}
[67]:
normalizer.normalize('2AM')
[67]:
{'normalize': '02:00:00',
'date': {'2am': datetime.datetime(2020, 12, 31, 2, 0)},
'money': {}}
18. expand repetition shortform¶
[68]:
normalizer.normalize('skit2')
[68]:
{'normalize': 'sakit-sakit', 'date': {}, 'money': {}}
[69]:
normalizer.normalize('xskit2')
[69]:
{'normalize': 'tak sakit-sakit', 'date': {}, 'money': {}}
[70]:
normalizer.normalize('xjdi2')
[70]:
{'normalize': 'tak jadi-jadi', 'date': {}, 'money': {}}
[71]:
normalizer.normalize('xjdi4')
[71]:
{'normalize': 'tak jadi-jadi-jadi-jadi', 'date': {}, 'money': {}}
[72]:
normalizer.normalize('xjdi0')
[72]:
{'normalize': 'tak jadi', 'date': {}, 'money': {}}
[73]:
normalizer.normalize('xjdi')
[73]:
{'normalize': 'tak jadi', 'date': {}, 'money': {}}
19. normalize NUM SI-UNIT
¶
[74]:
normalizer.normalize('61.2 kg')
[74]:
{'normalize': 'enam puluh satu perpuluhan dua kilogram',
'date': {},
'money': {}}
[75]:
normalizer.normalize('61.2kg')
[75]:
{'normalize': 'enam puluh satu perpuluhan dua kilogram',
'date': {},
'money': {}}
[76]:
normalizer.normalize('61kg')
[76]:
{'normalize': 'enam puluh satu kilogram', 'date': {}, 'money': {}}
[77]:
normalizer.normalize('61ml')
[77]:
{'normalize': 'enam puluh satu milliliter', 'date': {}, 'money': {}}
[78]:
normalizer.normalize('61m')
[78]:
{'normalize': 'enam puluh satu meter', 'date': {}, 'money': {}}
[79]:
normalizer.normalize('61.3434km')
[79]:
{'normalize': 'enam puluh satu perpuluhan tiga empat tiga empat kilometer',
'date': {},
'money': {}}
[80]:
normalizer.normalize('61.3434c')
[80]:
{'normalize': 'enam puluh satu perpuluhan tiga empat tiga empat celsius',
'date': {},
'money': {}}
[81]:
normalizer.normalize('61.3434 c')
[81]:
{'normalize': 'enam puluh satu perpuluhan tiga empat tiga empat celsius',
'date': {},
'money': {}}
20. normalize laughing
pattern¶
[82]:
normalizer.normalize('dia sakai wkwkwkawkw')
[82]:
{'normalize': 'dia sakai haha', 'date': {}, 'money': {}}
[83]:
normalizer.normalize('dia sakai hhihihu')
[83]:
{'normalize': 'dia sakai haha', 'date': {}, 'money': {}}
21. normalize mengeluh
pattern¶
[84]:
normalizer.normalize('Haih apa lah si yusuff ni . Mama cari rupanya celah ni')
[84]:
{'normalize': 'Aduh apa lah si yusuff ini . Mama cari rupanya celah ini',
'date': {},
'money': {}}
[85]:
normalizer.normalize('hais sorrylah syazzz')
[85]:
{'normalize': 'aduh maaf lah syazz', 'date': {}, 'money': {}}