BackTranslation 0.3.1__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation/__init__.py +1 -1
  2. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation/languages.py +110 -109
  3. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation/translated.py +23 -22
  4. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation/translation.py +154 -116
  5. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation/translation_Baidu.py +159 -113
  6. backtranslation-0.5.0/BackTranslation.egg-info/PKG-INFO +201 -0
  7. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation.egg-info/SOURCES.txt +6 -1
  8. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation.egg-info/top_level.txt +1 -0
  9. backtranslation-0.5.0/LICENSE +21 -0
  10. backtranslation-0.5.0/PKG-INFO +201 -0
  11. backtranslation-0.5.0/README.md +170 -0
  12. {BackTranslation-0.3.1 → backtranslation-0.5.0}/setup.cfg +4 -4
  13. {BackTranslation-0.3.1 → backtranslation-0.5.0}/setup.py +29 -24
  14. backtranslation-0.5.0/tests/__init__.py +0 -0
  15. backtranslation-0.5.0/tests/test_translated.py +52 -0
  16. backtranslation-0.5.0/tests/test_translation.py +255 -0
  17. backtranslation-0.5.0/tests/test_translation_baidu.py +197 -0
  18. BackTranslation-0.3.1/BackTranslation.egg-info/PKG-INFO +0 -116
  19. BackTranslation-0.3.1/PKG-INFO +0 -116
  20. BackTranslation-0.3.1/README.md +0 -100
  21. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation.egg-info/dependency_links.txt +0 -0
  22. {BackTranslation-0.3.1 → backtranslation-0.5.0}/BackTranslation.egg-info/requires.txt +0 -0
@@ -1,2 +1,2 @@
1
- from BackTranslation.translation import BackTranslation
1
+ from BackTranslation.translation import BackTranslation
2
2
  from BackTranslation.translation_Baidu import BackTranslation_Baidu
