StringTokenizer в JAVA
StringTokenizer используется для токенизации теговой строки в JAVA. Строка помечается с использованием Parts Of Speech MaxentTagger из Стэнфорда. Подстрока тегового текста используется для итеративного отображения только тега POS и только слова.
Вот текст перед пометкой:
Человек всегда имел представление о том, что смелые поступки проявляются в физических действиях. Хотя это не совсем ошибочно, не существует единственного пути к доблести. С давних пор это признак силы, чтобы дать отпор дикому животному. Это понятно, если биться в обороне; однако пройти лишнюю милю и спровоцировать животное и бороться с ним - это самая низкая степень цивилизации, которую может продемонстрировать человек. Тем более, в наш век рассуждений и знаний. Традиция может называть это, но слепо придерживаться этого - идиотизм, будь то знаменитый Джалликатту в Тамил Наду (индийский эквивалент испанской корриды) или петушиные бои. Бросать камни в собаку и наслаждаться ее воем от боли ужасно. Если бы кто-то дал всего лишь струйку мысли и совести, проблема оказалась бы плачевной во всех аспектах. Животные играют роль вместе с нами в нашей экосистеме. И некоторые животные дороже: бродячие собаки, которые охраняют нашу улицу, умная ворона, зверь бремя и обычные животные пастбища. Литература озвучивала по-своему: "Властелин колец" общался с пони Билла Ферни с особой тщательностью; в "Гарри Поттере", когда они не прислушались к совету Гермионы по поводу обращения с домашними эльфами, они усвоили трудный путь, который вызвал их собственное уничтожение; и Джек Лондон, пишет все о животных. На самом деле, доброта к животным является добродетелью.
Вот текст с тегами POS:
Man_NN имеет_VBZ всегда_RB имел_VBN this_DT notion_NN that_IN храбрый_VBP deeds_NNS являются_VBP манифест_JJ in_IN физические_JJ действия_NNS ._. Хотя _IN it_PRP is_VBZ не_RB полностью_RB ошибочно_JJ,_, там_EX делает_VBZ n't_RB лежат_VB the_DT singular_JJ path_NN to_TO valor_NN ._. From_IN из_IN old_JJ,_, it_PRP is_VBZ a_DT знак_NN из_IN сила_NN к_TO fight_VB назад_RP a_DT wild_JJ animal_NN._. Это_ПР_VBZ понятно_JJ, если_IN сражался_ВБН в_ИН обороне_NN; _: однако_RB,_, to_TO go_VB More_RBR so_RB,_, in_IN this_DT age_NN из_IN рассуждений_NN и_CC знаний_NN ._. Tradition_NN may_MD call_VB it_PRP,_, but_CC adhering_JJ blindly_RB to_TO it_PRP is_VBZ idiocy_NN,_, be_VB it_PRP the_DT famed_JJ Jallikattu_NNP in_IN Tamil_NNP Nadu_NNP -LRB-_-LRB- The_DT Indian_JJ equivalent_NN to_TO the_DT Spanish_JJ Bullfighting_NN -RRB-_-RRB- or_CC the_DT cock-fights_NNS ._. Pelting_VBG stone_NNS at_IN a_DT dog_NN и_CC relishing_VBG it_PRP howl_NN in_IN pain_NN is_VBZ ужасно_JJ._. Если бы _IN one_CD only_RB дал_VBD as_RB much_JJ as_IN a_DT trickle_VB of_IN мысли_NN и_CC сознание_NN the_DT выпуск_NN will_MD поверхность_VB как_IN deplorable_JJ in_IN каждый_DT аспект_NN ._. Animals_NNS play_VBP a_DT part_NN вдоль_IN с_IN us_PRP in_IN our_PRP$ ecosystem_NN ._. И_CC,_, некоторые_DT животные_NNS являются_VBP дорогой_RBR:_: the_DT беспризорный_JJ собак_NNS, которые_WDT охраняют_VBP наши_PRP $ street_NN, _, _DT разумные_JJ crow_NN, _, _DT зверя_N___________ Literature_NN has_VBZ voiced_VBN in_IN its_PRP$ own_JJ way_NN:_: In_IN The_DT Lord_NN of_IN the_DT Rings_NNP the_DT fellowship_NN treated_VBN Bill_NNP Ferny_NNP 's_POS pony_NN with_IN utmost_JJ care_NN;_: in_IN Harry_NNP Potter_NNP when_WRB they_PRP did_VBD n't_RB heed_VB Hermione_NNP 's_POS advice_NN on_IN the_DT treatment_NN of_IN house_NN elves_NNS они_PRP узнали_VBD the_DT hard_JJ way_NN, которые_IN it_PRP вызвали_VBD их_PRP $ own_JJ отменить_NN;_: and_CC Jack_NNP Лондон_NNP,_, пишет_VBZ all_DT about_IN животных_NNS ._. Действительно_RB,_, Доброта_NN к_TO animal_NNS is_VBZ a_DT virtue_NN ._.
А вот код, который стремится получить вышеупомянутые подстроки:
String line;
StringBuilder sb=new StringBuilder();
try(FileInputStream input = new FileInputStream("E:\\D.txt"))
{
int data = input.read();
while(data != -1)
{
sb.append((char)data);
data = input.read();
}
}
catch(FileNotFoundException e)
{
System.err.println("File Not Found Exception : " + e.getMessage());
}
line=sb.toString();
String line1=line;//Copy for Tagger
line+=" T";
List<String> sentenceList = new ArrayList<String>();//TAGGED DOCUMENT
MaxentTagger tagger = new MaxentTagger("E:\\Installations\\Java\\Tagger\\english-left3words-distsim.tagger");
String tagged = tagger.tagString(line1);
File file = new File("A.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));
output.write(tagged);
output.close();
DocumentPreprocessor dp = new DocumentPreprocessor("C:\\Users\\Admin\\workspace\\Project\\A.txt");
int largest=50;
int m=0;
StringTokenizer st1;
for (List<HasWord> sentence : dp)
{
String sentenceString = Sentence.listToString(sentence);
sentenceList.add(sentenceString.toString());
}
String[][] Gloss=new String[sentenceList.size()][largest];
String[] Adj=new String[largest];
String[] Adv=new String[largest];
String[] Noun=new String[largest];
String[] Verb=new String[largest];
int adj=0,adv=0,noun=0,verb=0;
for(int i=0;i<sentenceList.size();i++)
{
st1= new StringTokenizer(sentenceList.get(i)," ,(){}[]/.;:&?!");
m=0;//Count for Gloss 2nd dimension
//GETTING THE POS's COMPARTMENTALISED
while(st1.hasMoreTokens())
{
String token=st1.nextToken();
if(token.length()>1)//TO SKIP PAST TOKENS FOR PUNCTUATION MARKS
{
System.out.println(token);
String s=token.substring(token.lastIndexOf("_")+1,token.length());
System.out.println(s);
if(s.equals("JJ")||s.equals("JJR")||s.equals("JJS"))
{
Adj[adj]=token.substring(0,token.lastIndexOf("_"));
System.out.println(Adj[adj]);
adj++;
}
if(s.equals("NN")||s.equals("NNS"))
{
Noun[noun]=token.substring(0, token.lastIndexOf("_"));
System.out.println(Noun[noun]);
noun++;
}
if(s.equals("RB")||s.equals("RBR")||s.equals("RBS"))
{
Adv[adv]=token.substring(0,token.lastIndexOf("_"));
System.out.println(Adv[adv]);
adv++;
}
if(s.equals("VB")||s.equals("VBD")||s.equals("VBG")||s.equals("VBN")||s.equals("VBP")||s.equals("VBZ"))
{
Verb[verb]=token.substring(0,token.lastIndexOf("_"));
System.out.println(Verb[verb]);
verb++;
}
}
}
i++;//TO SKIP PAST THE LINES WHERE AN EXTRA UNDERSCORE OCCURS FOR FULLSTOP
}
D.txt содержит простой текст.
Что касается вопроса:
Каждое слово размечается в пробелах. За исключением 'n't_RB', где он маркируется как n't и RB отдельно.
Вот как выглядит результат:
Man_NN
NN
Man
has_VBZ
VBZ
has
always_RB
RB
always
had_VBN
VBN
had
this_DT
DT
notion_NN
NN
notion
that_IN
IN
brave_VBP
VBP
brave
deeds_NNS
NNS
deeds
are_VBP
VBP
are
manifest_JJ
JJ
manifest
in_IN
IN
physical_JJ
JJ
physical
actions_NNS
NNS
actions
While_IN
IN
it_PRP
PRP
is_VBZ
VBZ
is
not_RB
RB
not
entirely_RB
RB
entirely
erroneous_JJ
JJ
erroneous
there_EX
EX
does_VBZ
VBZ
does
n't
n't
RB
RB
Но если я просто запущу 'there_EX Does_VBZ n't_RB lie_VB' в токенизаторе, 'n't_RB' будет объединен. Когда я запускаю программу, я получаю исключение StringIndexOutOfBounds, которое понятно, потому что нет '_' в 'n't' или 'RB'. Кто-нибудь может посмотреть на это? Спасибо.
3 ответа
В документации DocumentPreprocessor сказано
ПРИМЕЧАНИЕ. Если используется пустой аргумент, предполагается, что документ токенизирован, а DocumentPreprocessor не выполняет токенизацию.
Поскольку документ, который вы загружаете из вашего файла, уже был размечен на первом шаге вашей программы, вы должны сделать:
DocumentPreprocessor dp = new DocumentPreprocessor("./data/stanford-nlp/A.txt");
dp.setTokenizerFactory(null);
Затем он выводит '
слова правильно, например
...
did_VBD
VBD
did
n't_RB
RB
n't
heed_VB
VB
heed
Hermione_NNP
NNP
's_POS
POS
...
Метод lastIndexOf при возникновении ошибки возвращает -1. Исключение, которое вы получаете, связано с методом подстроки, который вы используете, когда метод lastIndexOf не может получить правильный символ в вашей строке.
Я думаю, что вы можете сделать, чтобы проверить, если индекс отличается от -1, и после этого использовать его. С помощью этой проверки вы можете избежать той досадной ошибки, которую получаете. К сожалению, без всего вводимого текста действительно трудно понять, какие строки не содержат указанный вами символ.
Для полноты картины я думаю, что вам нужно исправить также способ получения всех элементов POS. На мой взгляд, матрица String подвержена ошибкам (вам необходимо выяснить, как управлять индексами), а также довольно неэффективна для такого рода задач.
Возможно, вы можете использовать Multimap, чтобы связать для каждого типа POS все элементы, которые к нему относятся. Я думаю, что таким образом вы можете управлять всем лучше.
Я постараюсь для String.split()
скорее, чем StringTokenizer
String str = "Man_NN has_VBZ always_RB had_VBN this_DT notion_NN that_IN brave_VBP deeds_NNS are_VBP manifest_JJ in_IN physical_JJ actions_NNS ._. While_IN it_PRP is_VBZ not_RB entirely_RB erroneous_JJ ,_, there_EX does_VBZ n't_RB lie_VB the_DT singular_JJ path_NN to_TO valor_NN ._. From_IN of_IN old_JJ ,_, it_PRP is_VBZ a_DT sign_NN of_IN strength_NN to_TO fight_VB back_RP a_DT wild_JJ animal_NN ._. It_PRP is_VBZ understandable_JJ if_IN fought_VBN in_IN defense_NN ;_: however_RB ,_, to_TO go_VB the_DT extra_JJ mile_NN and_CC instigate_VB an_DT animal_NN and_CC fight_VB it_PRP is_VBZ the_DT lowest_JJS degree_NN of_IN civilization_NN man_NN can_MD exhibit_VB ._. More_RBR so_RB ,_, in_IN this_DT age_NN of_IN reasoning_NN and_CC knowledge_NN ._. Tradition_NN may_MD call_VB it_PRP ,_, but_CC adhering_JJ blindly_RB to_TO it_PRP is_VBZ idiocy_NN ,_, be_VB it_PRP the_DT famed_JJ Jallikattu_NNP in_IN Tamil_NNP Nadu_NNP -LRB-_-LRB- The_DT Indian_JJ equivalent_NN to_TO the_DT Spanish_JJ Bullfighting_NN -RRB-_-RRB- or_CC the_DT cock-fights_NNS ._. Pelting_VBG stones_NNS at_IN a_DT dog_NN and_CC relishing_VBG it_PRP howl_NN in_IN pain_NN is_VBZ dreadful_JJ ._. If_IN one_CD only_RB gave_VBD as_RB much_JJ as_IN a_DT trickle_VB of_IN thought_NN and_CC conscience_NN the_DT issue_NN would_MD surface_VB as_IN deplorable_JJ in_IN every_DT aspect_NN ._. Animals_NNS play_VBP a_DT part_NN along_IN with_IN us_PRP in_IN our_PRP$ ecosystem_NN ._. And_CC ,_, some_DT animals_NNS are_VBP dearer_RBR :_: the_DT stray_JJ dogs_NNS that_WDT guard_VBP our_PRP$ street_NN ,_, the_DT intelligent_JJ crow_NN ,_, the_DT beast_NN of_IN burden_NN and_CC the_DT everyday_JJ animals_NNS of_IN pasture_NN ._. Literature_NN has_VBZ voiced_VBN in_IN its_PRP$ own_JJ way_NN :_: In_IN The_DT Lord_NN of_IN the_DT Rings_NNP the_DT fellowship_NN treated_VBN Bill_NNP Ferny_NNP 's_POS pony_NN with_IN utmost_JJ care_NN ;_: in_IN Harry_NNP Potter_NNP when_WRB they_PRP did_VBD n't_RB heed_VB Hermione_NNP 's_POS advice_NN on_IN the_DT treatment_NN of_IN house_NN elves_NNS they_PRP learned_VBD the_DT hard_JJ way_NN that_IN it_PRP caused_VBD their_PRP$ own_JJ undoing_NN ;_: and_CC Jack_NNP London_NNP ,_, writes_VBZ all_DT about_IN animals_NNS ._. Indeed_RB ,_, Kindness_NN to_TO animals_NNS is_VBZ a_DT virtue_NN ._. ";
for(String word : str.split("\\s")){
if(word.split("_").length==2){
String filteredWord = word.split("_")[0];
String wordType = word.split("_")[1];
System.out.println(word+" = "+filteredWord+ " - "+wordType );
}
}
И вывод выглядит так:
Man_NN = Man - NN
has_VBZ = has - VBZ
always_RB = always - RB
had_VBN = had - VBN
this_DT = this - DT
notion_NN = notion - NN
that_IN = that - IN
brave_VBP = brave - VBP
deeds_NNS = deeds - NNS
are_VBP = are - VBP
manifest_JJ = manifest - JJ
in_IN = in - IN
physical_JJ = physical - JJ
actions_NNS = actions - NNS
......
почему только n't_RB'разделяется как n't и RB
StringTokenizer stk = new StringTokenizer("n't_RB","_");
while(stk.hasMoreTokens()){
System.out.println(stk.nextToken());
}
Это будет расщеплено правильно,
n't
RB