@@ -1,109 +1,110 @@
1
- LANG_CODES = {
2
- 'afrikaans': 'af',
3
- 'albanian': 'sq',
4
- 'amharic': 'am',
5
- 'arabic': 'ar',
6
- 'armenian': 'hy',
7
- 'azerbaijani': 'az',
8
- 'basque': 'eu',
9
- 'belarusian': 'be',
10
- 'bengali': 'bn',
11
- 'bosnian': 'bs',
12
- 'bulgarian': 'bg',
13
- 'catalan': 'ca',
14
- 'cebuano': 'ceb',
15
- 'chichewa': 'ny',
16
- 'chinese (simplified)': 'zh-cn',
17
- 'chinese (traditional)': 'zh-tw',
18
- 'corsican': 'co',
19
- 'croatian': 'hr',
20
- 'czech': 'cs',
21
- 'danish': 'da',
22
- 'dutch': 'nl',
23
- 'english': 'en',
24
- 'esperanto': 'eo',
25
- 'estonian': 'et',
26
- 'filipino': 'tl',
27
- 'finnish': 'fi',
28
- 'french': 'fr',
29
- 'frisian': 'fy',
30
- 'galician': 'gl',
31
- 'georgian': 'ka',
32
- 'german': 'de',
33
- 'greek': 'el',
34
- 'gujarati': 'gu',
35
- 'haitian creole': 'ht',
36
- 'hausa': 'ha',
37
- 'hawaiian': 'haw',
38
- 'hebrew': 'he',
39
- 'hindi': 'hi',
40
- 'hmong': 'hmn',
41
- 'hungarian': 'hu',
42
- 'icelandic': 'is',
43
- 'igbo': 'ig',
44
- 'indonesian': 'id',
45
- 'irish': 'ga',
46
- 'italian': 'it',
47
- 'japanese': 'ja',
48
- 'javanese': 'jw',
49
- 'kannada': 'kn',
50
- 'kazakh': 'kk',
51
- 'khmer': 'km',
52
- 'korean': 'ko',
53
- 'kurdish (kurmanji)': 'ku',
54
- 'kyrgyz': 'ky',
55
- 'lao': 'lo',
56
- 'latin': 'la',
57
- 'latvian': 'lv',
58
- 'lithuanian': 'lt',
59
- 'luxembourgish': 'lb',
60
- 'macedonian': 'mk',
61
- 'malagasy': 'mg',
62
- 'malay': 'ms',
63
- 'malayalam': 'ml',
64
- 'maltese': 'mt',
65
- 'maori': 'mi',
66
- 'marathi': 'mr',
67
- 'mongolian': 'mn',
68
- 'myanmar (burmese)': 'my',
69
- 'nepali': 'ne',
70
- 'norwegian': 'no',
71
- 'odia': 'or',
72
- 'pashto': 'ps',
73
- 'persian': 'fa',
74
- 'polish': 'pl',
75
- 'portuguese': 'pt',
76
- 'punjabi': 'pa',
77
- 'romanian': 'ro',
78
- 'russian': 'ru',
79
- 'samoan': 'sm',
80
- 'scots gaelic': 'gd',
81
- 'serbian': 'sr',
82
- 'sesotho': 'st',
83
- 'shona': 'sn',
84
- 'sindhi': 'sd',
85
- 'sinhala': 'si',
86
- 'slovak': 'sk',
87
- 'slovenian': 'sl',
88
- 'somali': 'so',
89
- 'spanish': 'es',
90
- 'sundanese': 'su',
91
- 'swahili': 'sw',
92
- 'swedish': 'sv',
93
- 'tajik': 'tg',
94
- 'tamil': 'ta',
95
- 'telugu': 'te',
96
- 'thai': 'th',
97
- 'turkish': 'tr',
98
- 'ukrainian': 'uk',
99
- 'urdu': 'ur',
100
- 'uyghur': 'ug',
101
- 'uzbek': 'uz',
102
- 'vietnamese': 'vi',
103
- 'welsh': 'cy',
104
- 'xhosa': 'xh',
105
- 'yiddish': 'yi',
106
- 'yoruba': 'yo',
107
- 'zulu': 'zu'}
108
-
109
- LANGUAGES = {value:key for key, value in LANG_CODES.items()}
1
+ LANG_CODES = {
2
+ 'afrikaans': 'af',
3
+ 'albanian': 'sq',
4
+ 'amharic': 'am',
5
+ 'arabic': 'ar',
6
+ 'armenian': 'hy',
7
+ 'azerbaijani': 'az',
8
+ 'basque': 'eu',
9
+ 'belarusian': 'be',
10
+ 'bengali': 'bn',
11
+ 'bosnian': 'bs',
12
+ 'bulgarian': 'bg',
13
+ 'catalan': 'ca',
14
+ 'cebuano': 'ceb',
15
+ 'chichewa': 'ny',
16
+ 'chinese (simplified)': 'zh-cn',
17
+ 'chinese (traditional)': 'zh-tw',
18
+ 'chinese (cantonese)': 'yue',
19
+ 'corsican': 'co',
20
+ 'croatian': 'hr',
21
+ 'czech': 'cs',
22
+ 'danish': 'da',
23
+ 'dutch': 'nl',
24
+ 'english': 'en',
25
+ 'esperanto': 'eo',
26
+ 'estonian': 'et',
27
+ 'filipino': 'tl',
28
+ 'finnish': 'fi',
29
+ 'french': 'fr',
30
+ 'frisian': 'fy',
31
+ 'galician': 'gl',
32
+ 'georgian': 'ka',
33
+ 'german': 'de',
34
+ 'greek': 'el',
35
+ 'gujarati': 'gu',
36
+ 'haitian creole': 'ht',
37
+ 'hausa': 'ha',
38
+ 'hawaiian': 'haw',
39
+ 'hebrew': 'he',
40
+ 'hindi': 'hi',
41
+ 'hmong': 'hmn',
42
+ 'hungarian': 'hu',
43
+ 'icelandic': 'is',
44
+ 'igbo': 'ig',
45
+ 'indonesian': 'id',
46
+ 'irish': 'ga',
47
+ 'italian': 'it',
48
+ 'japanese': 'ja',
49
+ 'javanese': 'jw',
50
+ 'kannada': 'kn',
51
+ 'kazakh': 'kk',
52
+ 'khmer': 'km',
53
+ 'korean': 'ko',
54
+ 'kurdish (kurmanji)': 'ku',
55
+ 'kyrgyz': 'ky',
56
+ 'lao': 'lo',
57
+ 'latin': 'la',
58
+ 'latvian': 'lv',
59
+ 'lithuanian': 'lt',
60
+ 'luxembourgish': 'lb',
61
+ 'macedonian': 'mk',
62
+ 'malagasy': 'mg',
63
+ 'malay': 'ms',
64
+ 'malayalam': 'ml',
65
+ 'maltese': 'mt',
66
+ 'maori': 'mi',
67
+ 'marathi': 'mr',
68
+ 'mongolian': 'mn',
69
+ 'myanmar (burmese)': 'my',
70
+ 'nepali': 'ne',
71
+ 'norwegian': 'no',
72
+ 'odia': 'or',
73
+ 'pashto': 'ps',
74
+ 'persian': 'fa',
75
+ 'polish': 'pl',
76
+ 'portuguese': 'pt',
77
+ 'punjabi': 'pa',
78
+ 'romanian': 'ro',
79
+ 'russian': 'ru',
80
+ 'samoan': 'sm',
81
+ 'scots gaelic': 'gd',
82
+ 'serbian': 'sr',
83
+ 'sesotho': 'st',
84
+ 'shona': 'sn',
85
+ 'sindhi': 'sd',
86
+ 'sinhala': 'si',
87
+ 'slovak': 'sk',
88
+ 'slovenian': 'sl',
89
+ 'somali': 'so',
90
+ 'spanish': 'es',
91
+ 'sundanese': 'su',
92
+ 'swahili': 'sw',
93
+ 'swedish': 'sv',
94
+ 'tajik': 'tg',
95
+ 'tamil': 'ta',
96
+ 'telugu': 'te',
97
+ 'thai': 'th',
98
+ 'turkish': 'tr',
99
+ 'ukrainian': 'uk',
100
+ 'urdu': 'ur',
101
+ 'uyghur': 'ug',
102
+ 'uzbek': 'uz',
103
+ 'vietnamese': 'vi',
104
+ 'welsh': 'cy',
105
+ 'xhosa': 'xh',
106
+ 'yiddish': 'yi',
107
+ 'yoruba': 'yo',
108
+ 'zulu': 'zu'}
109
+
110
+ LANGUAGES = {value:key for key, value in LANG_CODES.items()}
@@ -1,22 +1,23 @@
1
- class Translated(object):
2
- """
3
- Save the translated result
4
- """
5
- def __init__(self, src_lang, tmp_lang, text, trans_text, back_text):
6
- self.source_text = text
7
- self.src = src_lang
8
- self.tmp = tmp_lang
9
- self.tran_text = trans_text
10
- self.result_text = back_text
11
-
12
-
13
- def __str__(self):
14
- return self.__unicode__()
15
-
16
-
17
-
18
- def __unicode__(self):
19
- if len(self.result_text) > 30 :
20
- show_text = ' '.join(self.result_text.split(' ')[:30])
21
- show_text += '...'
22
- return u'Trabslated(src={src}, tmp={tmp}, result_text={text})'.format(src=self.src, tmp=self.tmp, text = self.result_text)
1
+ class Translated(object):
2
+ """
3
+ Save the translated result
4
+ """
5
+ def __init__(self, src_lang, tmp_lang, text, trans_text, back_text, dst_lang=None, mode='back_translation'):
6
+ self.source_text = text
7
+ self.src = src_lang
8
+ self.tmp = tmp_lang
9
+ self.dst = dst_lang if dst_lang is not None else tmp_lang
10
+ self.mode = mode
11
+ self.tran_text = trans_text
12
+ self.result_text = back_text
13
+
14
+ def __str__(self):
15
+ return self.__unicode__()
16
+
17
+ def __unicode__(self):
18
+ if len(self.result_text.split(' ')) > 30:
19
+ show_text = ' '.join(self.result_text.split(' ')[:30])
20
+ show_text += '...'
21
+ else:
22
+ show_text = self.result_text
23
+ return u'Translated(src={src}, tmp={tmp}, result_text={text})'.format(src=self.src, tmp=self.tmp, text=show_text)
@@ -1,116 +1,154 @@
1
- from googletrans import Translator
2
- import nltk
3
- from nltk.tokenize import sent_tokenize
4
- import time
5
- from BackTranslation.languages import LANGUAGES, LANG_CODES
6
- from BackTranslation.translated import Translated
7
- import typing
8
- import httpcore
9
-
10
- try:
11
- nltk.data.find('tokenizers/punkt')
12
- except LookupError:
13
- nltk.download('punkt')
14
-
15
-
16
- class BackTranslation(object):
17
- """
18
- Translate the words to other language and translate back
19
- in order to generate more samples for NLP.
20
-
21
- This package built based on googletrans package.
22
- Thus, you have to create only one instance to translate your words.
23
- Otherwise, an error will occur from googletrans.
24
-
25
- """
26
-
27
- def __init__(self, url=['translate.google.com'], proxies: typing.Dict[str, httpcore.SyncHTTPTransport] = None):
28
- self.translator = Translator(service_urls=url, proxies=proxies)
29
- self.Languages = LANGUAGES
30
- self.langCodes = LANG_CODES
31
- self.MAX_LENGTH = 5000
32
-
33
- def translate(self, text, src=None, tmp=None, sleeping=0):
34
-
35
- if not src:
36
- src = self.translator.detect(text).lang
37
-
38
- if src.lower() not in self.Languages:
39
- raise ValueError("'{}': INVALID source language.".format(src))
40
-
41
- # if tmp is null, set a default language for tmp.
42
- if not tmp:
43
- if src == 'en':
44
- tmp = 'zh-cn'
45
- else:
46
- tmp = 'en'
47
-
48
- if tmp not in self.Languages:
49
- raise ValueError("'{}': INVALID transited language.".format(tmp))
50
-
51
- if src == tmp:
52
- raise ValueError("Transited language ({tmp}) should different from srouce language ({src}).".format(
53
- tmp=self.langCodes[tmp], src=self.langCodes[src]))
54
-
55
- # check the length of text
56
- if len(text) > self.MAX_LENGTH:
57
- original_sentences = self._split_segement(sent_tokenize(text))
58
-
59
- t_text = self.translator.translate(original_sentences, src=src, dest=tmp)
60
- tran_text = ' '.join([t.text for t in t_text])
61
- time.sleep(sleeping)
62
- r_text = self.translator.translate([t.text for t in t_text], src=tmp, dest=src)
63
- back_text = ' '.join([r.text for r in r_text])
64
- back_text.rstrip()
65
- else:
66
- mid_text = self.translator.translate(text, src=src, dest=tmp)
67
- tran_text = mid_text.text
68
- time.sleep(sleeping) # Sleep between translation
69
- result_text = self.translator.translate(tran_text, src=tmp, dest=src)
70
- back_text = result_text.text
71
- result = Translated(src_lang=src, tmp_lang=tmp, text=text, trans_text=tran_text, back_text=back_text)
72
- return result
73
-
74
- def _split_segement(self, sentences):
75
- """
76
- Split the long sentences into multiple sentences whose lengths are less than MAX_LENGTH.
77
-
78
- :param sentences: the list of tokenized sentences from source text
79
- :return: the list of sentences with proper length
80
- :rtype: list
81
- """
82
- sentences_list = []
83
- block = ""
84
- for sentence in sentences:
85
- if len((block.rstrip() + ' ' + sentence).encode('utf-8')) > self.MAX_LENGTH:
86
- sentences_list.append(block.rstrip())
87
- block = sentence
88
- else:
89
- block = block + sentence + ' '
90
- sentences_list.append(block.rstrip())
91
- return sentences_list
92
-
93
- def searchLanguage(self, language):
94
- """
95
- Search a matched language code by language name.
96
-
97
- :param language: the full name of language in english
98
- :return: return matched language name and their code
99
- :rtype: dict
100
-
101
- Usage:
102
- >>> trans = BackTranslation()
103
- >>> trans.searchLanguage('frenc')
104
- # {'french': 'fr'}
105
- >>> trans.searchLanguage('Chinese')
106
- # {'chinese (simplified)': 'zh-cn', 'chinese (traditional)': 'zh-tw'}
107
- """
108
- language = language.lower()
109
- if language in self.langCodes:
110
- return {language: self.langCodes[language]}
111
- else:
112
- language_list = [key for key in self.langCodes.keys() if language in key]
113
- if language_list != []:
114
- return {lan: self.langCodes[lan] for lan in language_list}
115
- else:
116
- raise ValueError("{}: No existing language.".format(language))
1
+ from googletrans import Translator
2
+ import nltk
3
+ from nltk.tokenize import sent_tokenize
4
+ import time
5
+ from BackTranslation.languages import LANGUAGES, LANG_CODES
6
+ from BackTranslation.translated import Translated
7
+ import typing
8
+ import httpcore
9
+
10
+ try:
11
+ nltk.data.find('tokenizers/punkt')
12
+ except LookupError:
13
+ nltk.download('punkt')
14
+
15
+
16
+ class BackTranslation(object):
17
+ """
18
+ Translate the words to other language and translate back
19
+ in order to generate more samples for NLP.
20
+
21
+ This package built based on googletrans package.
22
+ Thus, you have to create only one instance to translate your words.
23
+ Otherwise, an error will occur from googletrans.
24
+
25
+ """
26
+
27
+ def __init__(self, url=['translate.google.com'], proxies: typing.Dict[str, httpcore.SyncHTTPTransport] = None):
28
+ self.translator = Translator(service_urls=url, proxies=proxies)
29
+ self.Languages = LANGUAGES
30
+ self.langCodes = LANG_CODES
31
+ self.MAX_LENGTH = 5000
32
+
33
+ def translate(self, text, src=None, tmp=None, sleeping=0):
34
+ src = self._resolve_src(text, src)
35
+ self._validate_language(src, 'source')
36
+
37
+ # if tmp is null, set a default language for tmp.
38
+ if not tmp:
39
+ if src == 'en':
40
+ tmp = 'zh-cn'
41
+ else:
42
+ tmp = 'en'
43
+
44
+ self._validate_language(tmp, 'transited')
45
+ self._validate_different(src, tmp, 'Transited')
46
+
47
+ # check the length of text
48
+ if len(text) > self.MAX_LENGTH:
49
+ original_sentences = self._split_segement(sent_tokenize(text))
50
+
51
+ t_text = self._translate_with_google(original_sentences, src, tmp, 'Translation')
52
+ tran_text = ' '.join([t.text for t in t_text])
53
+ time.sleep(sleeping)
54
+ r_text = self._translate_with_google([t.text for t in t_text], tmp, src, 'Back-translation')
55
+ back_text = ' '.join([r.text for r in r_text])
56
+ back_text.rstrip()
57
+ else:
58
+ mid_text = self._translate_with_google(text, src, tmp, 'Translation')
59
+ tran_text = mid_text.text
60
+ time.sleep(sleeping) # Sleep between translation
61
+ result_text = self._translate_with_google(tran_text, tmp, src, 'Back-translation')
62
+ back_text = result_text.text
63
+ result = Translated(src_lang=src, tmp_lang=tmp, text=text, trans_text=tran_text, back_text=back_text,
64
+ dst_lang=tmp, mode='back_translation')
65
+ return result
66
+
67
+ def direct_translate(self, text, src=None, dst=None, sleeping=0):
68
+ if not dst:
69
+ raise ValueError("destination language is required")
70
+
71
+ src = self._resolve_src(text, src)
72
+
73
+ self._validate_language(src, 'source')
74
+ self._validate_language(dst, 'destination')
75
+ self._validate_different(src, dst, 'Destination')
76
+
77
+ if len(text) > self.MAX_LENGTH:
78
+ original_sentences = self._split_segement(sent_tokenize(text))
79
+ translated_text = self._translate_with_google(original_sentences, src, dst, 'Translation')
80
+ result_text = ' '.join([t.text for t in translated_text])
81
+ else:
82
+ translated_text = self._translate_with_google(text, src, dst, 'Translation')
83
+ result_text = translated_text.text
84
+
85
+ result = Translated(src_lang=src, tmp_lang=dst, text=text, trans_text=result_text, back_text=result_text,
86
+ dst_lang=dst, mode='direct')
87
+ return result
88
+
89
+ def _resolve_src(self, text, src):
90
+ if not src:
91
+ return self.translator.detect(text).lang
92
+ return src
93
+
94
+ def _validate_language(self, language, language_type):
95
+ if language.lower() not in self.Languages:
96
+ raise ValueError("'{}': INVALID {} language.".format(language, language_type))
97
+
98
+ def _validate_different(self, src, dst, dst_label):
99
+ if src == dst:
100
+ raise ValueError("{} language ({dst}) should different from source language ({src}).".format(
101
+ dst_label, dst=dst, src=src))
102
+
103
+ def _translate_with_google(self, text, src, dst, action):
104
+ try:
105
+ return self.translator.translate(text, src=src, dest=dst)
106
+ except httpcore.ConnectTimeout:
107
+ raise httpcore.ConnectTimeout(
108
+ "Connection timed out. If you are blocked by Google, try using the 'proxies' parameter or a different 'url'.")
109
+ except Exception as e:
110
+ raise Exception("{} failed (try increasing the 'sleeping' parameter): {}".format(action, e))
111
+
112
+ def _split_segement(self, sentences):
113
+ """
114
+ Split the long sentences into multiple sentences whose lengths are less than MAX_LENGTH.
115
+
116
+ :param sentences: the list of tokenized sentences from source text
117
+ :return: the list of sentences with proper length
118
+ :rtype: list
119
+ """
120
+ sentences_list = []
121
+ block = ""
122
+ for sentence in sentences:
123
+ if len((block.rstrip() + ' ' + sentence).encode('utf-8')) > self.MAX_LENGTH:
124
+ sentences_list.append(block.rstrip())
125
+ block = sentence
126
+ else:
127
+ block = block + sentence + ' '
128
+ sentences_list.append(block.rstrip())
129
+ return sentences_list
130
+
131
+ def searchLanguage(self, language):
132
+ """
133
+ Search a matched language code by language name.
134
+
135
+ :param language: the full name of language in english
136
+ :return: return matched language name and their code
137
+ :rtype: dict
138
+
139
+ Usage:
140
+ >>> trans = BackTranslation()
141
+ >>> trans.searchLanguage('frenc')
142
+ # {'french': 'fr'}
143
+ >>> trans.searchLanguage('Chinese')
144
+ # {'chinese (simplified)': 'zh-cn', 'chinese (traditional)': 'zh-tw'}
145
+ """
146
+ language = language.lower()
147
+ if language in self.langCodes:
148
+ return {language: self.langCodes[language]}
149
+ else:
150
+ language_list = [key for key in self.langCodes.keys() if language in key]
151
+ if language_list != []:
152
+ return {lan: self.langCodes[lan] for lan in language_list}
153
+ else:
154
+ raise ValueError("{}: No existing language.".format(language))