├── .gitignore
├── LICENSE
├── README.md
├── data
├── acos
│ ├── laptop16
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ └── rest16
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
├── asqp
│ ├── rest15
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ └── rest16
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
├── aste
│ ├── laptop14
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ ├── rest14
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ ├── rest15
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ └── rest16
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
├── tasd
│ ├── rest15
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
│ └── rest16
│ │ ├── dev.txt
│ │ ├── test.txt
│ │ └── train.txt
└── unified
│ └── seed10
│ ├── dev.txt
│ └── train.txt
├── images
├── framework.png
├── multi-task.png
├── result_chatgpt.png
└── result_main.png
├── requirements.txt
├── scripts
├── eval_unified.sh
├── process_unify.sh
├── run_llms.sh
├── run_low_resource.sh
├── run_main.sh
└── run_unified.sh
└── src
├── const.py
├── data_process
├── process_acos.py
└── process_unify.py
├── data_utils.py
├── eval_utils.py
├── force_tokens.json
├── llms
├── api.py
├── eval.py
├── infer.py
└── prompts
│ ├── acos_rest16_0shot.txt
│ ├── acos_rest16_10shot.txt
│ ├── asqp_rest15_0shot.txt
│ ├── asqp_rest15_10shot.txt
│ ├── aste_laptop14_0shot.txt
│ ├── aste_laptop14_10shot.txt
│ ├── tasd_rest16_0shot.txt
│ └── tasd_rest16_10shot.txt
├── main.py
├── t5.py
└── t5_score.py
/.gitignore:
--------------------------------------------------------------------------------
1 | outputs
2 | *.gz
3 | logs/
4 | results/
5 | # data/unified*
6 | src/llms/guide
7 | .vscode/
8 | *.out
9 | .DS_store
10 |
11 | # Byte-compiled / optimized / DLL files
12 | __pycache__/
13 | *.py[cod]
14 | *$py.class
15 |
16 | # C extensions
17 | *.so
18 |
19 | # Distribution / packaging
20 | .Python
21 | build/
22 | develop-eggs/
23 | dist/
24 | downloads/
25 | eggs/
26 | .eggs/
27 | lib/
28 | lib64/
29 | parts/
30 | sdist/
31 | var/
32 | wheels/
33 | share/python-wheels/
34 | *.egg-info/
35 | .installed.cfg
36 | *.egg
37 | MANIFEST
38 |
39 | # PyInstaller
40 | # Usually these files are written by a python script from a template
41 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
42 | *.manifest
43 | *.spec
44 |
45 | # Installer logs
46 | pip-log.txt
47 | pip-delete-this-directory.txt
48 |
49 | # Unit test / coverage reports
50 | htmlcov/
51 | .tox/
52 | .nox/
53 | .coverage
54 | .coverage.*
55 | .cache
56 | nosetests.xml
57 | coverage.xml
58 | *.cover
59 | *.py,cover
60 | .hypothesis/
61 | .pytest_cache/
62 | cover/
63 |
64 | # Translations
65 | *.mo
66 | *.pot
67 |
68 | # Django stuff:
69 | *.log
70 | local_settings.py
71 | db.sqlite3
72 | db.sqlite3-journal
73 |
74 | # Flask stuff:
75 | instance/
76 | .webassets-cache
77 |
78 | # Scrapy stuff:
79 | .scrapy
80 |
81 | # Sphinx documentation
82 | docs/_build/
83 |
84 | # PyBuilder
85 | .pybuilder/
86 | target/
87 |
88 | # Jupyter Notebook
89 | .ipynb_checkpoints
90 |
91 | # IPython
92 | profile_default/
93 | ipython_config.py
94 |
95 | # pyenv
96 | # For a library or package, you might want to ignore these files since the code is
97 | # intended to run in multiple environments; otherwise, check them in:
98 | # .python-version
99 |
100 | # pipenv
101 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
102 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
103 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
104 | # install all needed dependencies.
105 | #Pipfile.lock
106 |
107 | # poetry
108 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
109 | # This is especially recommended for binary packages to ensure reproducibility, and is more
110 | # commonly ignored for libraries.
111 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
112 | #poetry.lock
113 |
114 | # pdm
115 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
116 | #pdm.lock
117 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
118 | # in version control.
119 | # https://pdm.fming.dev/#use-with-ide
120 | .pdm.toml
121 |
122 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
123 | __pypackages__/
124 |
125 | # Celery stuff
126 | celerybeat-schedule
127 | celerybeat.pid
128 |
129 | # SageMath parsed files
130 | *.sage.py
131 |
132 | # Environments
133 | .env
134 | .venv
135 | env/
136 | venv/
137 | ENV/
138 | env.bak/
139 | venv.bak/
140 |
141 | # Spyder project settings
142 | .spyderproject
143 | .spyproject
144 |
145 | # Rope project settings
146 | .ropeproject
147 |
148 | # mkdocs documentation
149 | /site
150 |
151 | # mypy
152 | .mypy_cache/
153 | .dmypy.json
154 | dmypy.json
155 |
156 | # Pyre type checker
157 | .pyre/
158 |
159 | # pytype static type analyzer
160 | .pytype/
161 |
162 | # Cython debug symbols
163 | cython_debug/
164 |
165 | # PyCharm
166 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
167 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168 | # and can be added to the global gitignore or merged into this file. For a more nuclear
169 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
170 | #.idea/
171 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Zubin Gou
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Multi-view Prompting (MvP)
4 |
5 |
6 |
7 |
8 | 
9 | 
10 | 
11 | [](https://paperswithcode.com/sota/aspect-based-sentiment-analysis-absa-on-acos?p=mvp-multi-view-prompting-improves-aspect)
12 |
13 | [](https://paperswithcode.com/sota/aspect-based-sentiment-analysis-absa-on-asqp?p=mvp-multi-view-prompting-improves-aspect)
14 |
15 | [](https://paperswithcode.com/sota/aspect-based-sentiment-analysis-absa-on-aste?p=mvp-multi-view-prompting-improves-aspect)
16 |
17 | [](https://paperswithcode.com/sota/aspect-based-sentiment-analysis-absa-on-tasd?p=mvp-multi-view-prompting-improves-aspect)
18 |
19 |
20 |
21 |
22 | Quick Start •
23 | Trained Model •
24 | Paper •
25 | Citation
26 |
27 |
28 |
29 |
30 | Repo for ACL 2023 paper [MvP: Multi-view Prompting Improves Aspect Sentiment Tuple Prediction](https://arxiv.org/abs/2305.12627).
31 |
32 | ## ✨ Introduction
33 |
34 | MvP is an element order-based prompt learning method:
35 |
36 | - MvP unifies various tuple prediction tasks through the **combination of elements**:
37 |
38 |
39 |
40 |
41 |
42 |
43 | - MvP aggregates multi-view results by considering **permutations of elements**:
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | ## 🎯 Results
52 |
53 | MvP achieves **state-of-the-art** performance across 10 datasets encompassing 4 ABSA tasks with a **single** model:
54 |
55 |
56 |
57 |
58 |
59 | MvP with T5-base outperforms large language models ChatGPT (*gpt-3.5-turbo*) by a large margin, even in **few-shot** transfer settings:
60 |
61 |
62 |
63 |
64 |
65 | ## 🚀 Quick Start
66 |
67 |
68 | ### ⚙️ Setup
69 |
70 | ```sh
71 | conda create -n mvp python=3.8
72 | conda activate mvp
73 | pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu116
74 | pip install -r requirements.txt
75 | ```
76 |
77 | ### 🤖 Trained Model
78 |
79 | We release the multi-task MvP model (one seed): `mvp-unified-base` [[Google Drive]](https://drive.google.com/file/d/1FMTuS4DRquLjZ3xWHLDh25W31d4dgQph/view)
80 |
81 | You may download the model with [gdown](https://github.com/wkentaro/gdown) (`pip install gdown`):
82 | ```sh
83 | pip install gdown
84 | mkdir -p outputs && cd outputs
85 | gdown 1FMTuS4DRquLjZ3xWHLDh25W31d4dgQph
86 | tar -xvf unified_model.tar.gz
87 | mv src/outputs/unified unified
88 | cd ..
89 | ```
90 |
91 | then run evaluation:
92 |
93 | ```sh
94 | bash scripts/eval_unified.sh
95 | ```
96 |
97 | then you will get following results in `outputs/unified/top5_seed10/result.txt`:
98 |
99 | ```
100 | aste: laptop14: precision: 67.64 recall: 64.14 F1 = 65.84
101 | aste: rest14: precision: 74.49 recall: 77.73 F1 = 76.08
102 | aste: rest15: precision: 68.73 recall: 71.13 F1 = 69.91
103 | aste: rest16: precision: 72.15 recall: 72.57 F1 = 72.36
104 | tasd: rest15: precision: 69.88 recall: 62.60 F1 = 66.04
105 | tasd: rest16: precision: 70.15 recall: 67.57 F1 = 68.84
106 | acos: laptop16: precision: 44.75 recall: 44.64 F1 = 44.69
107 | acos: rest16: precision: 60.86 recall: 59.84 F1 = 60.35
108 | asqp: rest15: precision: 54.77 recall: 54.84 F1 = 54.81
109 | asqp: rest16: precision: 58.29 recall: 60.70 F1 = 59.47
110 | Average F1: 63.83899277391693
111 | ```
112 |
113 |
114 |
115 |
116 | ### ⚡️ Training
117 |
118 | - Train unified models:
119 |
120 | ```sh
121 | bash scripts/process_unify.sh # process data
122 | bash scripts/run_unified.sh
123 | ```
124 |
125 | - Train separate models:
126 |
127 | ```sh
128 | bash scripts/run_main.sh
129 | ```
130 |
131 | - Train with low-resource or cross-task transfer settings:
132 | ```sh
133 | bash scripts/run_low_resource.sh
134 | ```
135 |
136 | - Evaluate ChatGPT (*gpt-3.5-turbo*) baselines:
137 | ```sh
138 | bash scripts/run_llms.sh
139 | python llms/eval.py
140 | ```
141 |
142 |
143 | ## ☕️ Citation
144 |
145 | If you find this repository helpful, please consider citing our paper:
146 |
147 | ```
148 | @inproceedings{gou-etal-2023-mvp,
149 | title = "{M}v{P}: Multi-view Prompting Improves Aspect Sentiment Tuple Prediction",
150 | author = "Gou, Zhibin and
151 | Guo, Qingyan and
152 | Yang, Yujiu",
153 | booktitle = "Proceedings of the 61st Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)",
154 | month = jul,
155 | year = "2023",
156 | address = "Toronto, Canada",
157 | publisher = "Association for Computational Linguistics",
158 | url = "https://aclanthology.org/2023.acl-long.240",
159 | pages = "4380--4397",
160 | }
161 | ```
162 |
--------------------------------------------------------------------------------
/data/acos/rest16/dev.txt:
--------------------------------------------------------------------------------
1 | ca n ' t wait wait for my next visit .####[['NULL', 'restaurant general', 'positive', 'NULL']]
2 | their sake list was extensive , but we were looking for purple haze , which was n ' t listed but made for us upon request !####[['sake list', 'drinks style_options', 'positive', 'extensive'], ['NULL', 'service general', 'positive', 'NULL']]
3 | the spicy tuna roll was unusually good and the rock shrimp tempura was awesome , great appetizer to share !####[['spicy tuna roll', 'food quality', 'positive', 'good'], ['rock shrimp tempura', 'food quality', 'positive', 'awesome']]
4 | we love th pink pony .####[['pink pony', 'restaurant general', 'positive', 'love']]
5 | this place has got to be the best japanese restaurant in the new york area .####[['place', 'restaurant general', 'positive', 'best']]
6 | i tend to judge a sushi restaurant by its sea urchin , which was heavenly at sushi rose .####[['sea urchin', 'food quality', 'positive', 'heavenly']]
7 | the prix fixe menu is worth every penny and you get more than enough ( both in quantity and quality ) .####[['prix fixe menu', 'food quality', 'positive', 'worth'], ['prix fixe menu', 'food style_options', 'positive', 'worth'], ['prix fixe menu', 'food prices', 'positive', 'worth']]
8 | the food here is rather good , but only if you like to wait for it .####[['food', 'food quality', 'positive', 'good'], ['NULL', 'service general', 'negative', 'NULL']]
9 | also , specify if you like your food spicy - its rather bland if you do n ' t .####[['food', 'food quality', 'negative', 'bland']]
10 | the ambience is pretty and nice for conversation , so a casual lunch here would probably be best .####[['ambience', 'ambience general', 'positive', 'pretty'], ['ambience', 'ambience general', 'positive', 'nice'], ['NULL', 'restaurant miscellaneous', 'positive', 'best']]
11 | it was horrible .####[['NULL', 'restaurant general', 'negative', 'horrible']]
12 | have been dozens of times and never failed to enjoy the experience .####[['NULL', 'restaurant general', 'positive', 'enjoy']]
13 | make sure you try this place as often as you can .####[['place', 'restaurant general', 'positive', 'often']]
14 | i had a huge group for my birthday and we were well taken care of .####[['NULL', 'service general', 'positive', 'well']]
15 | get the tuna of gari .####[['tuna of gari', 'food quality', 'positive', 'NULL']]
16 | make sure you have the spicy scallop roll . . .####[['spicy scallop roll', 'food quality', 'positive', 'NULL']]
17 | raga ' s is a romantic , cozy restaurant .####[["raga ' s", 'ambience general', 'positive', 'romantic'], ["raga ' s", 'ambience general', 'positive', 'cozy']]
18 | i had a great time at jekyll and hyde !####[['jekyll and hyde', 'restaurant general', 'positive', 'great']]
19 | i am bringing my whole family back next time .####[['NULL', 'restaurant miscellaneous', 'positive', 'NULL']]
20 | fine dining restaurant quality .####[['dining', 'food quality', 'positive', 'fine']]
21 | we will return many times for this oasis in mid - town .####[['NULL', 'restaurant general', 'positive', 'NULL']]
22 | the food options rule .####[['food', 'food style_options', 'positive', 'NULL']]
23 | my husband and i thougt it would be great to go to the jekyll and hyde pub for our anniversary , and to our surprise it was fantastic .####[['jekyll and hyde pub', 'restaurant general', 'positive', 'great'], ['jekyll and hyde pub', 'restaurant general', 'positive', 'fantastic']]
24 | please take my advice , go and try this place .####[['place', 'restaurant general', 'positive', 'NULL']]
25 | they were served warm and had a soft fluffy interior .####[['NULL', 'food quality', 'positive', 'warm'], ['NULL', 'food quality', 'positive', 'soft']]
26 | but they do .####[['NULL', 'service general', 'positive', 'NULL']]
27 | fresh restaurant was amazing . . . . . . . . food was delicious and of course fresh .####[['restaurant', 'restaurant general', 'positive', 'fresh'], ['restaurant', 'restaurant general', 'positive', 'amazing'], ['food', 'food quality', 'positive', 'delicious'], ['food', 'food quality', 'positive', 'fresh']]
28 | hats off to the chef .####[['chef', 'food quality', 'positive', 'hats off']]
29 | this is some really good , inexpensive sushi .####[['sushi', 'food quality', 'positive', 'good'], ['sushi', 'food prices', 'positive', 'inexpensive']]
30 | this place is always very crowded and popular .####[['place', 'restaurant miscellaneous', 'positive', 'crowded'], ['place', 'restaurant miscellaneous', 'positive', 'popular']]
31 | and evaluated on those terms pastis is simply wonderful .####[['pastis', 'restaurant general', 'positive', 'wonderful']]
32 | i ' m still mad that i had to pay for lousy food .####[['food', 'food quality', 'negative', 'lousy']]
33 | the hanger steak was like rubber and the tuna was flavorless not to mention it tasted like it had just been thawed .####[['hanger steak', 'food quality', 'negative', 'rubber'], ['tuna', 'food quality', 'negative', 'flavorless']]
34 | big thumbs up !####[['NULL', 'restaurant general', 'positive', 'thumbs up']]
35 | the pizza and wine were excellent - the service too - - but what really made this place was the backyard dining area .####[['pizza', 'food quality', 'positive', 'excellent'], ['wine', 'drinks quality', 'positive', 'excellent'], ['service', 'service general', 'positive', 'excellent'], ['backyard dining area', 'ambience general', 'positive', 'NULL']]
36 | it is one the nicest outdoor restaurants i have ever seen in ny - - i am from italy and this place rivals the ones in my country .####[['outdoor restaurants', 'ambience general', 'positive', 'nicest']]
37 | it is simply amazing .####[['NULL', 'food quality', 'positive', 'amazing']]
38 | beautiful experience .####[['NULL', 'restaurant general', 'positive', 'beautiful']]
39 | the menu is very limited - i think we counted 4 or 5 entrees .####[['menu', 'food style_options', 'negative', 'limited']]
40 | we will go back every time we are in the city .####[['NULL', 'restaurant general', 'positive', 'NULL']]
41 | the characters really make for an enjoyable experience .####[['characters', 'ambience general', 'positive', 'enjoyable']]
42 | however , i think jeckll and hydes t is one of those places that is fun to do once .####[['jeckll and hydes', 'restaurant general', 'positive', 'fun']]
43 | we had a good time .####[['NULL', 'restaurant general', 'positive', 'good']]
44 | a little overpriced but worth it once you take a bite .####[['NULL', 'food prices', 'negative', 'overpriced'], ['NULL', 'food quality', 'positive', 'worth']]
45 | i have lived in japan for 7 years and the taste of the food and the feel of the restaurant is like being back in japan .####[['food', 'food quality', 'positive', 'NULL'], ['feel', 'ambience general', 'positive', 'NULL']]
46 | check out the secret back room .####[['back room', 'ambience general', 'positive', 'secret']]
47 | thank you emilio .####[['emilio', 'restaurant general', 'positive', 'NULL']]
48 | the food was authentic .####[['food', 'food quality', 'positive', 'authentic']]
49 | fantastic !####[['NULL', 'restaurant general', 'positive', 'fantastic']]
50 | but the staff was so horrible to us .####[['staff', 'service general', 'negative', 'horrible']]
51 | decor is nice though service can be spotty .####[['decor', 'ambience general', 'positive', 'nice'], ['service', 'service general', 'negative', 'spotty']]
52 | just awsome .####[['NULL', 'food quality', 'positive', 'awsome']]
53 | i had their eggs benedict for brunch , which were the worst in my entire life , i tried removing the hollondaise sauce completely that was how failed it was .####[['eggs benedict', 'food quality', 'negative', 'worst']]
54 | with the theater 2 blocks away we had a delicious meal in a beautiful room .####[['meal', 'food quality', 'positive', 'delicious'], ['room', 'ambience general', 'positive', 'beautiful'], ['NULL', 'location general', 'positive', 'NULL']]
55 | the service was attentive .####[['service', 'service general', 'positive', 'attentive']]
56 | patroon features a nice cigar bar and has great staff .####[['cigar bar', 'ambience general', 'positive', 'nice'], ['staff', 'service general', 'positive', 'great']]
57 | lloovve this place .####[['place', 'restaurant general', 'positive', 'lloovve']]
58 | the menu is limited but almost all of the dishes are excellent .####[['menu', 'food style_options', 'negative', 'limited'], ['dishes', 'food quality', 'positive', 'excellent']]
59 | wine list is extensive without being over - priced .####[['wine list', 'drinks style_options', 'positive', 'extensive'], ['wine list', 'drinks prices', 'positive', 'without being over - priced']]
60 | the food was very good , a great deal , and the place its self was great .####[['food', 'food quality', 'positive', 'good'], ['food', 'food prices', 'positive', 'a'], ['place', 'ambience general', 'positive', 'great']]
61 | the wait staff is very freindly , they make it feel like you ' re eating in a freindly little european town .####[['wait staff', 'service general', 'positive', 'freindly']]
62 | the whole set up is truly unprofessional and i wish cafe noir would get some good staff , because despite the current one this is a great place .####[['staff', 'service general', 'negative', 'unprofessional and i wish cafe noir would get some good staff'], ['cafe noir', 'restaurant general', 'positive', 'great']]
63 | you should pass on the calamari .####[['calamari', 'food quality', 'negative', 'NULL']]
64 | when asked about how a certain dish was prepared in comparison to a similar at other thai restaurants , he replied this is not mcdonald ' s , every place makes things differently####[['NULL', 'service general', 'negative', 'NULL']]
65 | everything was wonderful ; food , drinks , staff , mileau .####[['food', 'food quality', 'positive', 'wonderful'], ['drinks', 'drinks quality', 'positive', 'wonderful'], ['staff', 'service general', 'positive', 'wonderful'], ['mileau', 'ambience general', 'positive', 'wonderful'], ['NULL', 'restaurant general', 'positive', 'wonderful']]
66 | i would highly recommend this place !####[['place', 'restaurant general', 'positive', 'recommend']]
67 | fresh ingredients and everything is made to order .####[['ingredients', 'food quality', 'positive', 'fresh'], ['NULL', 'food quality', 'positive', 'NULL']]
68 | friendly staff that actually lets you enjoy your meal and the company you ' re with .####[['staff', 'service general', 'positive', 'friendly']]
69 | i will definitely be going back .####[['NULL', 'restaurant general', 'positive', 'NULL']]
70 | a great choice at any cost and a great deal .####[['NULL', 'restaurant general', 'positive', 'great'], ['NULL', 'restaurant prices', 'positive', 'great']]
71 | thalia is a beautiful restaurant with beautiful people serving you , but the food does n ' t quite match up .####[['people', 'service general', 'positive', 'beautiful'], ['food', 'food quality', 'negative', "does n ' t quite match up"], ['thalia', 'ambience general', 'positive', 'beautiful']]
72 | i ordered the smoked salmon and roe appetizer and it was off flavor .####[['smoked salmon and roe appetizer', 'food quality', 'negative', 'off flavor']]
73 | the food is good , especially their more basic dishes , and the drinks are delicious .####[['food', 'food quality', 'positive', 'good'], ['basic dishes', 'food quality', 'positive', 'good'], ['drinks', 'drinks quality', 'positive', 'delicious']]
74 | the big complaint : no toasting available .####[['NULL', 'service general', 'negative', 'complaint']]
75 | i ' ve been many time and have never been disappointed .####[['NULL', 'restaurant general', 'positive', 'never been disappointed']]
76 | the turkey burgers are scary !####[['turkey burgers', 'food quality', 'negative', 'scary']]
77 | for authentic thai food , look no further than toons .####[['thai food', 'food quality', 'positive', 'authentic']]
78 | try the pad thai , or sample anything on the appetizer menu . . . they ' re all delicious .####[['pad thai', 'food quality', 'positive', 'delicious'], ['pad thai', 'food quality', 'positive', 'delicious']]
79 | service was good and food is wonderful .####[['service', 'service general', 'positive', 'good'], ['food', 'food quality', 'positive', 'wonderful']]
80 | it is definitely a good spot for snacks and chat .####[['spot', 'restaurant general', 'positive', 'good']]
81 | do not get the go go hamburgers , no matter what the reviews say .####[['go go hamburgers', 'food quality', 'negative', 'NULL']]
82 | steamed fresh so brought hot hot hot to your table .####[['NULL', 'food quality', 'positive', 'fresh']]
83 | small servings for main entree , i had salmon ( wasnt impressed ) girlfriend had chicken , it was good .####[['salmon', 'food quality', 'negative', 'wasnt impressed'], ['chicken', 'food quality', 'positive', 'good'], ['servings for main entree', 'food general', 'negative', 'small']]
84 | cute and decorative .####[['NULL', 'ambience general', 'positive', 'cute'], ['NULL', 'ambience general', 'positive', 'decorative']]
85 | excellent spot for holiday get togethers with co - workers or friends that you have n ' t seen in a while .####[['spot', 'restaurant miscellaneous', 'positive', 'excellent']]
86 | what a great place !####[['place', 'restaurant general', 'positive', 'great']]
87 | not the typical nyc gimmick theme restaurant .####[['restaurant', 'ambience general', 'positive', 'not the typical']]
88 | service was very prompt but slightly rushed .####[['service', 'service general', 'positive', 'prompt'], ['service', 'service general', 'positive', 'rushed']]
89 | i really liked this place .####[['place', 'restaurant general', 'positive', 'liked']]
90 | everything i had was good , and i ' m a eater .####[['NULL', 'food quality', 'positive', 'good']]
91 | i also recommend the rice dishes or the different varieties of congee ( rice porridge ) .####[['rice dishes', 'food quality', 'positive', 'recommend'], ['congee ( rice porridge )', 'food quality', 'positive', 'recommend']]
92 | i recently tried suan and i thought that it was great .####[['suan', 'restaurant general', 'positive', 'great']]
93 | have been several times and it never dissapoints .####[['NULL', 'restaurant general', 'positive', 'never dissapoints']]
94 | this place is a great bargain .####[['place', 'restaurant prices', 'positive', 'great bargain']]
95 | people are always friendly .####[['people', 'service general', 'positive', 'friendly']]
96 | the best pad thai i ' ve ever had .####[['pad thai', 'food quality', 'positive', 'best']]
97 | would n ' t recomend it for dinner !####[['NULL', 'restaurant general', 'negative', "n ' t recomend"]]
98 | ask for usha , the nicest bartender in manhattan .####[['usha', 'service general', 'positive', 'nicest']]
99 | the food ' s as good as ever .####[['food', 'food quality', 'positive', 'good']]
100 | best drumsticks over rice and sour spicy soup in town !####[['drumsticks over rice', 'food quality', 'positive', 'best'], ['sour spicy soup', 'food quality', 'positive', 'best']]
101 | for those that go once and do n ' t enjoy it , all i can say is that they just do n ' t get it .####[['NULL', 'restaurant miscellaneous', 'positive', 'NULL']]
102 | not worth it .####[['NULL', 'food prices', 'negative', 'not worth']]
103 | this dish is my favorite and i always get it when i go there and never get tired of it .####[['dish', 'food quality', 'positive', 'favorite']]
104 | big wong is a great place to eat and fill your stomach .####[['big wong', 'restaurant general', 'positive', 'great']]
105 | the food is okay and the prices here are mediocre .####[['food', 'food quality', 'neutral', 'okay'], ['NULL', 'restaurant prices', 'neutral', 'mediocre']]
106 | me and my girls will definitely go back .####[['NULL', 'restaurant general', 'positive', 'NULL']]
107 | the food is great .####[['food', 'food quality', 'positive', 'great']]
108 | la rosa waltzes in , and i think they are doing it the best .####[['la rosa', 'food quality', 'positive', 'best']]
109 | interesting selection , good wines , service fine , fun decor .####[['wines', 'drinks quality', 'positive', 'good'], ['service', 'service general', 'positive', 'fine'], ['decor', 'ambience general', 'positive', 'fun'], ['selection', 'food style_options', 'positive', 'interesting']]
110 | the food here was mediocre at best .####[['food', 'food quality', 'negative', 'mediocre']]
111 | the cypriot restaurant has a lot going for it .####[['cypriot restaurant', 'restaurant general', 'positive', 'NULL']]
112 | will comeback for sure , wish they have it here in la . .####[['NULL', 'restaurant general', 'positive', 'NULL']]
113 | the space kind of feels like an alice in wonderland setting , without it trying to be that .####[['space', 'ambience general', 'negative', 'NULL']]
114 | i paid just about $ 60 for a good meal , though : )####[['meal', 'food quality', 'positive', 'good'], ['meal', 'food prices', 'positive', 'NULL']]
115 | love it .####[['NULL', 'restaurant general', 'positive', 'love']]
116 | the place is a bit hidden away , but once you get there , it ' s all worth it .####[['place', 'location general', 'positive', 'hidden away'], ['place', 'location general', 'positive', 'worth']]
117 | i love their chicken pasta cant remember the name but is sooo good####[['chicken pasta', 'food quality', 'positive', 'love'], ['chicken pasta', 'food quality', 'positive', 'good']]
118 | way below average####[['NULL', 'restaurant general', 'negative', 'below average']]
119 | i think the pizza is so overrated and was under cooked .####[['pizza', 'food quality', 'negative', 'overrated'], ['pizza', 'food quality', 'negative', 'under cooked']]
120 | i love this place####[['place', 'restaurant general', 'positive', 'love']]
121 | the service was quick and friendly .####[['service', 'service general', 'positive', 'quick'], ['service', 'service general', 'positive', 'friendly']]
122 | i thought the restaurant was nice and clean .####[['restaurant', 'restaurant general', 'positive', 'nice'], ['restaurant', 'ambience general', 'positive', 'clean']]
123 | chicken teriyaki had tomato or pimentos on top ? ?####[['chicken teriyaki', 'food style_options', 'negative', 'NULL']]
124 | the waitress was not attentive at all .####[['waitress', 'service general', 'negative', 'not attentive']]
125 | just go to yamato and order the red dragon roll .####[['yamato', 'restaurant general', 'positive', 'NULL'], ['red dragon roll', 'food quality', 'positive', 'NULL']]
126 | favorite sushi in nyc####[['sushi', 'food quality', 'positive', 'favorite']]
127 | the rolls are creative and i have yet to find another sushi place that serves up more inventive yet delicious japanese food .####[['rolls', 'food style_options', 'positive', 'creative'], ['japanese food', 'food style_options', 'positive', 'inventive'], ['japanese food', 'food quality', 'positive', 'delicious']]
128 | my quesadilla tasted like it had been made by a three - year old with no sense of proportion or flavor .####[['quesadilla', 'food quality', 'negative', 'NULL'], ['quesadilla', 'food style_options', 'negative', 'NULL']]
129 | save your money and your time and go somewhere else .####[['NULL', 'restaurant general', 'negative', 'NULL']]
130 | the spinach is fresh , definately not frozen . . .####[['spinach', 'food quality', 'positive', 'fresh']]
131 | decor needs to be upgraded but the food is amazing !####[['decor', 'ambience general', 'negative', 'upgraded'], ['food', 'food quality', 'positive', 'amazing']]
132 | my daughter ' s wedding reception at water ' s edge received the highest compliments from our guests .####[["water ' s edge", 'restaurant miscellaneous', 'positive', 'highest compliments']]
133 | the high prices you ' re going to pay is for the view not for the food .####[['view', 'location general', 'neutral', 'high prices'], ['food', 'food quality', 'negative', 'high prices'], ['NULL', 'restaurant prices', 'negative', 'high prices']]
134 | not what i would expect for the price and prestige of this location .####[['location', 'restaurant prices', 'neutral', 'NULL'], ['location', 'restaurant miscellaneous', 'neutral', 'NULL'], ['NULL', 'service general', 'negative', 'NULL']]
135 | the food was ok and fair nothing to go crazy .####[['food', 'food quality', 'neutral', 'ok'], ['food', 'food quality', 'neutral', 'fair']]
136 | impressed . . .####[['NULL', 'restaurant general', 'positive', 'impressed']]
137 | subtle food and service####[['food', 'food quality', 'positive', 'subtle'], ['service', 'service general', 'positive', 'subtle']]
138 | food took some time to prepare , all worth waiting for .####[['food', 'food quality', 'positive', 'worth'], ['NULL', 'service general', 'neutral', 'NULL']]
139 | great find in the west village !####[['NULL', 'restaurant general', 'positive', 'great']]
140 | when the bill came , nothing was comped , so i told the manager very politely that we were willing to pay for the wine , but i did n ' t think i should have to pay for food with a maggot in it .####[['NULL', 'service general', 'negative', 'NULL']]
141 | amazing food .####[['food', 'food quality', 'positive', 'amazing']]
142 | rather than preparing vegetarian dish , the chef presented me with a plate of steamed vegetables ( minus sauce , seasoning , or any form or aesthetic presentation ) .####[['vegetarian dish', 'food quality', 'negative', 'NULL'], ['vegetarian dish', 'food style_options', 'negative', 'NULL'], ['chef', 'service general', 'negative', 'NULL']]
143 | the only thing that strikes you is the decor ? ( not very pleasant ) .####[['decor', 'ambience general', 'negative', 'not very pleasant']]
144 | the martinis are amazing and very fairly priced .####[['martinis', 'drinks quality', 'positive', 'amazing'], ['martinis', 'drinks prices', 'positive', 'fairly priced']]
145 | i wanted to go there to see if it was worth it and sadly , curiousity got the best of me and i paid dearly for it .####[['NULL', 'restaurant general', 'negative', 'NULL'], ['NULL', 'restaurant prices', 'negative', 'NULL']]
146 | the environment is very upscale and you will see a lot of rich guys with trophy wives or just highly paid escorts .####[['environment', 'ambience general', 'neutral', 'upscale'], ['NULL', 'restaurant miscellaneous', 'neutral', 'upscale']]
147 | however , our $ 14 drinks were were horrible !####[['drinks', 'drinks quality', 'negative', 'horrible'], ['drinks', 'drinks prices', 'negative', 'horrible']]
148 | once we finally got a table , despite indicating we wanted an alla carte menu we were pushed into a table that was only price fixed !####[['NULL', 'service general', 'negative', 'NULL']]
149 | i do n ' t appreciate places or people that try to drive up the bill without the patron ' s knowledge so that was a huge turnoff ( more than the price ) .####[['NULL', 'service general', 'negative', 'NULL'], ['NULL', 'restaurant prices', 'negative', 'NULL']]
150 | eat at your own risk .####[['NULL', 'food quality', 'negative', 'NULL']]
151 | the service was spectacular as the waiter knew everything about the menu and his recommendations were amazing !####[['service', 'service general', 'positive', 'spectacular'], ['waiter', 'service general', 'positive', 'amazing']]
152 | the sake ’ s complimented the courses very well and is successfully easing me into the sake world .####[['sake ’ s', 'drinks quality', 'positive', 'well']]
153 | maybe it was the great company ( i had friends visiting from philly – yes , it was not a date this time ) or the super reasonable price point , but i just can ’ t say enough good things about this brasserie .####[['brasserie', 'restaurant general', 'positive', 'good'], ['brasserie', 'restaurant prices', 'positive', 'good']]
154 | i tried a couple other dishes but was n ' t too impressed .####[['dishes', 'food quality', 'neutral', "n ' t too impressed"]]
155 | the family seafood entree was very good .####[['family seafood entree', 'food quality', 'positive', 'good']]
156 | the food they serve is not comforting , not appetizing and uncooked .####[['food', 'food quality', 'negative', 'not comforting'], ['food', 'food quality', 'negative', 'not appetizing'], ['food', 'food quality', 'negative', 'uncooked']]
157 | supercilious scorn is in .####[['NULL', 'service general', 'negative', 'supercilious']]
158 | single worst restaurant in manhattan####[['restaurant', 'restaurant general', 'negative', 'worst']]
159 | it is quite a spectacular scene i ' ll give them that .####[['scene', 'ambience general', 'positive', 'spectacular']]
160 | how this place survives the competitive west village market in this economy , or any other for that matter , is beyond me .####[['place', 'restaurant general', 'negative', 'NULL']]
161 | though it ' s been crowded most times i ' ve gone here , bark always delivers on their food .####[['bark', 'restaurant miscellaneous', 'neutral', 'NULL'], ['food', 'food quality', 'positive', 'NULL']]
162 | but nonetheless - - great spot , great food .####[['spot', 'restaurant general', 'positive', 'great'], ['food', 'food quality', 'positive', 'great']]
163 | the food and service were fine , however the maitre - d was incredibly unwelcoming and arrogant .####[['food', 'food quality', 'positive', 'fine'], ['service', 'service general', 'positive', 'fine'], ['maitre - d', 'service general', 'negative', 'unwelcoming'], ['maitre - d', 'service general', 'negative', 'arrogant']]
164 | a word to the wise : you ca n ' t dine here and disturb the maitre - d ' s sense of ` ` table turnover ' ' , as whacked as it is , or else .####[['maitre - d', 'service general', 'negative', 'NULL']]
165 | i had the lamb special which was perfect .####[['lamb special', 'food quality', 'positive', 'perfect']]
166 | do n ' t go to this place !####[['place', 'restaurant general', 'negative', 'NULL']]
167 | when the main course finally arrived ( another 45mins ) half of our order was missing .####[['NULL', 'service general', 'negative', 'NULL']]
168 | when we threatened to leave , we were offered a meager discount even though half the order was missing .####[['NULL', 'service general', 'negative', 'NULL']]
169 | the bread was stale , the salad was overpriced and empty .####[['bread', 'food quality', 'negative', 'stale'], ['salad', 'food prices', 'negative', 'overpriced'], ['salad', 'food style_options', 'negative', 'empty']]
170 | shame on this place for the horrible rude staff and non - existent customer service .####[['staff', 'service general', 'negative', 'horrible'], ['staff', 'service general', 'negative', 'rude'], ['customer service', 'service general', 'negative', 'non - existent']]
171 | the food is good .####[['food', 'food quality', 'positive', 'good']]
172 |
--------------------------------------------------------------------------------
/data/aste/laptop14/dev.txt:
--------------------------------------------------------------------------------
1 | In the shop , these MacBooks are encased in a soft rubber enclosure - so you will never know about the razor edge until you buy it , get it home , break the seal and use it ( very clever con ) .####[([11, 12], [10], 'POS')]
2 | This laptop meets every expectation and Windows 7 is great !####[([6, 7], [9], 'POS')]
3 | Drivers updated ok but the BIOS update froze the system up and the computer shut down .####[([0], [2], 'POS'), ([5, 6], [7], 'NEG'), ([9], [7], 'NEG')]
4 | The fact that you can spend over $ 100 on just a webcam underscores the value of this machine .####[([15], [13], 'POS')]
5 | It rarely works and when it does it 's incredibly slow .####[([2], [1], 'NEG')]
6 | It 's so much easier to navigate through the operating system , to find files , and it runs a lot faster !####[([9, 10], [4], 'POS'), ([18], [21], 'POS'), ([6], [4], 'POS'), ([13, 14], [21], 'POS')]
7 | I am using the external speaker -- sound is good .####[([4, 5], [9], 'POS'), ([7], [9], 'POS')]
8 | The battery life seems to be very good , and have had no issues with it .####[([1, 2], [7], 'POS'), ([1, 2], [12, 13], 'POS')]
9 | Temperatures on the outside were alright but i did not track in Core Processing Unit temperatures .####[([0], [5], 'NEU')]
10 | After about a week I finally got it back and was told that the motherboard had failed and so they installed a new motherboard .####[([14], [16], 'NEU'), ([23], [22], 'NEU')]
11 | It was slow , locked up , and also had hardware replaced after only 2 months !####[([10], [11], 'NEG')]
12 | Yes , the computer was light weight , less expensive than the average laptop , and was pretty self explantory in use .####[([21], [18, 19], 'POS')]
13 | Keyboard is great , very quiet for all the typing that I do .####[([0], [2], 'POS'), ([0], [5], 'POS')]
14 | The keyboard feels good and I type just fine on it .####[([1], [3], 'POS')]
15 | I thought the white Mac computers looked dirty too quicly where you use the mousepad and where you place your hands when typing .####[([14], [7], 'NEU')]
16 | My favorite part of this computer is that it has a vga port so I can connect it to a bigger screen .####[([11, 12], [1], 'POS'), ([21], [20], 'NEU')]
17 | Granted , it 's still a very new laptop but in comparison to my previous laptops and desktops , my Mac boots up noticeably quicker .####[([21, 22], [24], 'POS')]
18 | It caught a virus that completely wiped out my hard drive in a matter of hours .####[([9, 10], [6, 7], 'NEG')]
19 | The AMD Turin processor seems to always perform so much better than Intel .####[([1, 2, 3], [10], 'POS')]
20 | High price tag , however .####[([1, 2], [0], 'NEG')]
21 | I custom ordered the machine from HP and could NOT understand the techie due to his accent .####[([12], [9, 10], 'NEG')]
22 | For the not so good , I got the stock screen - which is VERY glossy .####[([9, 10], [15], 'NEG')]
23 | The gray color was a good choice .####[([1, 2], [5], 'POS')]
24 | I would like to have volume buttons rather than the adjustment that is on the front .####[([5, 6], [2], 'NEG')]
25 | The processor a AMD Semprom at 2.1 ghz is a bummer it does not have the power for HD or heavy computing .####[([1], [10], 'NEG'), ([21], [20], 'NEG')]
26 | It is easy to use , fast and has great graphics for the money .####[([10], [9], 'POS'), ([4], [2], 'POS')]
27 | I like how the Mac OS is so simple and easy to use .####[([4, 5], [1], 'POS'), ([12], [10], 'POS')]
28 | Obviously one of the most important features of any computer is the `` human interface .####[([6], [4, 5], 'NEU'), ([13, 14], [4, 5], 'NEU')]
29 | A great feature is the spotlight search : one can search for documents by simply typing a keyword , rather than parsing tens of file folders for a document .####[([5, 6], [1], 'POS'), ([2], [1], 'POS')]
30 | I 've had to call Apple support to set up my new printer and have had wonderful experiences with helpful , english speaking ( from Vancouver ) techs that walked me through the processes to help me .####[([5, 6], [16], 'POS'), ([27], [19], 'POS')]
31 | I need graphic power to run my Adobe Creative apps efficiently .####[([2, 3], [10], 'NEU'), ([7, 8, 9], [10], 'NEU')]
32 | upon giving them the serial number the first thing I was told , was that it was out of warranty and I could pay to have it repaired .####[([19], [17, 18], 'NEU')]
33 | Laptop was in new condition and operational , but for the audio problem when 1st sent for repair .####[([11], [12], 'NEG')]
34 | I was disappointed when I realized that the keyboard does n't light up on this model .####[([8], [2], 'NEG'), ([8], [9, 10, 11, 12], 'NEG')]
35 | It runs perfectly .####[([1], [2], 'POS')]
36 | Sometimes the screen even goes black on this computer .####[([2], [5], 'NEG')]
37 | Its fast and another thing I like is that it has three USB ports .####[([12, 13], [6], 'POS')]
38 | The salesman talked us into this computer away from another we were looking at and we have had nothing but problems with software problems and just not happy with it .####[([22], [23], 'NEG'), ([22], [26, 27], 'NEG')]
39 | That system is fixed .####[([1], [3], 'NEU')]
40 | I would not recommend this to anyone wanting a notebook expecting the performance of a Desktop it does not meet the expectations .####[([12], [2, 3], 'NEG')]
41 | The Macbook arrived in a nice twin packing and sealed in the box , all the functions works great .####[([6, 7], [5], 'POS'), ([16], [18], 'POS')]
42 | It 's super fast and a great value for the price !####[([7], [6], 'POS'), ([10], [6], 'POS')]
43 | It drives me crazy when I want to download a game or something of that nature and I ca n't play it because its not compatable with the software .####[([28], [24, 25], 'NEG')]
44 | The online tutorial videos make it super easy to learn if you have always used a PC .####[([1, 2, 3], [7], 'POS')]
45 | It was very easy to just pick up and use -- It did not take long to get used to the Mac OS .####[([21, 22], [3], 'POS'), ([9], [3], 'POS')]
46 | Features like the font are very block-like and old school .####[([3], [6], 'NEG'), ([3], [8], 'NEG'), ([0], [6], 'NEG'), ([0], [8], 'NEG')]
47 | It is loaded with programs that is of no good for the average user , that makes it run way to slow .####[([4], [8, 9], 'NEG'), ([18], [21], 'NEG')]
48 | Now , , , , , my monitor has been acting up for about 2 months .####[([7], [10, 11], 'NEG')]
49 | Also , the extended warranty was a problem .####[([3, 4], [7], 'NEG')]
50 | They sent it back with a huge crack in it and it still did n't work .####[([15], [13, 14], 'NEG')]
51 | The size is perfect and I do not recommend anything bigger except for any person who can exceed the limited space it gives you .####[([1], [3], 'POS'), ([20], [19], 'NEG')]
52 | the mouse buttons are hard to push .####[([1, 2], [4], 'NEG')]
53 | The price is another driving influence that made me purchase this laptop .####[([1], [4], 'POS')]
54 | It is stamped and not in pieces therefore it is a stronger more resilient frame .####[([14], [11], 'POS'), ([14], [13], 'POS')]
55 | I would like at least a 4 hr . battery life .####[([9, 10], [2], 'NEU')]
56 | Clear picture on it and everything .####[([1], [0], 'POS')]
57 | Screen is awesome , battery life is good .####[([0], [2], 'POS'), ([4, 5], [7], 'POS')]
58 | Somehow the system clock got messed up after reboot .####[([2, 3], [5, 6], 'NEG')]
59 | HP said it was out of warranty .####[([6], [4, 5], 'NEU')]
60 | I like those programs better than Office and you can save your files to be completely compatible with the Office programs as well .####[([3], [1], 'POS'), ([3], [4], 'POS'), ([19, 20], [16], 'NEU')]
61 | Great wifi too .####[([1], [0], 'POS')]
62 | The lcd screen stopped working on mine after 10 months .####[([1, 2], [3], 'NEG')]
63 | We have had numerous problems with Vista , such as Adobe Flash player just quits and has to be uninstalled and then reinsalled , Internet Explore just quits and you lose whatever you were working on , also , the same Windows update has appeared on this computer since we got it and has been updated probably 400 times , the same update .####[([6], [4], 'NEG'), ([10, 11, 12], [4], 'NEG'), ([24, 25], [4], 'NEG'), ([41, 42], [4], 'NEG'), ([42], [4], 'NEG')]
64 | I always have used a tower home PC and jumped to the laptop and have been very satisfied with its performance .####[([20], [17], 'POS')]
65 | The Apple applications ( ex . iPhoto ) are fun , easy , and really cool to use ( unlike the competition ) !####[([1, 2], [9], 'POS'), ([1, 2], [11], 'POS'), ([1, 2], [15], 'POS'), ([6], [9], 'POS'), ([6], [11], 'POS'), ([6], [15], 'POS')]
66 | First it burned or fused the power adapter plug .####[([6, 7, 8], [2], 'NEG'), ([6, 7, 8], [4], 'NEG')]
67 | It was still working , but there was nothing on the screen .####[([11], [8], 'NEG')]
68 | Though the picture , video , and music software is nowhere close to professional grade software Im used to ( CS5 ) but does the job for beginner and even intermediate media designers .####[([7, 8], [10, 11, 12, 13], 'NEG'), ([7, 8], [23, 24, 25], 'NEG'), ([2], [10, 11, 12, 13], 'NEG'), ([2], [23, 24, 25], 'NEG'), ([4], [10, 11, 12, 13], 'NEG'), ([4], [23, 24, 25], 'NEG')]
69 | The much lauded combined touch pad and clicker is a nightmare .####[([3, 4, 5, 6, 7], [10], 'NEG')]
70 | The Unibody construction is solid , sleek and beautiful .####[([1, 2], [4], 'POS'), ([1, 2], [6], 'POS'), ([1, 2], [8], 'POS')]
71 | This MacBook is an outstanding product with great value .####[([8], [4], 'POS'), ([8], [7], 'POS')]
72 | No temporary replacement , they are out of replacements because `` many computers had problems with the Nvidia chipset `` -Inquired status of repair .####[([17, 18], [14], 'NEG')]
73 | I BOUGHT THIS LAP TOP AND THE CHARGE TIME DOSE N'T LAST AS LONG AS THEY SAY IT WILL MORE LIKE 2 HOURS####[([7, 8], [13], 'NEG')]
74 | The feature are good enough for what I need .####[([1], [3], 'POS')]
75 | Finally , the biggest problem has been tech support .####[([7, 8], [4], 'NEG')]
76 | ( I had been a Windows/Linux user before this ) I love the size because the screen is big enough for what I use it for ( Internet , artwork ) , and yet it is small enough to be reasonably portable .####[([13], [11], 'POS'), ([16], [18], 'POS'), ([16], [36], 'POS')]
77 | Plain and simple , it ( laptop ) runs great and loads fast .####[([8], [9], 'POS'), ([11], [12], 'POS')]
78 | It was a great laptop , ran great and was really fast .####[([6], [7], 'POS')]
79 | The only problem is a lack of screen resolutions !####[([7, 8], [2], 'NEG'), ([7, 8], [5], 'NEG')]
80 | It is very well built .####[([4], [3], 'POS')]
81 | The design is awesome , quality is unprecedented .####[([1], [3], 'POS'), ([5], [7], 'POS')]
82 | AND the best part is that it even comes with a free printer ( when they have a certain promotion/offer going , of course ) !####[([12], [11], 'POS')]
83 | it is very easy for anyone to use an apple and specially the mcbook pro notebook .####[([7], [3], 'POS')]
84 | The touchpad is very intuitive , so much so that I never want to use buttons to click again !####[([1], [4], 'POS')]
85 | tons of bloatware and junk programs .####[([5], [4], 'NEG')]
86 | The real stand out on this computer is the feel of the keyboard and it 's speed .####[([12], [2, 3], 'POS'), ([16], [2, 3], 'POS')]
87 | Delivery was early too .####[([0], [2], 'POS')]
88 | Laptops are usually used on the go , so why not give you a better battery ?####[([15], [14], 'NEG')]
89 | I was n't a big fan of the Netbooks but this one was very well designed .####[([15], [14], 'POS')]
90 | I still have that stupid bluetooth mouse to !####[([5, 6], [4], 'NEG')]
91 | 2nd Best computer in the world only one way this computer might become the best is that it needs to upgreade patches to make less easier for people to hack into####[([21], [18, 19, 20], 'NEG')]
92 | It could be a perfect laptop if it would have faster system memory and its radeon 5850 would have DDR5 instead of DDR3 .####[([11, 12], [10], 'NEG')]
93 | I definitely suggest getting an extended warranty , you will probably need it !####[([5, 6], [2], 'POS')]
94 | The only thing I wish is the 15 inch MacBook Pro has much better speakers on the side of the keyboard .####[([14], [13], 'NEG')]
95 | Keys stick periodically and I havent had the laptop for 45 days yet .####[([0], [1], 'NEG')]
96 | It 's graphics are n't bad at all , for the lower end of the MacBook Pro spectrum , easily capable of running StarCraft II and other games with comparable graphics .####[([2], [3, 4, 5], 'NEU')]
97 | I have Vista , so I am unable to install and uninstall some programs .####[([9], [7], 'NEG')]
98 | i am a huge computer person i love anykind of computer that works well , but when i got this one i was so happy with the way it works and how it runs its amazing .####[([33], [35], 'POS')]
99 | Its white color is stylish for college students and easy to take to carry and take to classes .####[([2], [4], 'POS')]
100 | I took off a star because the machine has a lot of junk software on it .####[([13], [12], 'NEG')]
101 | The battery life is great .####[([1, 2], [4], 'POS')]
102 | I sent it back and found this time that the battery was faulty , so I got a new one and some other fixes they found .####[([10], [12], 'NEG')]
103 | Great pick for portability and affordability .####[([3], [0], 'POS'), ([5], [0], 'POS')]
104 | It 's fast , it 's easy easy easy to set up , easy to hook to my wireless network .####[([10, 11], [6, 7, 8], 'POS'), ([15, 16, 17, 18, 19], [13], 'POS')]
105 | I previously purchased a 13 '' macbook ( had pro specs and was aluminum style ) which had a nvidia 9800 ( If I am not mistaken ) and it had major heating issues .####[([19, 20], [33], 'NEU')]
106 | Oh yea , has no numeric pad on the side .####[([5, 6], [4], 'NEG')]
107 | More times that not the screen pops up saying I have a bad internet connection , or the page ca n't be displayed .####[([13, 14], [12], 'NEG')]
108 | The ease of use is wonderful .####[([3], [1], 'POS'), ([3], [5], 'POS')]
109 | Best thing is I can use existing 32 bit old programs .####[([10], [0], 'POS')]
110 | The only thing I would change about it is the mouse keys .####[([10, 11], [5], 'NEG')]
111 | After that I turned to email in my next vain help to get them to acknowledge that the warranty was still valid .####[([18], [21], 'NEU')]
112 | They have developed excellent proprietary software for editing video and pictures and I 'm looking forward to utilizing these tools on the regular .####[([4, 5], [3], 'POS')]
113 | Graphics are clean and sharp , internet interfaces are seamless .####[([0], [2], 'POS'), ([0], [4], 'POS'), ([6, 7], [9], 'POS')]
114 | But after using it a couple of weeks , the overall operation is poor .####[([11], [13], 'NEG')]
115 | I already have a HP laptop I bought last year that 's standard size .####[([13], [12], 'NEU')]
116 | I just plug this into my 22 '' Monitor and the speedy MacOSX performs just as well on this dual-core that my Dell did with Windows 7 with a quad-core .####[([12], [11], 'POS'), ([12], [16], 'POS')]
117 | Good monitor and performed well .####[([1], [0], 'POS'), ([3], [4], 'POS')]
118 | the mouse pad and buttons are the worst i 've ever seen .####[([1, 2], [7], 'NEG'), ([4], [7], 'NEG')]
119 | It really is perfect for work and play .####[([7], [3], 'POS'), ([5], [3], 'POS')]
120 | Eventually my battery would n't charge , so unless I had it plugged in it would n't even power on .####[([2], [3, 4, 5], 'NEG')]
121 | My first problem was with the pre-loaded Norton Firewall/Security program .####[([6, 7, 8, 9], [2], 'NEG')]
122 | I had a USB connect but , i ca n't use it because it is not compatible .####[([3, 4], [8, 9, 10], 'NEG'), ([3, 4], [15, 16], 'NEG')]
123 | It is easy to use , good quality and good price .####[([7], [6], 'POS'), ([10], [9], 'POS'), ([4], [2], 'POS')]
124 | After 2 months of complaints , Asus finally sent the right power supply to my techies .####[([11, 12], [10], 'NEU')]
125 | That included the extra Sony Sonic Stage software , the speakers and the subwoofer I got ( that WAS worth the money ) , the bluetooth mouse for my supposedly bluetooth enabled computer , the extended life battery and the Docking port .####[([4, 5, 6, 7], [3], 'NEU'), ([10], [19], 'POS'), ([13], [19], 'POS')]
126 | also the keyboard does not liht up so unless your sitting in a room with some light you cant see anything and thats bad for me because my boyfriend tends to watch tv in the dark at night which leaves me with no way of seeing the keyboard .####[([2], [23], 'NEG')]
127 | I agree with the previous comment that ASUS TECH SUPPORT IS HORRIBLE WHICH IS A CON IN MY OPINION .####[([7, 8, 9], [11], 'NEG')]
128 | I would recommend this computer to anyone searching for the perfect laptop , and the battery life is amazing .####[([15, 16], [18], 'POS')]
129 | Not easy to carry .####[([3], [1], 'NEG')]
130 | Summary : I 've had this laptop for 2 months , out of the blue the power adapter stops working .####[([16, 17], [18, 19], 'NEG')]
131 | Of course , for a student , weight is always an issue .####[([7], [11], 'NEU')]
132 | 2.The wireless card is low quality .####[([1, 2], [4, 5], 'NEG')]
133 | They offer the best warranty in the business , and do n't 3rd party it out like Toshiba .####[([4], [3], 'POS')]
134 | The only problems are the sound isnt very loud I have to wear headphones .####[([5], [6, 7, 8], 'NEG')]
135 | There are no viruses or spyware to worry about like on a Windows computer .####[([12], [7, 8], 'NEG')]
136 | while about 8 years ago , I hope that the quality has changed .####[([10], [7], 'NEG'), ([10], [12], 'NEG')]
137 | The difference is it 's a whole lot of fun using the laptop now , still learning the Apple navigation , but is fun and comes with a lot of cool apps .####[([18, 19], [23], 'NEU'), ([31], [30], 'POS')]
138 | The display is awesome .####[([1], [3], 'POS')]
139 | The speakers on it are useless too .####[([1], [5], 'NEG')]
140 | In early May I got it back and this time I only had it back for 1 day before it had a NEW issue so it was sent back in for the 6th time they `` expedited '' the repairs so I was only supposed to have to be without it for 3 days and it was supposed to be fixed , by a `` Senior Tech '' .####[([65, 66], [57, 58, 59, 60], 'NEG')]
141 | Adjust the sensitivity since it 's not that responsive to begin with .####[([2], [6, 7, 8], 'NEG')]
142 | Also , I have had a lot of trouble with the shift key to go to other lines .####[([11, 12], [8], 'NEG')]
143 | iLife is easily compatible with Microsoft Office so you can send and receive files from a PC .####[([0], [2, 3], 'POS')]
144 | Fully charged , the MacBook Pro can last about five hours unplugged .####[([1], [0], 'POS')]
145 | Also the display is exceptional !####[([2], [4], 'POS')]
146 | Your cursor will end up all over the freaking place , , , it 's not uncommon for me to accidentally delete words , sentences , paragraphs because of this mousepad .####[([1], [3, 4], 'NEG'), ([1], [8], 'NEG')]
147 | Then I 've fixed the DC jack ( inside the unit ) , rewired the DC jack to the OUTside of the laptop , replaced the power brick .####[([5, 6], [3], 'NEU'), ([15, 16], [13], 'NEU'), ([26, 27], [24], 'NEU')]
148 | Great product , very easy to use and great graphics .####[([9], [8], 'POS'), ([6], [4], 'POS')]
149 | The built-in webcam is great for Skype and similar video-chat services .####[([1, 2], [4], 'POS')]
150 | THE MOTHERBOARD IS DEAD !####[([1], [3], 'NEG')]
151 | This process continued to repeat itself until the mother board had been replaced 4 times and the hard drive replaced 3 times .####[([8, 9], [12], 'NEG'), ([17, 18], [19], 'NEG')]
152 | I could n't believe how long the battery lasted on a single charge .####[([7], [5], 'POS'), ([12], [11], 'POS')]
153 | The backlit keys are wonderful when you are working in the dark .####[([1, 2], [4], 'POS')]
154 | The most recent being that my Safari internet browser is freaking out on me , but I have just been using firefox instead .####[([6, 7, 8], [10, 11], 'NEG')]
155 | The DVD drive randomly pops open when it is in my backpack as well , which is annoying .####[([1, 2], [3, 4, 5], 'NEG'), ([1, 2], [17], 'NEG')]
156 | Its also FUN to use !####[([4], [2], 'POS')]
157 | The graphics and screen are stunning and although I was a PC person , I was able to understand how to use a mac fairly quickly .####[([1], [5], 'POS'), ([3], [5], 'POS')]
158 | I just took the broken cords into the Apple store and they gave me new ones .####[([5], [4], 'POS')]
159 | The screen is gorgeous - yummy good .####[([1], [3], 'POS'), ([1], [6], 'POS')]
160 | The Macbook starts fast , does n't crash , has a fantastic display , is small and light ( I have the 13.3 '' model ) , and is n't always complaining about updates , lost connections , errors , blue screens , etc .####[([12], [11], 'POS'), ([2], [3], 'POS')]
161 | The guy then said that if I insist on having the hinge tightened , they can do it for me but I have to accept the condition after the `` repair '' .####[([11], [12], 'NEU')]
162 | so in a brief summary i would have to say that i would not recommend dell vostro 1000 to anyone due to it being a down right awful setup so in my opinion you should steer clear of them if you want a decent laptop .####[([28], [27], 'NEG')]
163 | My friend just had to replace his entire motherboard , so did my wife , and it looks like I will have to as well .####[([8], [5], 'NEG')]
164 | First , it does not have a push button to open the lid .####[([7, 8], [3, 4], 'NEG')]
165 | The screen almost looked like a barcode when it froze .####[([1], [6], 'NEG'), ([1], [9], 'NEG')]
166 | I love the solid machined aluminum frame , and the keyboard is the best of any laptop I 've used .####[([4, 5, 6], [1], 'POS'), ([4, 5, 6], [3], 'POS'), ([10], [13], 'POS')]
167 | You can even run a parallels type program easily and run any leftover PC software that you absolutely can not be without .####[([5, 6, 7], [8], 'POS')]
168 | It has easy to use features and all the speed and power I could ask for .####[([5], [2], 'POS'), ([9], [2], 'POS'), ([11], [2], 'POS')]
169 | The Mac Snow Leopard O/S is extremely easy to use , although very different than Win XP , Visa or Win7 .####[([1, 2, 3, 4], [7, 8, 9], 'POS'), ([1, 2, 3, 4], [13], 'POS')]
170 | super fast processor and really nice graphics card ...####[([2], [1], 'POS'), ([6, 7], [5], 'POS')]
171 | I dislike the weight and size , cubersome .####[([3], [1], 'NEG'), ([3], [7], 'NEG'), ([5], [1], 'NEG'), ([5], [7], 'NEG')]
172 | I love windows 7 but i ca n't give Toshiba any credit for that , unless y'all get serious about ergonomics and making required connections less obtrusive i will be looking to different manufacturer next time .####[([2, 3], [1], 'POS'), ([20], [18], 'NEG'), ([24], [25, 26], 'NEG')]
173 | Not sure how I recommend it for quality gaming , as I have a desktop rig for that reason .####[([8], [7], 'NEG')]
174 | Great value , fast delivery -- Computer works as if brand new , no problems , very pleased####[([4], [3], 'POS'), ([4], [17], 'POS'), ([1], [0], 'POS'), ([1], [17], 'POS')]
175 | so the fact that the computer does not work on the 24 twenty fourth day is my fault .####[([8], [6, 7], 'NEG')]
176 | I would definitely reccomend this if you are in the market for an ease to use , stylish , fun , awesome computer .####[([15], [13], 'POS')]
177 | The Windows 7 Starter is , in my opinion , a great way to think about using your netbook : basics , basics , basics .####[([1, 2, 3], [11], 'POS')]
178 | So we exchanged it for the same on and after 2 hours it did n't work .####[([15], [13, 14], 'NEG')]
179 | The OS is still as fast as the day that the laptop was purchased and continues to run flawlessly .####[([1], [5], 'POS'), ([17], [18], 'POS')]
180 | After way too many times sending the thing in for repairs ( delivery service was slow , and without the laptop I had no access to the internet , and thus no way of tracking it to find out when I might hope to see my computer again ) , it finally kicked the bucket after just over 2 years .####[([12, 13], [15], 'NEG')]
181 | The only thing I wish this had was the option to turn off the touchpad with a button like my big 16 '' laptop does .####[([14], [11, 12], 'NEG')]
182 | I especially like the backlit keyboard .####[([4, 5], [2], 'POS')]
183 | The buttons you have to press a little harder than most .####[([1], [8], 'NEG')]
184 | But to be honest , I do n't use my computer for anything like graphics editing and complex data analysis and gaming .####[([21], [6, 7, 8], 'NEU'), ([14, 15], [6, 7, 8], 'NEU'), ([17, 18, 19], [6, 7, 8], 'NEU')]
185 | The one thing I wish it had was a detailed hardcopy manuel .####[([10, 11], [4], 'NEG'), ([10, 11], [9], 'NEG')]
186 | the mcbook pro notebook will make it easy for you to write and read your emails at blazing speeds .####[([18], [7], 'POS'), ([18], [17], 'POS')]
187 | However , I love this particular Mac because its very fast , great size , and has fantastic features like the lighted keyboard and easy mouse pad .####[([13], [12], 'POS'), ([18], [17], 'POS'), ([21, 22], [17], 'POS'), ([25, 26], [17], 'POS'), ([25, 26], [24], 'POS')]
188 | We paid for the three year warranty and the extended warranty after that one ended as well .####[([4, 5, 6], [1, 2], 'NEU'), ([9, 10], [1, 2], 'NEU')]
189 | My husband got me this for Chrismas after getting me a very expensive laptop that did not work after 2 days .####[([17], [16], 'NEG')]
190 | The resolution is even higher then any other laptop on the market .####[([1], [4], 'POS')]
191 | But with A WAY Bigger Screen , and IS able to connect to an HDMI .####[([5], [4], 'POS'), ([14], [9, 10, 11], 'NEU')]
192 | the graphics are awful and the wireless switch it at the top rather than the side which I am used to it being on the side .####[([1], [3], 'NEG')]
193 | The speakers are terrible and are probably the cheapest ones I have ever seen in a laptop so if your planning to listen to music I suggest you get something better .####[([1], [3], 'NEG'), ([1], [8], 'NEG')]
194 | I have had no problems with it unlike some hardware defects on past models .####[([9], [10], 'NEG')]
195 | Not to mention the fact that your mac comes fully loaded with all necessary basic programs .####[([15], [13], 'POS')]
196 | If this is an improvement in Customer Service then I would hate too see what it was before !####[([6, 7], [4], 'NEG')]
197 | For me I was lucky and a local store was selling them for $ 2000 off and Best Buy matched their price so I was able to buy one for under $ 1000####[([21], [4], 'POS'), ([21], [17], 'POS')]
198 | The layout of the MacBook is horrible and confusing ;####[([1], [6], 'NEG'), ([1], [8], 'NEG')]
199 | Was not happy with one of the programs on it .####[([4, 5, 6, 7], [1, 2], 'NEG')]
200 | The first one sent : Touchpad did n't work The second sent : USB did n't work The third sent : Touchpad did n't work The fourth sent : Has n't arrived yet .####[([5], [6, 7, 8], 'NEG'), ([13], [14, 15, 16], 'NEG'), ([5], [6, 7, 8], 'NEG')]
201 | In November my computer messed up entirely and would n't power on after intalling a Windows update , I had to have my HD flashed and lost EVERYTHING on it , including my school assignments and irriplaceable pictures that were only in digital format and several other things , when this update was installed for some reason I was unable to roll back the drivers and everything to an earlier working condition because when the update was installed it deleted my history .####[([15, 16], [4, 5], 'NEU')]
202 | Overall : Poor , Features : Average , Performance : Poor , Battery Life : Excellent , Price -- Value : Poor####[([4], [6], 'NEU'), ([8], [10], 'NEG'), ([12, 13], [15], 'POS'), ([17], [21], 'NEG'), ([19], [21], 'NEG')]
203 | The graphics are stunning .####[([1], [3], 'POS')]
204 | ( I found a 2GB stick for a bit under $ 50 ) Nice and portable and definitely a decent enough system to keep you entertained while sitting in the airplane for a couple of hours , or at the hotel taking care of some last minute details and documents .####[([21], [13], 'POS'), ([21], [15], 'POS'), ([21], [19], 'POS')]
205 | after much effort and 10 days ASUS replaced itThe WiFi is very weak .####[([9], [12], 'NEG')]
206 | , Applications respond immediately ( not like the tired MS applications ) .####[([1], [2, 3], 'POS')]
207 | The only drawback for me is how dirty the screen gets , and rather quickly too .####[([9], [7], 'NEG'), ([9], [14], 'NEG')]
208 | Seems to slow down occassionally but can run many applications ( ie Internet tabs , programs , etc ) simultaneously .####[([9], [8], 'POS')]
209 | Not to mention sometimes the whole charger unit will decide not to work entirely .####[([6, 7], [10, 11, 12, 13], 'NEG')]
210 | I have other computers that get strong signals that do n't drop in places that this `` net '' book loses its signal .####[([7], [6], 'POS'), ([22], [20], 'NEG')]
211 | Anyway , in early July of this year , the DVD burner stopped working , and the computer stared having issues with power supply .####[([10, 11], [12, 13], 'NEG'), ([22, 23], [20], 'NEG')]
212 | The screen gets smeary and dusty very quickly and it 's very noticeable .####[([1], [3], 'NEG'), ([1], [5], 'NEG'), ([1], [7], 'NEG'), ([1], [12], 'NEG')]
213 | The battery life , before the battery completely died of course , left much to be desired .####[([1, 2], [12, 13, 14, 15, 16], 'NEG')]
214 | It had most of the features and all of the power that I wanted to replace my desktop machine .####[([5], [13], 'POS'), ([10], [13], 'POS')]
215 | It seemed to be a very nice laptop except I was not able to load my Garmin GPS software or Microsoft Office 2003 .####[([16, 17, 18], [11, 12, 13, 14], 'NEG'), ([20, 21, 22], [11, 12, 13, 14], 'NEG')]
216 | Was very much worth the price i paid .####[([5], [3], 'POS')]
217 | This is a great little computer for the price .####[([8], [3], 'POS')]
218 | All apple associates are always willing to help you out with anything , no matter when you purchased the computer and how many years passed .####[([1, 2], [5], 'POS')]
219 | I would like to use a different operating system altogether .####[([7, 8], [2], 'NEU'), ([7, 8], [6], 'NEU')]
220 |
--------------------------------------------------------------------------------
/data/aste/rest15/dev.txt:
--------------------------------------------------------------------------------
1 | The food is very average ... the Thai fusion stuff is a bit too sweet , every thing they serve is too sweet here .####[([1], [4], 'NEG'), ([7, 8, 9], [13, 14], 'NEG')]
2 | The decor is night tho ... but they REALLY need to clean that vent in the ceiling ... its quite un-appetizing , and kills your effort to make this place look sleek and modern .####[([29], [31], 'NEG'), ([29], [33], 'NEG'), ([1], [3], 'POS'), ([13], [20], 'NEG')]
3 | The spicy tuna roll was unusually good and the rock shrimp tempura was awesome , great appetizer to share !####[([1, 2, 3], [6], 'POS'), ([9, 10, 11], [13], 'POS')]
4 | we love th pink pony .####[([3, 4], [1], 'POS')]
5 | THe perfect spot .####[([2], [1], 'POS')]
6 | Ambiance relaxed and stylish .####[([0], [1], 'POS'), ([0], [3], 'POS')]
7 | however , it 's the service that leaves a bad taste in my mouth .####[([5], [9, 10], 'NEG')]
8 | i happen to have a policy that goes along with a little bit of self-respect , which includes not letting a waiter intimidate me , i.e . make me feel bad asking for trivialities like water , or the check .####[([21], [30], 'NEG')]
9 | I tend to judge a sushi restaurant by its sea urchin , which was heavenly at sushi rose .####[([9, 10], [14], 'POS')]
10 | The sushi seemed pretty fresh and was adequately proportioned .####[([1], [4], 'POS'), ([1], [8], 'POS')]
11 | The rice to fish ration was also good -- they did n't try to overpack the rice .####[([1, 2, 3, 4], [7], 'POS')]
12 | The food was well prepared and the service impecable .####[([1], [3, 4], 'POS'), ([7], [8], 'POS')]
13 | The Prix Fixe menu is worth every penny and you get more than enough ( both in quantity AND quality ) .####[([1, 2, 3], [5], 'POS')]
14 | The kitchen however , is almost always slow .####[([1], [7], 'NEG')]
15 | Add to that great service and great food at a reasonable price and you have yourself the beginning of a great evening .####[([4], [3], 'POS'), ([7], [6], 'POS')]
16 | The food was average to above-average ; the French Onion soup filling yet not overly impressive , and the desserts not brilliant in any way .####[([1], [3, 4, 5], 'POS'), ([8, 9, 10], [13, 14, 15], 'POS'), ([19], [20, 21], 'NEG')]
17 | This place is the most Japanese it can ever get .####[([1], [5], 'POS')]
18 | Leon is an East Village gem : casual but hip , with well prepared basic French bistro fare , good specials , a warm and lively atmosphere .####[([0], [7], 'POS'), ([0], [9], 'POS'), ([20], [19], 'POS'), ([26], [23], 'POS'), ([26], [25], 'POS'), ([15, 16, 17], [12, 13], 'POS')]
19 | The food was bland oily .####[([1], [3, 4], 'NEG')]
20 | I went there for lunch and it was not as good as I expected from the reviews I read .####[([4], [8, 9, 10, 11, 12, 13], 'NEG')]
21 | The place is small and cramped but the food is fantastic .####[([1], [3], 'NEG'), ([1], [5], 'NEG'), ([8], [10], 'POS')]
22 | those rolls were big , but not good and sashimi was n't fresh .####[([1], [3], 'NEG'), ([1], [6, 7], 'NEG'), ([9], [10, 11, 12], 'NEG')]
23 | Admittedly some nights inside the restaurant were rather warm , but the open kitchen is part of the charm .####[([12, 13], [18], 'POS'), ([5], [8], 'NEG')]
24 | Great wine selection , Gigondas is worth the price , and the house champagne is a great value .####[([1, 2], [0], 'POS'), ([4], [6, 7, 8], 'POS'), ([12, 13], [16, 17], 'POS')]
25 | Have recommended the place to friends , always gets good response .####[([3], [1], 'POS')]
26 | Service is not exactly five star , but thats not really a big deal .####[([0], [2, 3, 4, 5], 'NEU')]
27 | The tuna and wasabe potatoes are excellent .####[([1], [6], 'POS'), ([3, 4], [6], 'POS')]
28 | Service was prompt and courteous .####[([0], [2], 'POS'), ([0], [4], 'POS')]
29 | The pizza is delicious - they use fresh mozzarella instead of the cheap , frozen , shredded cheese common to most pizzaria 's .####[([1], [3], 'POS')]
30 | Wine list selection is good and wine-by-the-glass was generously filled to the top .####[([0, 1, 2], [4], 'POS'), ([6], [8, 9], 'POS')]
31 | I have NEVER been disappointed in the Red Eye .####[([7, 8], [2, 3, 4], 'POS')]
32 | The first time I went , and was completely taken by the live jazz band and atmosphere , I ordered the Lobster Cobb Salad .####[([12, 13, 14], [9], 'POS'), ([16], [9], 'POS')]
33 | My husband and I thougt it would be great to go to the Jekyll and Hyde Pub for our anniversary , and to our surprise it was fantastic .####[([13, 14, 15, 16], [8], 'POS'), ([13, 14, 15, 16], [27], 'POS')]
34 | The workers there also absolutely load the bagel with cream cheese ( gets a little messy ) .####[([7], [15], 'NEG')]
35 | I have to highly recommend the lobster roll - not to much mayo ; you can tell it was a fresh lobster .####[([6, 7], [4], 'POS'), ([21], [20], 'POS')]
36 | The scallion pancakes and fried dumplings were nothing out of the ordinary .####[([1, 2], [11], 'NEU'), ([4, 5], [11], 'NEU')]
37 | Salads were fantastic .####[([0], [2], 'POS')]
38 | The takeout is great too since they give high quality tupperware as well .####[([1], [3], 'POS')]
39 | The staff was accomodating , the food was absolutely delicious and the place is lovely .####[([1], [3], 'POS'), ([6], [9], 'POS'), ([12], [14], 'POS')]
40 | The place is a BISTRO which means : simple dishes and wine served efficiently in a bustling atmosphere .####[([9], [8], 'POS'), ([11], [12, 13], 'POS'), ([17], [16], 'POS')]
41 | Right off the L in Brooklyn this is a nice cozy place with good pizza .####[([14], [13], 'POS'), ([11], [9, 10], 'POS')]
42 | It 's a nice place to relax and have conversation .####[([4], [3], 'POS')]
43 | This is my first time writing a review for a restaurant because the food and service was excellent .####[([13], [17], 'POS'), ([15], [17], 'POS')]
44 | The filet mignon dish was superb !####[([1, 2, 3], [5], 'POS')]
45 | I like the ambience , it 's very dark and original .####[([3], [1], 'POS'), ([3], [8], 'POS'), ([3], [10], 'POS')]
46 | The sushi is amazing ! ! !####[([1], [3], 'POS')]
47 | Very affordable and excellent ambient !####[([4], [1], 'POS'), ([4], [3], 'POS')]
48 | My Girlfriend and I stumbled onto this hopping place the other night and had a great time !####[([8], [7], 'POS'), ([8], [15, 16], 'POS')]
49 | To be completely fair , the only redeeming factor was the food , which was above average , but could n't make up for all the other deficiencies of Teodora .####[([11], [15, 16], 'POS'), ([29], [27], 'NEG')]
50 | One of us actually liked the expresso - that 's it .####[([6], [4], 'POS')]
51 | We did n't want a bottle of bubbly on a weekday so we each got little bottles of Korbett it was just enough .####[([16, 17, 18], [22], 'POS')]
52 | Problem is nothing at Prune is particularly memorable .####[([4], [7], 'NEG')]
53 | Our food was great too !####[([1], [3], 'POS')]
54 | And really large portions .####[([3], [2], 'POS')]
55 | The food however , is what one might expect .####[([1], [8], 'NEG')]
56 | Prices too high for this cramped and unappealing resturant .####[([8], [5], 'NEG'), ([8], [7], 'NEG')]
57 | Thius is a must for anyone who loves Shabu-Shabu .####[([8], [7], 'POS')]
58 | Despite a slightly limited menu , everything prepared is done to perfection , ultra fresh and a work of food art .####[([4], [3], 'NEG')]
59 | The location and ambience is Ok but the food is what makes up for it .####[([1], [5], 'NEU'), ([3], [5], 'NEU')]
60 | I found the food , service and value exceptional everytime I have been there .####[([3], [8], 'POS'), ([5], [8], 'POS')]
61 | The service was excellent - friendly and attentive .####[([1], [3], 'POS'), ([1], [5], 'POS'), ([1], [7], 'POS')]
62 | Very good wine choices .####[([2, 3], [1], 'POS')]
63 | Great staff .####[([1], [0], 'POS')]
64 | But the staff was so horrible to us .####[([2], [5], 'NEG')]
65 | This place is pricey , and yes , the food is worth it ; but the service makes you feel like you should be paying a quater of the price .####[([1], [3], 'NEG'), ([9], [11], 'POS')]
66 | Do n't dine at Tamarind for the vegetarian dishes , they are simply not up to par with the non-veg selections .####[([7, 8], [13, 14, 15, 16], 'NEG')]
67 | Decor is nice though service can be spotty .####[([0], [2], 'POS'), ([4], [7], 'NEG')]
68 | I am happy i did the food was awsome .####[([6], [8], 'POS')]
69 | limited menu , no-so-fresh ingredients , thinly-sliced fish , fall-apart rice .####[([1], [0], 'NEG'), ([4], [3], 'NEG'), ([7], [6], 'NEG'), ([10], [9], 'NEG')]
70 | With the theater 2 blocks away we had a delicious meal in a beautiful room .####[([10], [9], 'POS'), ([14], [13], 'POS')]
71 | The seats are uncomfortable if you are sitting against the wall on wooden benches .####[([1], [3], 'NEG')]
72 | Waitstaff are very friendly .####[([0], [3], 'POS')]
73 | The lobster sandwich is $ 24 and although it was good it was not nearly enough to warrant that price .####[([1, 2], [10], 'NEG'), ([1, 2], [13, 14, 15, 16, 17, 18, 19], 'NEG')]
74 | The food was delicious ( I had a halibut special , my husband had steak ) , and the service was top-notch .####[([1], [3], 'POS'), ([19], [21], 'POS')]
75 | I almost hesititate to write a review because the atmosphere was so great and I would hate for it too become to crowded .####[([9], [12], 'POS')]
76 | Service is average .####[([0], [2], 'NEU')]
77 | The ambience was so fun , and the prices were great , on top of the fact that the food was really tasty .####[([1], [4], 'POS'), ([19], [22], 'POS')]
78 | I would highly recommend this place !####[([5], [3], 'POS')]
79 | Nice Family owned traditional restaurant .####[([4], [3], 'POS')]
80 | Fresh ingredients and everything is made to order .####[([1], [0], 'POS')]
81 | My friends settled for rice dishes , but we came back the following day to try the dim sum , which was good ... not outstanding , but good .####[([17, 18], [22], 'NEU'), ([17, 18], [24, 25], 'NEU')]
82 | I would recommend Roxy 's for that , but not for their food .####[([12], [2], 'NEG')]
83 | I had a huge pastrami sandwich on a roll .####[([4, 5, 6, 7, 8], [3], 'NEU')]
84 | We went here for lunch a couple of weeks ago on a Saturday , and I was thoroughly impressed with the food .####[([21], [18], 'POS')]
85 | We had the scallops as an appetizer and they were delicious and the sauce was wonderful .####[([3], [10], 'POS'), ([13], [15], 'POS')]
86 | The dishes offered were unique , very tasty and fresh from the lamb sausages , sardines with biscuits , large whole shrimp to the amazing pistachio ice cream ( the best and freshest I 've ever had ) .####[([1], [4], 'POS'), ([1], [7], 'POS'), ([1], [9], 'POS'), ([25, 26, 27], [24], 'POS')]
87 | I 'm glad I was introduced to this place and this is a rare gem in NY .####[([8], [2], 'POS')]
88 | The service was excellent and the food was delicious .####[([1], [3], 'POS'), ([6], [8], 'POS')]
89 | The food arrived 20 minutes after I called , cold and soggy .####[([1], [9], 'NEG'), ([1], [11], 'NEG')]
90 | The food looked very appetizing and delicious since it came on a variety of fancy plates .####[([1], [4], 'POS'), ([1], [6], 'POS')]
91 | By far , the best pizza in Manhattan .####[([5], [4], 'POS')]
92 | The food was mediocre at best but it was the horrible service that made me vow never to go back .####[([1], [3], 'NEG'), ([11], [10], 'NEG')]
93 | While their kitchen food is delicious , their Sushi is out of this world .####[([2, 3], [5], 'POS'), ([8], [10, 11, 12, 13], 'POS')]
94 | Mizu is home to creative and unique rolls not to found anywhere else .####[([7], [6], 'POS')]
95 | Not only is the cuisine the best around , the service has always been attentive and charming .####[([4], [6], 'POS'), ([10], [14], 'POS'), ([10], [16], 'POS')]
96 | The entree was bland and small , dessert was not inspired .####[([1], [3], 'NEG'), ([1], [5], 'NEG'), ([7], [9, 10], 'NEG')]
97 | Wonderful strawberry daiquiries as well !####[([1, 2], [0], 'POS')]
98 | Authentic Taiwanese food that 's cheap ... what more could you ask for ?####[([1, 2], [0], 'POS'), ([1, 2], [5], 'POS')]
99 | My friend devoured her chicken and mashed potatos .####[([4, 5, 6, 7], [2], 'POS')]
100 | Great neighborhood joint .####[([2], [0], 'POS')]
101 | This is a nice pizza place with good selection of thin crust pizza including the Basil slice .####[([8, 9, 10, 11, 12], [7], 'POS'), ([4, 5], [3], 'POS'), ([15, 16], [7], 'POS')]
102 | The dosas are skimpy , unattractive and drip with grease , and personally I 'd drink popcorn topping before I 'd eat another one of these .####[([1], [3], 'NEG'), ([1], [5], 'NEG')]
103 | Best Italian food I ever had ( and being Italian , that means alot ) .####[([1, 2], [0], 'POS')]
104 | The restaurant looks out over beautiful green lawns to the Hudson River and the Statue of Liberty .####[([1], [5], 'POS')]
105 | The food is good , especially their more basic dishes , and the drinks are delicious .####[([1], [3], 'POS'), ([8, 9], [3], 'POS'), ([13], [15], 'POS')]
106 | Good spreads , great beverage selections and bagels really tasty .####[([1], [0], 'POS'), ([4, 5], [3], 'POS'), ([7], [9], 'POS')]
107 | The cream cheeses are out of this world and I love that coffee ! !####[([1, 2], [4, 5, 6, 7], 'POS'), ([12], [10], 'POS')]
108 | The fish was adequate , but inexpertly sliced .####[([1], [3], 'NEG'), ([1], [6, 7], 'NEG')]
109 | Well , this place is so Ghetto its not even funny .####[([3], [6], 'NEG'), ([3], [8, 9, 10], 'NEG')]
110 | Awsome Pizza especially the Margheritta slice .####[([1], [0], 'POS'), ([4, 5], [0], 'POS')]
111 | Everything about this restaurant was special .####[([3], [5], 'POS')]
112 | You ca n't go wrong with this place .####[([7], [1, 2, 3, 4], 'POS')]
113 | The food is excellent !####[([1], [3], 'POS')]
114 | The restaurant is a bit noisy but that is something that can be overlooked once you sit down and enjoy a great meal####[([22], [19], 'POS'), ([22], [21], 'POS'), ([1], [5], 'NEG')]
115 | this little place has a cute interior decor and affordable city prices .####[([6, 7], [5], 'POS'), ([2], [1], 'POS')]
116 | delicious bagels , especially when right out of the oven .####[([1], [0], 'POS')]
117 | Service is fast and friendly .####[([0], [2], 'POS'), ([0], [4], 'POS')]
118 | Rao is a good restaurant , but it 's nothing special .####[([0], [3], 'NEU')]
119 | I really loved the different and inovated touch that 's the cheff gives to the food .####[([11], [2], 'POS'), ([11], [6], 'POS')]
120 | Drawbacks : service is slow and they do n't toast !####[([2], [4], 'NEG')]
121 | Volare virgins or weekly regulars , everyone gets treated the same and you ca n't ask for more than that when the service is this friendly .####[([22], [25], 'POS')]
122 | Lucky Strike is a great casual place to just grab a bite to eat .####[([0, 1], [4, 5], 'POS')]
123 | What a great place !####[([3], [2], 'POS')]
124 | This place has the best Chinese style BBQ ribs in the city .####[([7, 8], [4], 'POS')]
125 | Quick and friendly service .####[([3], [0], 'POS'), ([3], [2], 'POS')]
126 | This little place definitely exceeded my expectations and you sure get a lot of food for your money .####[([14], [12], 'POS'), ([2], [4, 5, 6], 'POS')]
127 | Service , however , was excellent ... and I liked the setting/atmosphere a lot .####[([0], [5], 'POS'), ([11], [9], 'POS')]
128 | People are always friendly .####[([0], [3], 'POS')]
129 | bottles of wine are cheap and good .####[([0, 1, 2], [4], 'POS'), ([0, 1, 2], [6], 'POS')]
130 | The food was actually aweful .####[([1], [4], 'NEG')]
131 | the drinks are amazing and half off till 8pm .####[([1], [3], 'POS')]
132 | This is an amazing place to try some roti rolls .####[([8, 9], [6], 'POS')]
133 | I really recommend the very simple Unda ( Egg ) rolls .####[([6, 7, 8, 9, 10], [2], 'POS'), ([6, 7, 8, 9, 10], [5], 'POS')]
134 | Delicate spices , onions , eggs and a kick-ass roti .####[([1], [0], 'POS'), ([3], [0], 'POS'), ([5], [0], 'POS'), ([9], [8], 'POS')]
135 | Best drumsticks over rice and sour spicy soup in town !####[([1, 2, 3], [0], 'POS'), ([5, 6, 7], [0], 'POS')]
136 | Beef noodle soup is good as well .####[([0, 1, 2], [4], 'POS')]
137 | Best Taiwanese food in NY !####[([1, 2], [0], 'POS')]
138 | I have been to Rao 's probably 15 times the past 3 years and it keeps getting better .####[([4, 5], [17], 'POS')]
139 | Staff is very accomodating .####[([0], [3], 'POS')]
140 | The decor is very simple but comfortable .####[([1], [4], 'POS'), ([1], [6], 'POS')]
141 | You must have the crabmeat lasagna which is out of this world and the chocolate bread pudding for dessert .####[([4, 5], [8, 9, 10, 11], 'POS')]
142 | whoever the jazz duo was , they were on POINT .####[([2, 3], [8, 9], 'POS')]
143 | even the wine by the glass was good .####[([2, 3, 4, 5], [7], 'POS')]
144 | The food is okay and the prices here are mediocre .####[([1], [3], 'NEU')]
145 | Baluchi 's has solid food and a nice decor at reasonable prices .####[([4], [3], 'POS'), ([8], [7], 'POS'), ([0, 1], [3], 'POS')]
146 | $ 20 for all you can eat sushi can not be beaten .####[([3, 4, 5, 6, 7], [11], 'POS')]
147 | The vibe is very relaxed and cozy , service was great and the food was excellent !####[([1], [4], 'POS'), ([1], [6], 'POS'), ([8], [10], 'POS'), ([13], [15], 'POS')]
148 | Never have I had such dramatic delivery guys ( a lot of huffing and panting and muttering under breath b/c I live in a walkup ) who always seem disappointed with their tips .####[([6, 7], [5], 'NEG')]
149 |
--------------------------------------------------------------------------------
/data/aste/rest16/dev.txt:
--------------------------------------------------------------------------------
1 | The food is very average ... the Thai fusion stuff is a bit too sweet , every thing they serve is too sweet here .####[([1], [4], 'NEG'), ([7, 8, 9], [13, 14], 'NEG')]
2 | We went around 9:30 on a Friday and it had died down a bit by then so the service was great !####[([18], [20], 'POS')]
3 | we love th pink pony .####[([3, 4], [1], 'POS')]
4 | the food is decent .####[([1], [3], 'NEU')]
5 | however , it 's the service that leaves a bad taste in my mouth .####[([5], [9, 10], 'NEG')]
6 | i happen to have a policy that goes along with a little bit of self-respect , which includes not letting a waiter intimidate me , i.e . make me feel bad asking for trivialities like water , or the check .####[([21], [30], 'NEG')]
7 | I tend to judge a sushi restaurant by its sea urchin , which was heavenly at sushi rose .####[([9, 10], [14], 'POS')]
8 | The sushi seemed pretty fresh and was adequately proportioned .####[([1], [4], 'POS'), ([1], [8], 'POS')]
9 | In the evening , this place attracted a well dressed , with it , NY crowd .####[([15], [6], 'POS')]
10 | The food was well prepared and the service impecable .####[([1], [3, 4], 'POS'), ([7], [8], 'POS')]
11 | The Prix Fixe menu is worth every penny and you get more than enough ( both in quantity AND quality ) .####[([1, 2, 3], [5], 'POS')]
12 | The kitchen however , is almost always slow .####[([1], [7], 'NEG')]
13 | Add to that great service and great food at a reasonable price and you have yourself the beginning of a great evening .####[([4], [3], 'POS'), ([7], [6], 'POS')]
14 | The pizza was delivered cold and the cheese was n't even fully melted !####[([1], [4], 'NEG'), ([7], [8, 9, 10, 11, 12], 'NEG')]
15 | Yes , they use fancy ingredients , but even fancy ingredients do n't make for good pizza unless someone knows how to get the crust right .####[([5], [4], 'POS'), ([16], [15], 'NEG')]
16 | Best Pastrami I ever had and great portion without being ridiculous .####[([1], [0], 'POS'), ([7], [6], 'POS')]
17 | My wife had the fried shrimp which are huge and loved it .####[([4, 5], [8], 'POS'), ([4, 5], [10], 'POS')]
18 | This place is the most Japanese it can ever get .####[([1], [5], 'POS')]
19 | Leon is an East Village gem : casual but hip , with well prepared basic French bistro fare , good specials , a warm and lively atmosphere .####[([0], [7], 'POS'), ([0], [9], 'POS'), ([20], [19], 'POS'), ([26], [23], 'POS'), ([26], [25], 'POS'), ([15, 16, 17], [12, 13], 'POS')]
20 | The food was bland oily .####[([1], [3, 4], 'NEG')]
21 | I went there for lunch and it was not as good as I expected from the reviews I read .####[([4], [8, 9, 10, 11, 12, 13], 'NEG')]
22 | This place is great .####[([1], [3], 'POS')]
23 | Great pizza and fantastic service .####[([1], [0], 'POS'), ([4], [3], 'POS')]
24 | The place is small and cramped but the food is fantastic .####[([1], [3], 'NEG'), ([1], [5], 'NEG'), ([8], [10], 'POS')]
25 | Moules were excellent , lobster ravioli was VERY salty !####[([0], [2], 'POS'), ([4, 5], [8], 'NEG')]
26 | Service is not exactly five star , but thats not really a big deal .####[([0], [2, 3, 4, 5], 'NEU')]
27 | Downstairs lounge is always a good attraction####[([0, 1], [5, 6], 'POS')]
28 | The staff is incredibly helpful and attentive .####[([1], [4], 'POS'), ([1], [6], 'POS')]
29 | Rude service , medicore food ... there are tons of restaurants in NY ... stay away from this one####[([1], [0], 'NEG'), ([4], [3], 'NEU')]
30 | I had a great time at Jekyll and Hyde !####[([6, 7, 8], [3, 4], 'POS')]
31 | The food was good too .####[([1], [3], 'POS')]
32 | The tuna and wasabe potatoes are excellent .####[([1], [6], 'POS'), ([3, 4], [6], 'POS')]
33 | Great service , great food .####[([1], [0], 'POS'), ([4], [3], 'POS')]
34 | The pizza is delicious - they use fresh mozzarella instead of the cheap , frozen , shredded cheese common to most pizzaria 's .####[([1], [3], 'POS')]
35 | He served me an Uni Hand roll , which I never had before , and let me tell you ... IT WAS HEAVEN !####[([4, 5, 6], [22], 'POS')]
36 | My husband and I thougt it would be great to go to the Jekyll and Hyde Pub for our anniversary , and to our surprise it was fantastic .####[([13, 14, 15, 16], [8], 'POS'), ([13, 14, 15, 16], [27], 'POS')]
37 | This was my frist time at Cafe St. Bart 's and I must say how delicious the food and the service was .####[([17], [15], 'POS')]
38 | I have to highly recommend the lobster roll - not to much mayo ; you can tell it was a fresh lobster .####[([6, 7], [4], 'POS'), ([21], [20], 'POS')]
39 | All the staff is absolutely professional ! !####[([2], [5], 'POS')]
40 | This restaurant was way overhyped .####[([1], [4], 'NEG')]
41 | It 's boring on the inside , and our sushi was pretty below average ... the tuna was soggy and the other rolls had no flavor .####[([9], [12, 13], 'NEG'), ([16], [18], 'NEG'), ([22], [24, 25], 'NEG')]
42 | Their pad penang is delicious and everything else is fantastic .####[([1, 2], [4], 'POS')]
43 | The price is reasonable although the service is poor .####[([6], [8], 'NEG')]
44 | The spicy Tuna roll is huge and probably the best that I 've had at this price range .####[([1, 2, 3], [5], 'POS'), ([1, 2, 3], [9], 'POS')]
45 | The staff was accomodating , the food was absolutely delicious and the place is lovely .####[([1], [3], 'POS'), ([6], [9], 'POS'), ([12], [14], 'POS')]
46 | The food is authentic Italian - delicious !####[([1], [3, 4], 'POS'), ([1], [6], 'POS')]
47 | I 'm still mad that i had to pay for lousy food .####[([11], [10], 'NEG')]
48 | Very affordable and excellent ambient !####[([4], [1], 'POS'), ([4], [3], 'POS')]
49 | We wo n't go to this place again for a good meal .####[([11], [10], 'NEG')]
50 | However , I think this place is a good hang out spot .####[([5], [8], 'POS')]
51 | Cute place , nice wait staff but would never go there again .####[([4, 5], [3], 'POS'), ([1], [0], 'NEG')]
52 | Someone else recommended the dessert - we also left that .####[([4], [2], 'NEG')]
53 | I 've never had bad service and the fish is fresh and delicious .####[([5], [2, 3, 4], 'POS'), ([8], [10], 'POS'), ([8], [12], 'POS')]
54 | The place is so cool and the service is prompt and curtious .####[([7], [9], 'POS'), ([7], [11], 'POS'), ([1], [4], 'POS')]
55 | My boyfriend had the New England Chowder it was good but I think the award should go to the Lobster Bisque .####[([4, 5, 6], [9], 'POS'), ([19, 20], [14], 'POS')]
56 | The characters really make for an enjoyable experience .####[([1], [6], 'POS')]
57 | Food was good not great not worth the wait or another visit####[([0], [2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 'NEU')]
58 | The lox is always fresh too .####[([1], [4], 'POS')]
59 | The service is ok , some of the people did n't get what they asked for .####[([1], [3], 'NEU')]
60 | The wine the service was very good too .####[([1], [6], 'POS'), ([3], [6], 'POS')]
61 | Great staff .####[([1], [0], 'POS')]
62 | The hostess and the waitress were incredibly rude and did everything they could to rush us out .####[([1], [7], 'NEG'), ([4], [7], 'NEG')]
63 | This place is always packed .####[([1], [4], 'NEU')]
64 | and yes Dal Bukhara is so dam good and so are all the kababs .####[([13], [7], 'POS'), ([2, 3], [7], 'POS')]
65 | I have been to Roth 's twice and both times were very disappointing .####[([4, 5], [12], 'NEG')]
66 | Chennai Garden is my favorite Indian restaurant in the city .####[([0, 1], [4], 'POS')]
67 | They have authentic Indian at amazin prices .####[([3], [2], 'POS')]
68 | It 's a rather cramped and busy restaurant and it closes early .####[([7], [4], 'NEG'), ([7], [6], 'NEG')]
69 | Food is excellent .####[([0], [2], 'POS')]
70 | Fish is so very fresh .####[([0], [4], 'POS')]
71 | Love YUKA .####[([1], [0], 'POS')]
72 | The food is so cheap and the waiters are nice .####[([1], [4], 'POS'), ([7], [9], 'POS')]
73 | Be sure to try the seasonal , and always delicious , specials .####[([11], [3], 'POS'), ([11], [5], 'POS'), ([11], [9], 'POS')]
74 | Salads are a delicious way to begin the meal .####[([0], [3], 'POS')]
75 | I would definitely recommend SEA if you like thai cuisine !####[([8, 9], [7], 'POS')]
76 | I absolutely Loved this place .####[([4], [2], 'POS')]
77 | Everything was wonderful ; food , drinks , staff , mileau .####[([4], [2], 'POS'), ([6], [2], 'POS'), ([8], [2], 'POS'), ([10], [2], 'POS')]
78 | Nice Family owned traditional restaurant .####[([4], [3], 'POS')]
79 | I also ordered the Change Mojito , which was out of this world .####[([4, 5], [9, 10, 11, 12], 'POS')]
80 | The place was nice and calm .####[([1], [3], 'POS'), ([1], [5], 'POS')]
81 | Consequently , their burgers fell apart in their hands and made such a mess that they did'nt feel like finishing them .####[([3], [4, 5], 'NEG')]
82 | I had a huge pastrami sandwich on a roll .####[([4, 5, 6, 7, 8], [3], 'NEU')]
83 | THe back garden sitting area is very pleasant , where you can see their personal herb garden .####[([1, 2, 3, 4], [7], 'POS')]
84 | We ended our great experience by having Gulab Jamun ( dessert ) recommended by the waiter .####[([7, 8, 9, 10, 11], [3], 'POS')]
85 | I thanked my friend who recommended me this restaurant and will certainly recommend it to others .####[([8], [12], 'POS')]
86 | I am reluctant to write because I would not want my jem of a pizza place to become overcrowded .####[([14, 15], [18], 'POS')]
87 | While their kitchen food is delicious , their Sushi is out of this world .####[([2, 3], [5], 'POS'), ([8], [10, 11, 12, 13], 'POS')]
88 | Thalia is a beautiful restaurant with beautiful people serving you , but the food does n't quite match up .####[([7], [6], 'POS'), ([13], [14, 15, 16, 17, 18], 'NEG'), ([0], [3], 'POS')]
89 | I expected quite a bit more from such an expensive menu .####[([10], [9], 'NEG')]
90 | The view is spectacular , and the food is great .####[([1], [3], 'POS'), ([7], [9], 'POS')]
91 | Authentic Taiwanese food that 's cheap ... what more could you ask for ?####[([1, 2], [0], 'POS'), ([1, 2], [5], 'POS')]
92 | Kind , attentive wait staff .####[([3, 4], [0], 'POS'), ([3, 4], [2], 'POS')]
93 | My friend devoured her chicken and mashed potatos .####[([4, 5, 6, 7], [2], 'POS')]
94 | The atmosphere is unheralded , the service impecible , and the food magnificant .####[([1], [3], 'POS'), ([6], [7], 'POS'), ([11], [12], 'POS')]
95 | This is such a lovely , peaceful place to eat outside .####[([7], [4], 'POS'), ([7], [6], 'POS')]
96 | Great sushi experience .####[([1], [0], 'POS')]
97 | This place is not worth the prices .####[([1], [3, 4, 5, 6], 'NEG')]
98 | Love Pizza 33 ...####[([1, 2], [0], 'POS')]
99 | The rice was poor quality and was cooked so badly it was hard .####[([1], [3, 4], 'NEG'), ([1], [7, 8, 9], 'NEG'), ([1], [12], 'NEG')]
100 | The fish was adequate , but inexpertly sliced .####[([1], [3], 'NEG'), ([1], [6, 7], 'NEG')]
101 | The wait staff is pleasant , fun , and for the most part gorgeous ( in the wonderful aesthetic beautification way , not in that she's-way-cuter-than-me-that-b @ # $ * way ) .####[([1, 2], [4], 'POS'), ([1, 2], [6], 'POS'), ([1, 2], [13], 'POS')]
102 | But the best part about LS is the late night atmosphere , delightfully free of the BTs .####[([8, 9, 10], [2], 'POS')]
103 | Suan is a great place that I often take my friends ( classmates ) too .####[([0], [3], 'POS')]
104 | noodles with shrimp and chicken and coconut juice is the MUST !####[([0, 1, 2, 3, 4, 5, 6, 7], [10], 'POS')]
105 | I can not imagine a friendlier staff working in a restaurant .####[([6], [5], 'POS')]
106 | I can not imagine better Indian food in all of the city .####[([5, 6], [4], 'POS')]
107 | if you 're daring , try the balsamic vinegar over icecream , it 's wonderful !####[([7, 8, 9, 10], [5], 'POS'), ([7, 8, 9, 10], [14], 'POS')]
108 | The rest of the dim sum , though pricey by Chinatown standards , is worth it .####[([4, 5], [8], 'POS'), ([4, 5], [14], 'POS')]
109 | A few tips : skip the turnip cake , roast pork buns and egg custards .####[([6, 7], [4], 'NEG'), ([9, 10, 11], [4], 'NEG'), ([13, 14], [4], 'NEG')]
110 | The food was exceptional .####[([1], [3], 'POS')]
111 | it 's a perfect place to have a amazing indian food .####[([9, 10], [8], 'POS')]
112 | Drawbacks : service is slow and they do n't toast !####[([2], [4], 'NEG')]
113 | Downtown Dinner 2002 - Prixe fix : Appetizers were ok , waiter gave me poor suggestion ... try the potato stuff kanish best one .####[([7], [9], 'NEU'), ([11], [14], 'NEG'), ([19, 20, 21], [17], 'POS'), ([19, 20, 21], [22], 'POS')]
114 | The anti-pasta was excellent , especially the calamari , as were the filling pasta mains .####[([1], [3], 'POS'), ([7], [3], 'POS'), ([13, 14], [3], 'POS')]
115 | Great food , great decor , great service .####[([1], [0], 'POS'), ([4], [3], 'POS'), ([7], [6], 'POS')]
116 | Not the typical NYC gimmick theme restaurant .####[([6], [0, 1, 2], 'POS')]
117 | Service was very prompt but slightly rushed .####[([0], [3], 'NEG'), ([0], [6], 'NEG')]
118 | I ca n't wait for summer , when they serve outside on their gigantic patio .####[([14], [13], 'POS')]
119 | Good drink .####[([1], [0], 'POS')]
120 | i 've been to sapphire twice and both times the food was fine , if not good .####[([10], [12], 'POS')]
121 | stick with the chicken , beef , and lamb dishes .####[([3], [0], 'POS'), ([5], [0], 'POS'), ([8, 9], [0], 'POS')]
122 | service is friendly , and never had a problem walking in and getting a table .####[([0], [2], 'POS')]
123 | skip dessert .####[([1], [0], 'NEG')]
124 | Pizza was a little soggy .####[([0], [4], 'NEG')]
125 | This place is a great bargain .####[([1], [4, 5], 'POS')]
126 | The design and atmosphere is just as good .####[([1], [7], 'POS'), ([3], [7], 'POS')]
127 | the drinks are amazing and half off till 8pm .####[([1], [3], 'POS')]
128 | This is an amazing place to try some roti rolls .####[([8, 9], [6], 'POS')]
129 | The food 's as good as ever .####[([1], [4], 'POS')]
130 | Best drumsticks over rice and sour spicy soup in town !####[([1, 2, 3], [0], 'POS'), ([5, 6, 7], [0], 'POS')]
131 | The service is good and the resturant is clean .####[([1], [3], 'POS'), ([6], [8], 'POS')]
132 | We recently decided to try this location , and to our delight , they have outdoor seating , perfect since I had my yorkie with me .####[([15, 16], [18], 'POS')]
133 | Great Indian food and the service is incredible .####[([1, 2], [0], 'POS'), ([5], [7], 'POS')]
134 | The food here does a great service to the name ( Cantonese that is ... ) .####[([1], [5], 'POS')]
135 | good music , great food , speedy service affordable prices .####[([1], [0], 'POS'), ([4], [3], 'POS'), ([7], [6], 'POS')]
136 | Atmosphere is nice and relaxed too ...####[([0], [2], 'POS'), ([0], [4], 'POS')]
137 | If you do n't mind pre-sliced low quality fish , unfriendly staff and a sushi chef that looks like he is miserable then this is your place .####[([8], [6, 7], 'NEG'), ([11], [10], 'NEG'), ([14, 15], [21], 'NEG')]
138 | One would think we 'd get an apology or complimentary drinks - instead , we got a snobby waiter would n't even take our order for 15 minutes and gave us lip when we asked him to do so .####[([18], [17], 'NEG')]
139 | With so many good restaurants on the UWS , I do n't need overpriced food , absurdly arrogant wait-staff who do n't recognize they work at a glorified diner , clumsy service , and management that does n't care .####[([14], [13], 'NEG'), ([18], [17], 'NEG'), ([31], [30], 'NEG')]
140 | $ 20 for all you can eat sushi can not be beaten .####[([3, 4, 5, 6, 7], [11], 'POS')]
141 | Food was good and the view of the new york city skiline was terrific even on a foggy rainy day like that of when I went .####[([0], [2], 'POS'), ([5, 6, 7, 8, 9, 10, 11], [13], 'POS')]
142 | Although they do the typical what kind of water would you like questions the service was good and overall very relaxing to place to eat .####[([14], [16], 'POS'), ([22], [20], 'POS')]
143 | The pizza was pretty good and huge .####[([1], [4], 'POS'), ([1], [6], 'POS')]
144 | La Rosa waltzes in , and I think they are doing it the best .####[([0, 1], [13], 'POS')]
145 | The mussels were fantastic and so was the dessert ... definitely going to be back very soon .####[([1], [3], 'POS'), ([8], [3], 'POS')]
146 | I have been coming here for years and have nothing but good things to say about the service and the great staff at La Lanterna .####[([17], [11], 'POS'), ([21], [20], 'POS')]
147 | Love Al Di La####[([1, 2, 3], [0], 'POS')]
148 | An awesome organic dog , and a conscious eco friendly establishment .####[([3], [2], 'POS'), ([10], [8, 9], 'POS')]
149 | But the best pork souvlaki I ever had is the main thing .####[([3, 4], [2], 'POS')]
150 | I LOOOVE their eggplant pizza , as well as their pastas !####[([3, 4], [1], 'POS'), ([10], [1], 'POS')]
151 | We had half/half pizza , mine was eggplant and my friend had the buffalo and it was sooo huge for a small size pizza !####[([2, 3], [18], 'POS')]
152 | Reliable , Fresh Sushi####[([3], [0], 'POS'), ([3], [2], 'POS')]
153 | The sashimi is always fresh and the rolls are innovative and delicious .####[([1], [4], 'POS'), ([7], [9], 'POS'), ([7], [11], 'POS')]
154 | Delivery guy sometimes get upset if you do n't tip more than 10 % .####[([0, 1], [4], 'NEG')]
155 | The place is a bit hidden away , but once you get there , it 's all worth it .####[([1], [5, 6], 'POS'), ([1], [17], 'POS')]
156 | Good food : my favorite is the seafood spaghetti .####[([1], [0], 'POS'), ([7, 8], [4], 'POS')]
157 | The wait staff is very courteous and accomodating .####[([1, 2], [5], 'POS'), ([1, 2], [7], 'POS')]
158 | I thought the restaurant was nice and clean .####[([3], [5], 'POS'), ([3], [7], 'POS')]
159 | WORST PLACE ON SMITH STREET IN BROOKLYN####[([1], [0], 'NEG')]
160 | The waitress was not attentive at all .####[([1], [3, 4], 'NEG')]
161 | The Seafood Dynamite is also otherworldly .####[([1, 2], [5], 'POS')]
162 | In the summer months , the back garden area is really nice .####[([6, 7, 8], [11], 'POS')]
163 | The rolls are creative and I have yet to find another sushi place that serves up more inventive yet delicious japanese food .####[([1], [3], 'POS'), ([20, 21], [17], 'POS'), ([20, 21], [19], 'POS')]
164 | I CAN EAT HERE EVERY DAY OF THE WEEK REALLY LOL LOVE THIS PLACE ... )####[([13], [11], 'POS')]
165 | Great Indian Food !####[([1, 2], [0], 'POS')]
166 | This is one of my favorite spot , very relaxing the food is great all the times , celebrated my engagement and my wedding here , it was very well organized .####[([11], [13], 'POS')]
167 | Love their drink menu .####[([2, 3], [0], 'POS')]
168 | A beautifully designed dreamy Egyptian restaurant that gets sceney at night .####[([4, 5], [3], 'POS')]
169 | Watch the talented belly dancers as you enjoy delicious baba ganoush that 's more lemony than smoky .####[([9, 10], [7, 8], 'POS'), ([3, 4], [2], 'POS')]
170 | The drinks are great , especially when made by Raymond .####[([1], [3], 'POS'), ([9], [3], 'POS')]
171 | Decor needs to be upgraded but the food is amazing !####[([0], [4], 'NEG'), ([7], [9], 'POS')]
172 | Great food , amazing service , this place is a class act .####[([1], [0], 'POS'), ([4], [3], 'POS'), ([7], [10, 11], 'POS')]
173 | Paul , the maitre d ' , was totally professional and always on top of things .####[([0], [9], 'POS')]
174 | The bar drinks were Eh , ok to say the least .####[([1, 2], [6], 'NEG')]
175 | The bread we received was horrible - rock hard and cold - and the `` free '' appetizer of olives was disappointing .####[([1], [5], 'NEG'), ([1], [7, 8], 'NEG'), ([1], [10], 'NEG'), ([17, 18, 19], [21], 'NEG')]
176 | short and sweet – seating is great : it 's romantic , cozy and private .####[([4], [6], 'POS')]
177 | The service was extremely fast and attentive ( thanks to the service button on your table ) but I barely understood 1 word when the waiter took our order .####[([1], [4], 'POS'), ([1], [6], 'POS'), ([11, 12], [8, 9], 'POS'), ([25], [19, 20], 'NEG')]
178 | Highly impressed from the decor to the food to the hospitality to the great night I had !####[([4], [1], 'POS'), ([7], [1], 'POS')]
179 | Food took some time to prepare , all worth waiting for .####[([0], [8], 'POS')]
180 | The menu looked great , and the waiter was very nice , but when the food came , it was average .####[([1], [3], 'POS'), ([7], [10], 'POS'), ([15], [20], 'NEU')]
181 | It 's a great place to order from or sit-in .####[([4], [3], 'POS')]
182 | Yamato is an excellent place to go if youre not into sashimi , or if you have friends who doesnt like sushi much .####[([0], [3], 'POS')]
183 | I 've had my fair share of modern Japanese and this spot delivers .####[([7, 8], [12], 'POS')]
184 | Everything on the menu is great .####[([3], [5], 'POS')]
185 | Bison was quite excellent however .####[([0], [3], 'POS')]
186 | All in all , the food was great ( except for the dessserts ) .####[([5], [7], 'POS')]
187 | However , our $ 14 drinks were were horrible !####[([5], [8], 'NEG')]
188 | The menu is fairly simple without much descriptions .####[([1], [4], 'NEU')]
189 | Not much of a selection of bottled beer either , we went with Brahma .####[([4, 5, 6, 7], [0, 1], 'NEG')]
190 | All in all the food was good - a little on the expensive side , but fresh .####[([4], [6], 'NEG'), ([4], [12], 'NEG'), ([4], [16], 'NEG')]
191 | It was n't as if this restaurant had any major bragging points before hand , but now it 's simply repulsive .####[([6], [20], 'NEG')]
192 | Gorgeous place ideal for a romantic dinner####[([1], [0], 'POS'), ([1], [2], 'POS')]
193 | The nakgi-bokum was horrible .####[([1], [3], 'NEG')]
194 | The side dishes were passable , and I did get a refill upon request .####[([1, 2], [4], 'NEU')]
195 | My wife had barely touched that mess of a dish .####[([9], [6], 'NEG')]
196 | The wife had the risotto which was amazing .####[([4], [7], 'POS')]
197 | The crust has a great bite and a good chew , the sauce is light with a nice acidity to it , the salt from the cheese is great , really heightens the flavor of all the other components .####[([1], [4], 'POS'), ([1], [8], 'POS'), ([12], [14], 'POS'), ([26], [28], 'POS')]
198 | I picked the Grilled Black Cod as my entree , which I absolutely devoured while someone commented that the Grilled Salmon dish was better .####[([3, 4, 5], [13], 'POS'), ([19, 20, 21], [23], 'POS')]
199 | The service leaves much to be desired , from feeling like you are rushed the place your order , to being ignored the rest of the night .####[([1], [2, 3, 4, 5, 6], 'NEG')]
200 | The hot dogs are good , yes , but the reason to get over here is the fantastic pork croquette sandwich , perfect on its supermarket squishy bun .####[([1, 2], [4], 'POS'), ([18, 19, 20], [17], 'POS'), ([27], [22], 'POS')]
201 | The family seafood entree was very good .####[([1, 2, 3], [6], 'POS')]
202 | Price is high but the food is good , so I would come back again .####[([5], [7], 'NEG')]
203 | This place is not inviting and the food is totally weird .####[([1], [3, 4], 'NEG'), ([7], [10], 'NEG')]
204 | A coworker and I tried Pacifico after work a few Fridays and loved it .####[([5], [12], 'POS')]
205 | The food we ordered was excellent , although I would n't say the margaritas were anything to write home about .####[([1], [5], 'POS')]
206 | The hot dogs are top notch , and they 're Slamwich is amazing !####[([1, 2], [4, 5], 'POS'), ([10], [12], 'POS')]
207 | But nonetheless -- great spot , great food .####[([4], [3], 'POS'), ([7], [6], 'POS')]
208 | This guy refused to seat her and she left , followed shortly by the four of us , but not before I told him that in my 40 years of world travel , including Paris , that I had never seen such a display of bad behavior by a frontman in a restaurant .####[([49], [45], 'NEG')]
209 | Mussles and calamari were superb Saturday evening .####[([0], [4], 'POS'), ([2], [4], 'POS')]
210 | I had the Lamb special which was perfect .####[([3, 4], [7], 'POS')]
211 |
--------------------------------------------------------------------------------
/data/tasd/rest15/dev.txt:
--------------------------------------------------------------------------------
1 | Judging from previous posts this used to be a good place , but not any longer .####[('place', 'restaurant general', 'negative')]
2 | We , there were four of us , arrived at noon - the place was empty - and the staff acted like we were imposing on them and they were very rude .####[('staff', 'service general', 'negative')]
3 | They never brought us complimentary noodles , ignored repeated requests for sugar , and threw our dishes on the table .####[('NULL', 'service general', 'negative')]
4 | The food was lousy - too sweet or too salty and the portions tiny .####[('food', 'food quality', 'negative'), ('portions', 'food style_options', 'negative')]
5 | After all that , they complained to me about the small tip .####[('NULL', 'service general', 'negative')]
6 | Avoid this place !####[('place', 'restaurant general', 'negative')]
7 | I have eaten at Saul , many times , the food is always consistently , outrageously good .####[('food', 'food quality', 'positive')]
8 | Saul is the best restaurant on Smith Street and in Brooklyn .####[('Saul', 'restaurant general', 'positive')]
9 | The duck confit is always amazing and the foie gras terrine with figs was out of this world .####[('foie gras terrine with figs', 'food quality', 'positive'), ('duck confit', 'food quality', 'positive')]
10 | The wine list is interesting and has many good values .####[('wine list', 'drinks style_options', 'positive'), ('wine list', 'drinks prices', 'positive')]
11 |
--------------------------------------------------------------------------------
/data/tasd/rest16/dev.txt:
--------------------------------------------------------------------------------
1 | Judging from previous posts this used to be a good place , but not any longer .####[('place', 'restaurant general', 'negative')]
2 | We , there were four of us , arrived at noon - the place was empty - and the staff acted like we were imposing on them and they were very rude .####[('staff', 'service general', 'negative')]
3 | They never brought us complimentary noodles , ignored repeated requests for sugar , and threw our dishes on the table .####[('NULL', 'service general', 'negative')]
4 | The food was lousy - too sweet or too salty and the portions tiny .####[('food', 'food quality', 'negative'), ('portions', 'food style_options', 'negative')]
5 | After all that , they complained to me about the small tip .####[('NULL', 'service general', 'negative')]
6 | Avoid this place !####[('place', 'restaurant general', 'negative')]
7 | I have eaten at Saul , many times , the food is always consistently , outrageously good .####[('food', 'food quality', 'positive')]
8 | Saul is the best restaurant on Smith Street and in Brooklyn .####[('Saul', 'restaurant general', 'positive')]
9 | The duck confit is always amazing and the foie gras terrine with figs was out of this world .####[('foie gras terrine with figs', 'food quality', 'positive'), ('duck confit', 'food quality', 'positive')]
10 | The wine list is interesting and has many good values .####[('wine list', 'drinks style_options', 'positive'), ('wine list', 'drinks prices', 'positive')]
11 | For the price , you cannot eat this well in Manhattan .####[('NULL', 'restaurant prices', 'positive'), ('NULL', 'food quality', 'positive')]
12 | I was very disappointed with this restaurant .####[('restaurant', 'restaurant general', 'negative')]
13 | Ive asked a cart attendant for a lotus leaf wrapped rice and she replied back rice and just walked away .####[('cart attendant', 'service general', 'negative')]
14 | I had to ask her three times before she finally came back with the dish Ive requested .####[('NULL', 'service general', 'negative')]
15 | Food was okay , nothing great .####[('Food', 'food quality', 'neutral')]
16 | Chow fun was dry ; pork shu mai was more than usually greasy and had to share a table with loud and rude family . ####[('Chow fun', 'food quality', 'negative'), ('pork shu mai', 'food quality', 'negative'), ('NULL', 'restaurant miscellaneous', 'negative')]
17 | I /we will never go back to this place again .####[('place', 'restaurant general', 'negative')]
18 | Went on a 3 day oyster binge , with Fish bringing up the closing , and I am so glad this was the place it O trip ended , because it was so great !####[('Fish', 'restaurant general', 'positive')]
19 | Service was devine , oysters where a sensual as they come , and the price can 't be beat ! ! !####[('Service', 'service general', 'positive'), ('oysters', 'food quality', 'positive'), ('NULL', 'restaurant prices', 'positive')]
20 | You can 't go wrong here .####[('NULL', 'restaurant general', 'positive')]
21 | Every time in New York I make it a point to visit Restaurant Saul on Smith Street .####[('Restaurant Saul', 'restaurant general', 'positive')]
22 | Everything is always cooked to perfection , the service is excellent , the decor cool and understated .####[('NULL', 'food quality', 'positive'), ('service', 'service general', 'positive'), ('decor', 'ambience general', 'positive')]
23 | I had the duck breast special on my last visit and it was incredible .####[('duck breast special', 'food quality', 'positive')]
24 | Can 't wait wait for my next visit .####[('NULL', 'restaurant general', 'positive')]
25 | And I hate to say this but I doubt I 'll ever go back . ####[('NULL', 'restaurant general', 'negative')]
26 | The food is very average . . .the Thai fusion stuff is a bit too sweet , every thing they serve is too sweet here .####[('food', 'food quality', 'negative'), ('Thai fusion stuff', 'food quality', 'negative'), ('NULL', 'food quality', 'negative')]
27 | The only thing I moderately enjoyed was their Grilled Chicken special with Edamame Puree .####[('Grilled Chicken special with Edamame Puree', 'food quality', 'positive')]
28 | I had never had Edamame pureed before but I thought it was innovative and tasty (could 've used a bit more salt ) .####[('Edamame pureed', 'food quality', 'positive'), ('Edamame pureed', 'food style_options', 'positive')]
29 | The decor is night tho . . .but they REALLY need to clean that vent in the ceiling . . .its quite un-appetizing , and kills your effort to make this place look sleek and modern .####[('place', 'ambience general', 'negative'), ('decor', 'ambience general', 'positive'), ('vent', 'ambience general', 'negative')]
30 |
--------------------------------------------------------------------------------
/images/framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZubinGou/multi-view-prompting/549a2b79f9bc2966242e473777a21839411c3157/images/framework.png
--------------------------------------------------------------------------------
/images/multi-task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZubinGou/multi-view-prompting/549a2b79f9bc2966242e473777a21839411c3157/images/multi-task.png
--------------------------------------------------------------------------------
/images/result_chatgpt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZubinGou/multi-view-prompting/549a2b79f9bc2966242e473777a21839411c3157/images/result_chatgpt.png
--------------------------------------------------------------------------------
/images/result_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZubinGou/multi-view-prompting/549a2b79f9bc2966242e473777a21839411c3157/images/result_main.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | typing-extensions==4.6.2
2 | sentencepiece==0.1.99
3 | numpy==1.24.3
4 | pandas==1.5.3
5 | pytorch_lightning==1.9.5
6 | tqdm==4.65.0
7 | transformers==4.14.1
8 | openai==0.27.7
9 | Requests==2.31.0
--------------------------------------------------------------------------------
/scripts/eval_unified.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | export CUDA_VISIBLE_DEVICES=0
4 |
5 | cd src
6 |
7 | for SEED in 10
8 | # for SEED in 5 10 15 20 25
9 | do
10 | K=5
11 | INFER_PATH=$K
12 | CTRL_TOKEN=post
13 | TASK=unified
14 | OUT_DIR="../outputs/$TASK/top${K}_seed${SEED}"
15 |
16 | mkdir -p $OUT_DIR
17 |
18 |
19 | python main.py \
20 | --data_path "../data/" \
21 | --dataset seed$SEED \
22 | --model_name_or_path "t5-base" \
23 | --output_dir $OUT_DIR \
24 | --num_train_epochs 20 \
25 | --save_top_k 0 \
26 | --task $TASK \
27 | --top_k $K \
28 | --ctrl_token $CTRL_TOKEN \
29 | --multi_path \
30 | --num_path $INFER_PATH \
31 | --seed $SEED \
32 | --train_batch_size 16 \
33 | --gradient_accumulation_steps 1 \
34 | --learning_rate 1e-4 \
35 | --lowercase \
36 | --sort_label \
37 | --data_ratio 1.0 \
38 | --check_val_every_n_epoch 10 \
39 | --agg_strategy vote \
40 | --eval_batch_size 128 \
41 | --constrained_decode \
42 | --multi_task \
43 | > $OUT_DIR/eval.log
44 | # --do_train \
45 | # --load_ckpt_name "best.ckpt" \
46 | # --load_path_cache \
47 | # > $OUT_DIR/eval.log 2>&1&
48 | done
49 |
--------------------------------------------------------------------------------
/scripts/process_unify.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 | set -ex
3 |
4 |
5 | cd src
6 |
7 | python data_process/process_unify.py
8 |
--------------------------------------------------------------------------------
/scripts/run_llms.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 | set -ex
3 |
4 |
5 | cd src
6 |
7 |
8 | for DATA in rest15
9 | do
10 |
11 | TASK=asqp
12 | K=1
13 | INFER_PATH=$K
14 | CTRL_TOKEN=none
15 | OUT_DIR="../outputs/$TASK/${DATA}/top${K}_${CTRL_TOKEN}_data${DATA_RATIO}_seed${SEED}"
16 |
17 | mkdir -p $OUT_DIR
18 |
19 | python -u llms/infer.py \
20 | --data_path "../data/" \
21 | --dataset $DATA \
22 | --model_name_or_path t5-base \
23 | --output_dir $OUT_DIR \
24 | --save_top_k 0 \
25 | --task $TASK \
26 | --top_k $K \
27 | --ctrl_token $CTRL_TOKEN \
28 | --num_path $INFER_PATH \
29 | --seed 0 \
30 | --train_batch_size 16 \
31 | --gradient_accumulation_steps 1 \
32 | --learning_rate 1e-4 \
33 | --lowercase \
34 | --sort_label \
35 | --check_val_every_n_epoch 10 \
36 | --constrained_decode \
37 | --single_view_type heuristic \
38 |
39 | done
--------------------------------------------------------------------------------
/scripts/run_low_resource.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | export CUDA_VISIBLE_DEVICES=0
4 |
5 | cd src
6 |
7 | TASK=aste
8 | for DATA in laptop14
9 | do
10 | for DATA_RATIO in 0.01 0.02 0.05 0.1 0.2 # few-shot
11 | # for DATA_RATIO in 0.0 # zero-shot
12 | do
13 | for SEED in 5 10 15 20 25
14 | do
15 | for K in 5
16 | # for K in 1 3 7 15
17 | do
18 | INFER_PATH=$K
19 | CTRL_TOKEN=post
20 | OUT_DIR="../outputs/$TASK/${DATA}/top${K}_${CTRL_TOKEN}_data${DATA_RATIO}_acos5_seed${SEED}"
21 |
22 | mkdir -p $OUT_DIR
23 |
24 | python main.py \
25 | --data_path "../data/" \
26 | --dataset $DATA \
27 | --model_name_or_path outputs/acos/rest16/top5_post_data1.0_seed${SEED}/final \
28 | --output_dir $OUT_DIR \
29 | --num_train_epochs 20 \
30 | --save_top_k 0 \
31 | --task $TASK \
32 | --top_k $K \
33 | --ctrl_token $CTRL_TOKEN \
34 | --multi_path \
35 | --num_path $INFER_PATH \
36 | --seed $SEED \
37 | --train_batch_size 8 \
38 | --gradient_accumulation_steps 1 \
39 | --learning_rate 1e-4 \
40 | --lowercase \
41 | --sort_label \
42 | --data_ratio $DATA_RATIO \
43 | --check_val_every_n_epoch 10 \
44 | --agg_strategy vote \
45 | --eval_batch_size 64 \
46 | --constrained_decode \
47 | --do_train \
48 | # --load_path_cache \
49 | # > $OUT_DIR/train.log 2>&1&
50 | done
51 | done
52 | done
53 | done
54 |
--------------------------------------------------------------------------------
/scripts/run_main.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | export CUDA_VISIBLE_DEVICES=0
4 |
5 | declare -A TASK_DATA
6 | TASK_DATA[asqp]="rest15 rest16"
7 | TASK_DATA[acos]="laptop16 rest16"
8 | TASK_DATA[aste]="laptop14"
9 | TASK_DATA[tasd]="rest15 rest16"
10 |
11 | cd src
12 |
13 | # for SVP_TYPE in heuristic rand rank
14 | for TASK in aste
15 | do
16 | for DATA in ${TASK_DATA[${TASK}]}
17 | do
18 | for DATA_RATIO in 1.0
19 | do
20 | for SEED in 5 10 15 20 25
21 | do
22 | for K in 5
23 | # for K in 3 7 15
24 | do
25 | INFER_PATH=$K
26 | CTRL_TOKEN=post
27 | OUT_DIR="../outputs/$TASK/${DATA}/top${K}_${CTRL_TOKEN}_data${DATA_RATIO}"
28 |
29 | mkdir -p $OUT_DIR
30 |
31 |
32 | python main.py \
33 | --data_path "../data/" \
34 | --dataset $DATA \
35 | --model_name_or_path t5-base \
36 | --output_dir $OUT_DIR \
37 | --num_train_epochs 20 \
38 | --save_top_k 0 \
39 | --task $TASK \
40 | --top_k $K \
41 | --ctrl_token $CTRL_TOKEN \
42 | --multi_path \
43 | --num_path $INFER_PATH \
44 | --seed $SEED \
45 | --train_batch_size 16 \
46 | --gradient_accumulation_steps 1 \
47 | --learning_rate 1e-4 \
48 | --lowercase \
49 | --sort_label \
50 | --data_ratio $DATA_RATIO \
51 | --check_val_every_n_epoch 10 \
52 | --agg_strategy vote \
53 | --eval_batch_size 64 \
54 | --constrained_decode \
55 | --do_train \
56 | | tee ${OUT_DIR}/train.log \
57 | 2> ${OUT_DIR}/train.err
58 | # --model_name_or_path "PATH TO THE CHECKPOINT" \ # configure the checkpoint path to eval
59 |
60 | # --load_path_cache \
61 | # --single_view_type $SVP_TYPE \
62 | # --load_ckpt_name "ckpt path" \
63 | # > $OUT_DIR/train.log 2>&1&
64 | done
65 | done
66 | done
67 | done
68 | done
69 | # done
70 |
--------------------------------------------------------------------------------
/scripts/run_unified.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | export CUDA_VISIBLE_DEVICES=0
4 |
5 | cd src
6 |
7 | for SEED in 5 10 15 20 25
8 | do
9 | K=5
10 | INFER_PATH=$K
11 | CTRL_TOKEN=post
12 | TASK=unified
13 | OUT_DIR="../outputs/$TASK/top${K}_seed${SEED}"
14 |
15 | mkdir -p $OUT_DIR
16 |
17 |
18 | python main.py \
19 | --data_path "../data/" \
20 | --dataset seed$SEED \
21 | --model_name_or_path t5-base \
22 | --output_dir $OUT_DIR \
23 | --num_train_epochs 20 \
24 | --save_top_k 0 \
25 | --task $TASK \
26 | --top_k $K \
27 | --ctrl_token $CTRL_TOKEN \
28 | --multi_path \
29 | --num_path $INFER_PATH \
30 | --seed $SEED \
31 | --train_batch_size 16 \
32 | --gradient_accumulation_steps 1 \
33 | --learning_rate 1e-4 \
34 | --lowercase \
35 | --sort_label \
36 | --data_ratio 1.0 \
37 | --check_val_every_n_epoch 10 \
38 | --agg_strategy vote \
39 | --eval_batch_size 64 \
40 | --constrained_decode \
41 | --multi_task \
42 | --do_train \
43 | > $OUT_DIR/train.log
44 | # --load_ckpt_name "best.ckpt" \
45 | # --load_path_cache \
46 | # > $OUT_DIR/train.log 2>&1&
47 | done
48 |
--------------------------------------------------------------------------------
/src/const.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | senttag2opinion = {'pos': 'great', 'neg': 'bad', 'neu': 'ok'}
4 | sentword2opinion = {'positive': 'great', 'negative': 'bad', 'neutral': 'ok'}
5 |
6 | rest_aspect_cate_list = [
7 | 'location general', 'food prices', 'food quality', 'food general',
8 | 'ambience general', 'service general', 'restaurant prices',
9 | 'drinks prices', 'restaurant miscellaneous', 'drinks quality',
10 | 'drinks style_options', 'restaurant general', 'food style_options'
11 | ]
12 |
13 | laptop_aspect_cate_list = [
14 | 'keyboard operation_performance', 'os operation_performance',
15 | 'out_of_scope operation_performance', 'ports general',
16 | 'optical_drives general', 'laptop operation_performance',
17 | 'optical_drives operation_performance', 'optical_drives usability',
18 | 'multimedia_devices general', 'keyboard general', 'os miscellaneous',
19 | 'software operation_performance', 'display operation_performance',
20 | 'shipping quality', 'hard_disc quality', 'motherboard general',
21 | 'graphics general', 'multimedia_devices connectivity', 'display general',
22 | 'memory operation_performance', 'os design_features',
23 | 'out_of_scope usability', 'software design_features',
24 | 'graphics design_features', 'ports connectivity',
25 | 'support design_features', 'display quality', 'software price',
26 | 'shipping general', 'graphics operation_performance',
27 | 'hard_disc miscellaneous', 'display design_features',
28 | 'cpu operation_performance', 'mouse general', 'keyboard portability',
29 | 'hardware price', 'support quality', 'hardware quality',
30 | 'motherboard operation_performance', 'multimedia_devices quality',
31 | 'battery design_features', 'mouse usability', 'os price',
32 | 'shipping operation_performance', 'laptop quality', 'laptop portability',
33 | 'fans&cooling general', 'battery general', 'os usability',
34 | 'hardware usability', 'optical_drives design_features',
35 | 'fans&cooling operation_performance', 'memory general', 'company general',
36 | 'power_supply general', 'hardware general', 'mouse design_features',
37 | 'software general', 'keyboard quality', 'power_supply quality',
38 | 'software quality', 'multimedia_devices usability',
39 | 'power_supply connectivity', 'multimedia_devices price',
40 | 'multimedia_devices operation_performance', 'ports design_features',
41 | 'hardware operation_performance', 'shipping price',
42 | 'hardware design_features', 'memory usability', 'cpu quality',
43 | 'ports quality', 'ports portability', 'motherboard quality',
44 | 'display price', 'os quality', 'graphics usability', 'cpu design_features',
45 | 'hard_disc general', 'hard_disc operation_performance', 'battery quality',
46 | 'laptop usability', 'company design_features',
47 | 'company operation_performance', 'support general', 'fans&cooling quality',
48 | 'memory design_features', 'ports usability', 'hard_disc design_features',
49 | 'power_supply design_features', 'keyboard miscellaneous',
50 | 'laptop miscellaneous', 'keyboard usability', 'cpu price',
51 | 'laptop design_features', 'keyboard price', 'warranty quality',
52 | 'display usability', 'support price', 'cpu general',
53 | 'out_of_scope design_features', 'out_of_scope general',
54 | 'software usability', 'laptop general', 'warranty general',
55 | 'company price', 'ports operation_performance',
56 | 'power_supply operation_performance', 'keyboard design_features',
57 | 'support operation_performance', 'hard_disc usability', 'os general',
58 | 'company quality', 'memory quality', 'software portability',
59 | 'fans&cooling design_features', 'multimedia_devices design_features',
60 | 'laptop connectivity', 'battery operation_performance', 'hard_disc price',
61 | 'laptop price'
62 | ]
63 |
64 | with open("force_tokens.json", 'r') as f:
65 | force_tokens = json.load(f)
66 |
67 | cate_list = {
68 | "rest14": rest_aspect_cate_list,
69 | "rest15": rest_aspect_cate_list,
70 | "rest": rest_aspect_cate_list,
71 | "rest16": rest_aspect_cate_list,
72 | "laptop": laptop_aspect_cate_list,
73 | "laptop14": laptop_aspect_cate_list
74 | }
75 |
76 | task_data_list = {
77 | "aste": ["laptop14", "rest14", "rest15", "rest16"],
78 | "tasd": ['rest15', "rest16"],
79 | "acos": ['laptop16', "rest16"],
80 | "asqp": ['rest15', "rest16"],
81 | }
82 | force_words = {
83 | 'aste': {
84 | 'rest15': list(senttag2opinion.values()) + ['[SSEP]'],
85 | 'rest16': list(senttag2opinion.values()) + ['[SSEP]'],
86 | 'rest14': list(senttag2opinion.values()) + ['[SSEP]'],
87 | 'laptop14': list(senttag2opinion.values()) + ['[SSEP]']
88 | },
89 | 'tasd': {
90 | "rest15": rest_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]'],
91 | "rest16": rest_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]']
92 | },
93 | 'acos': {
94 | "rest": rest_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]'],
95 | "laptop": laptop_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]'],
96 | },
97 | 'asqp': {
98 | "rest15": rest_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]'],
99 | "rest16": rest_aspect_cate_list + list(sentword2opinion.values()) + ['[SSEP]'],
100 | }
101 | }
102 |
103 |
104 | optim_orders_all = {
105 | "aste": {
106 | "laptop14": [
107 | '[O] [A] [S]', '[A] [O] [S]', '[O] [S] [A]',
108 | '[A] [S] [O]', '[S] [O] [A]', '[S] [A] [O]'
109 | ],
110 | "rest14": [
111 | '[O] [A] [S]', '[O] [S] [A]', '[A] [O] [S]',
112 | '[A] [S] [O]', '[S] [O] [A]', '[S] [A] [O]'
113 | ],
114 | "rest15": [
115 | '[A] [O] [S]', '[O] [A] [S]', '[O] [S] [A]',
116 | '[A] [S] [O]', '[S] [O] [A]', '[S] [A] [O]'
117 | ],
118 | "rest16": [
119 | '[O] [A] [S]', '[A] [O] [S]', '[O] [S] [A]',
120 | '[A] [S] [O]', '[S] [O] [A]', '[S] [A] [O]'
121 | ],
122 | },
123 | "tasd": {
124 | "rest15": [
125 | '[A] [C] [S]', '[A] [S] [C]', '[C] [S] [A]',
126 | '[C] [A] [S]', '[S] [C] [A]', '[S] [A] [C]'
127 | ],
128 | "rest16": [
129 | '[A] [C] [S]', '[A] [S] [C]', '[C] [S] [A]',
130 | '[C] [A] [S]', '[S] [C] [A]', '[S] [A] [C]'
131 | ]
132 | },
133 | "acos": {
134 | "laptop16": [ # ot null -> sp
135 | '[A] [O] [S] [C]', '[A] [S] [O] [C]',
136 | '[A] [O] [C] [S]', '[O] [A] [S] [C]',
137 | '[O] [A] [C] [S]', '[A] [S] [C] [O]',
138 | '[A] [C] [O] [S]', '[O] [C] [A] [S]',
139 | '[O] [S] [A] [C]', '[A] [C] [S] [O]',
140 | '[O] [C] [S] [A]', '[O] [S] [C] [A]',
141 | '[S] [A] [O] [C]', '[C] [O] [A] [S]',
142 | '[C] [S] [A] [O]', '[C] [A] [O] [S]',
143 | '[C] [S] [O] [A]', '[C] [O] [S] [A]',
144 | '[S] [O] [A] [C]', '[C] [A] [S] [O]',
145 | '[S] [O] [C] [A]', '[S] [C] [O] [A]',
146 | '[S] [A] [C] [O]', '[S] [C] [A] [O]'
147 | ],
148 | "rest16": [ # ot null -> sp
149 | '[A] [O] [S] [C]', '[A] [O] [C] [S]',
150 | '[A] [S] [O] [C]', '[O] [A] [C] [S]',
151 | '[O] [A] [S] [C]', '[O] [S] [C] [A]',
152 | '[A] [C] [O] [S]', '[O] [C] [A] [S]',
153 | '[O] [S] [A] [C]', '[A] [S] [C] [O]',
154 | '[A] [C] [S] [O]', '[O] [C] [S] [A]',
155 | '[C] [O] [A] [S]', '[C] [A] [O] [S]',
156 | '[C] [S] [O] [A]', '[C] [O] [S] [A]',
157 | '[S] [A] [O] [C]', '[C] [S] [A] [O]',
158 | '[C] [A] [S] [O]', '[S] [O] [A] [C]',
159 | '[S] [C] [O] [A]', '[S] [O] [C] [A]',
160 | '[S] [C] [A] [O]', '[S] [A] [C] [O]'
161 | ],
162 | },
163 | "asqp": {
164 | "rest15": [
165 | '[A] [O] [S] [C]', '[O] [A] [C] [S]',
166 | '[A] [O] [C] [S]', '[O] [A] [S] [C]',
167 | '[O] [S] [C] [A]', '[A] [S] [O] [C]',
168 | '[O] [C] [A] [S]', '[O] [S] [A] [C]',
169 | '[A] [C] [O] [S]', '[O] [C] [S] [A]',
170 | '[A] [C] [S] [O]', '[C] [O] [A] [S]',
171 | '[A] [S] [C] [O]', '[C] [A] [O] [S]',
172 | '[C] [S] [O] [A]', '[C] [O] [S] [A]',
173 | '[C] [S] [A] [O]', '[C] [A] [S] [O]',
174 | '[S] [A] [O] [C]', '[S] [O] [A] [C]',
175 | '[S] [C] [O] [A]', '[S] [O] [C] [A]',
176 | '[S] [C] [A] [O]', '[S] [A] [C] [O]'
177 | ],
178 | "rest16": [
179 | '[O] [A] [C] [S]', '[A] [O] [S] [C]',
180 | '[O] [A] [S] [C]', '[O] [S] [C] [A]',
181 | '[A] [O] [C] [S]', '[O] [S] [A] [C]',
182 | '[O] [C] [A] [S]', '[A] [S] [O] [C]',
183 | '[O] [C] [S] [A]', '[A] [C] [O] [S]',
184 | '[A] [C] [S] [O]', '[C] [O] [A] [S]',
185 | '[A] [S] [C] [O]', '[C] [A] [O] [S]',
186 | '[C] [O] [S] [A]', '[C] [S] [O] [A]',
187 | '[C] [S] [A] [O]', '[S] [A] [O] [C]',
188 | '[C] [A] [S] [O]', '[S] [O] [A] [C]',
189 | '[S] [O] [C] [A]', '[S] [C] [O] [A]',
190 | '[S] [C] [A] [O]', '[S] [A] [C] [O]'
191 | ],
192 | },
193 | }
194 |
195 |
196 | heuristic_orders = {
197 | 'aste': ['[A] [O] [S]'],
198 | 'tasd': ['[A] [C] [S]'],
199 | 'asqp': ['[A] [O] [C] [S]'],
200 | 'acos': ['[A] [O] [C] [S]'],
201 | }
--------------------------------------------------------------------------------
/src/data_process/process_acos.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import csv
3 |
4 | num2sent = {"0": "negative", "1": "neutral", "2": "positive"}
5 |
6 |
7 | def process(input_file, output_file):
8 | """
9 | convert the original data to unified format for MvP
10 | """
11 | wf = open(output_file, 'w')
12 | with open(input_file, "r", encoding="utf-8") as f:
13 | reader = csv.reader(f, delimiter="\t", quotechar=None)
14 | lines = []
15 | for line in reader:
16 | cur_sent = line[0]
17 | quads = line[1:]
18 | new_quads = []
19 | for quad in quads:
20 | words = cur_sent.split()
21 | a, c, s, o = quad.split()
22 | a_start, a_end = a.split(',')
23 | a_start = int(a_start)
24 | a_end = int(a_end)
25 | if a_start == -1 or a_end == -1:
26 | a = "NULL"
27 | else:
28 | a = " ".join(words[a_start:a_end])
29 | c = c.replace('#', ' ').lower()
30 | s = num2sent[s]
31 | o_start, o_end = o.split(',')
32 | o_start = int(o_start)
33 | o_end = int(o_end)
34 | if o_start == -1 or o_end == -1:
35 | o = "NULL"
36 | else:
37 | o = " ".join(words[o_start:o_end])
38 | new_quads.append([a, c, s, o])
39 | wf.writelines(cur_sent + '####')
40 | wf.writelines(str(new_quads))
41 | wf.write('\n')
42 | wf.close()
43 |
44 |
45 | if __name__ == '__process__':
46 | postfix = ['train', 'test', 'dev']
47 | for p in postfix:
48 | process(f'./acos/rest/rest16_quad_{p}.tsv', f'./acos/rest/{p}.txt')
49 |
50 | for p in postfix:
51 | process(f'./acos/laptop/laptop_quad_{p}.tsv', f'./acos/laptop/{p}.txt')
52 |
53 |
--------------------------------------------------------------------------------
/src/data_process/process_unify.py:
--------------------------------------------------------------------------------
1 | import os
2 | import random
3 | import sys
4 | sys.path.append(".")
5 |
6 | from collections import Counter
7 | from data_utils import parse_aste_tuple
8 |
9 | join = os.path.join
10 |
11 |
12 | def process(data_folder, tasks, out_dir):
13 | """
14 | 1. Aggregate all train, dev, and test sets for the tasks acos/asqp/aste/tasd.
15 | 2. Remove data contamination: delete the test set data that exists in the train/dev sets.
16 | 3. Output data.txt
17 | Data format: (task, data, words, tuples)
18 | """
19 | train_data = []
20 | test_data = []
21 | # merge all data
22 | for task in tasks:
23 | task_path = join(data_folder, task)
24 | print("task:", task_path)
25 | for data_name in os.listdir(task_path):
26 | data_path = join(task_path, data_name)
27 | print("data:", data_path)
28 | # acos data_name
29 | for split in ["train", "dev", "test"]:
30 | with open(join(data_path, "{}.txt".format(split)),
31 | 'r',
32 | encoding="utf-8") as fp:
33 | for line in fp:
34 | line = line.strip().lower()
35 | if line != '':
36 | words, tuples = line.split('####')
37 | # parse aste
38 | if task == "aste":
39 | aste_tuples = []
40 | for _tuple in eval(tuples):
41 | parsed_tuple = parse_aste_tuple(
42 | _tuple, words.split())
43 | aste_tuples.append(parsed_tuple)
44 | tuples = str(aste_tuples)
45 |
46 | # output
47 | if split == "test":
48 | test_data.append((task, data_name, words, tuples))
49 | else:
50 | train_data.append((task, data_name, words, tuples))
51 | # remove inputs in test set
52 | test_inputs = set()
53 | for _, _, words, _ in test_data:
54 | test_inputs.add(words.replace(" ", ""))
55 | train_data_safe = []
56 | for item in train_data:
57 | if item[2].replace(" ", "") not in test_inputs:
58 | train_data_safe.append(item)
59 |
60 | print("test inputs size:", len(test_inputs))
61 | print("train data size (before remove test):", len(train_data))
62 | print("train data size (after remove test):", len(train_data_safe))
63 |
64 | # dedup
65 | random.seed(0)
66 | random.shuffle(train_data_safe)
67 | train_data_dedup = []
68 | train_pairs = set()
69 | for item in train_data_safe:
70 | pair = (item[2] + item[3]).replace(" ", "")
71 | if pair not in train_pairs:
72 | train_pairs.add(pair)
73 | train_data_dedup.append(item)
74 |
75 | print("train data size (dedup):", len(train_data_dedup))
76 |
77 | # stats
78 | task_list = []
79 | data_list = []
80 | for task, data_name, _, _ in train_data_dedup:
81 | task_list.append(task)
82 | data_list.append(data_name)
83 | print("Tasks counts:", Counter(task_list))
84 | print("Data counts:", Counter(data_list))
85 |
86 | # output
87 | for seed in [5, 10, 15, 20, 25]:
88 | os.makedirs(out_dir + "seed{}".format(seed), exist_ok=True)
89 | random.seed(seed)
90 | random.shuffle(train_data_dedup)
91 | idx = int(len(train_data_dedup) * 0.9)
92 | train_set = train_data_dedup[:idx]
93 | dev_set = train_data_dedup[idx:]
94 |
95 | # sort
96 | train_set = sorted(train_set, key=lambda x: x[2])
97 |
98 | with open(out_dir + "seed{}/train.txt".format(seed),
99 | 'w',
100 | encoding="utf-8") as fp:
101 | for item in train_set:
102 | fp.write("{}\t{}\t{}####{}\n".format(*item))
103 |
104 | with open(out_dir + "seed{}/dev.txt".format(seed),
105 | 'w',
106 | encoding="utf-8") as fp:
107 | for item in dev_set:
108 | fp.write("{}\t{}\t{}####{}\n".format(*item))
109 |
110 |
111 | if __name__ == "__main__":
112 | tasks = ["acos", "asqp", "aste", "tasd"]
113 | process("../data", tasks, "../data/unified/")
114 |
--------------------------------------------------------------------------------
/src/data_utils.py:
--------------------------------------------------------------------------------
1 | import random
2 | import json
3 | import numpy as np
4 | from itertools import permutations
5 | import torch
6 | from torch.utils.data import Dataset
7 | # from transformers import AdamW, T5Tokenizer, T5ForConditionalGeneration
8 |
9 | from t5_score import MyT5ForConditionalGenerationScore
10 | from const import *
11 |
12 |
13 | def get_element_tokens(task):
14 | dic = {
15 | "aste":
16 | ["[A]", "[O]", "[S]"],
17 | "tasd":
18 | ["[A]", "[C]", "[S]"],
19 | "aocs":
20 | ["[A]", "[O]", "[C]", "[S]"],
21 | "asqp":
22 | ["[A]", "[O]", "[C]", "[S]"],
23 | }
24 | return dic[task]
25 |
26 |
27 | def get_orders(task, data, args, sents, labels):
28 | ## uncomment to calculate orders from scratch
29 | # if torch.cuda.is_available():
30 | # device = torch.device('cuda:0')
31 | # else:
32 | # device = torch.device("cpu")
33 | # tokenizer = T5Tokenizer.from_pretrained("t5-base").to(device)
34 | # model = MyT5ForConditionalGenerationScore.from_pretrained(
35 | # "t5-base").to(device)
36 | # optim_orders_all = choose_best_order_global(sents, labels, model,
37 | # tokenizer, device,
38 | # args.task)
39 |
40 | if args.single_view_type == 'rank':
41 | orders = optim_orders_all[task][data]
42 | elif args.single_view_type == 'rand':
43 | orders = [random.Random(args.seed).choice(
44 | optim_orders_all[task][data])]
45 | elif args.single_view_type == "heuristic":
46 | orders = heuristic_orders[task]
47 | return orders
48 |
49 |
50 | def read_line_examples_from_file(data_path,
51 | task_name,
52 | data_name,
53 | lowercase,
54 | silence=True):
55 | """
56 | Read data from file, each line is: sent####labels
57 | Return List[List[word]], List[Tuple]
58 | """
59 | tasks, datas = [], []
60 | sents, labels = [], []
61 | with open(data_path, 'r', encoding='UTF-8') as fp:
62 | words, labels = [], []
63 | for line in fp:
64 | line = line.strip()
65 | if lowercase:
66 | line = line.lower()
67 | if "unified" in task_name:
68 | _task, _data, line = line.split("\t")
69 | tasks.append(_task)
70 | datas.append(_data)
71 | else:
72 | tasks.append(task_name)
73 | datas.append(data_name)
74 | if line != '':
75 | words, tuples = line.split('####')
76 | sents.append(words.split())
77 | labels.append(eval(tuples))
78 | if silence:
79 | print(f"Total examples = {len(sents)}")
80 | return tasks, datas, sents, labels
81 |
82 |
83 | def cal_entropy(inputs, preds, model_path, tokenizer, device=torch.device('cuda:0')):
84 | all_entropy = []
85 | model = MyT5ForConditionalGenerationScore.from_pretrained(model_path).to(
86 | device)
87 | batch_size = 8
88 | _inputs = [' '.join(s) for s in inputs]
89 | _preds = [' '.join(s) for s in preds]
90 | for id in range(0, len(inputs), batch_size):
91 | in_batch = _inputs[id: min(id + batch_size, len(inputs))]
92 | pred_batch = _preds[id: min(id + batch_size, len(inputs))]
93 | assert len(in_batch) == len(pred_batch)
94 | tokenized_input = tokenizer.batch_encode_plus(in_batch,
95 | max_length=200,
96 | padding="max_length",
97 | truncation=True,
98 | return_tensors="pt")
99 | tokenized_target = tokenizer.batch_encode_plus(pred_batch,
100 | max_length=200,
101 | padding="max_length",
102 | truncation=True,
103 | return_tensors="pt")
104 |
105 | target_ids = tokenized_target["input_ids"].to(device)
106 |
107 | target_ids[target_ids[:, :] == tokenizer.pad_token_id] = -100
108 | outputs = model(
109 | input_ids=tokenized_input["input_ids"].to(device),
110 | attention_mask=tokenized_input["attention_mask"].to(device),
111 | labels=target_ids,
112 | decoder_attention_mask=tokenized_target["attention_mask"].to(device))
113 |
114 | loss, entropy = outputs[0]
115 | all_entropy.extend(entropy)
116 | return all_entropy
117 |
118 |
119 | def order_scores_function(quad_list, cur_sent, model, tokenizer, device, task):
120 | q = get_element_tokens(task)
121 |
122 | all_orders = permutations(q)
123 | all_orders_list = []
124 |
125 | all_targets = []
126 | all_inputs = []
127 | cur_sent = " ".join(cur_sent)
128 | for each_order in all_orders:
129 | cur_order = " ".join(each_order)
130 | all_orders_list.append(cur_order)
131 | cur_target = []
132 | for each_q in quad_list:
133 | cur_target.append(each_q[cur_order][0])
134 |
135 | all_inputs.append(cur_sent)
136 | all_targets.append(" ".join(cur_target))
137 |
138 | tokenized_input = tokenizer.batch_encode_plus(all_inputs,
139 | max_length=200,
140 | padding="max_length",
141 | truncation=True,
142 | return_tensors="pt")
143 | tokenized_target = tokenizer.batch_encode_plus(all_targets,
144 | max_length=200,
145 | padding="max_length",
146 | truncation=True,
147 | return_tensors="pt")
148 |
149 | target_ids = tokenized_target["input_ids"].to(device)
150 |
151 | target_ids[target_ids[:, :] == tokenizer.pad_token_id] = -100
152 | outputs = model(
153 | input_ids=tokenized_input["input_ids"].to(device),
154 | attention_mask=tokenized_input["attention_mask"].to(device),
155 | labels=target_ids,
156 | decoder_attention_mask=tokenized_target["attention_mask"].to(device))
157 |
158 | loss, entropy = outputs[0]
159 | results = {}
160 | for i, _ in enumerate(all_orders_list):
161 | cur_order = all_orders_list[i]
162 | results[cur_order] = {"loss": loss[i], "entropy": entropy[i]}
163 | # print(best_quad)
164 | return results
165 |
166 |
167 | def choose_best_order_global(sents, labels, model, tokenizer, device, task):
168 | q = get_element_tokens(task)
169 | all_orders = permutations(q)
170 | all_orders_list = []
171 | scores = []
172 |
173 | for each_order in all_orders:
174 | cur_order = " ".join(each_order)
175 | all_orders_list.append(cur_order)
176 | scores.append(0)
177 |
178 | for i in range(len(sents)):
179 | label = labels[i]
180 | sent = sents[i]
181 |
182 | quad_list = []
183 | for _tuple in label:
184 | # parse ASTE tuple
185 | if task == "aste":
186 | _tuple = parse_aste_tuple(_tuple, sent)
187 |
188 | at, ac, sp, ot = get_task_tuple(_tuple, task)
189 |
190 | element_dict = {"[A]": at, "[O]": ot, "[C]": ac, "[S]": sp}
191 | element_list = []
192 | for key in q:
193 | element_list.append("{} {}".format(key, element_dict[key]))
194 |
195 | x = permutations(element_list)
196 |
197 | permute_object = {}
198 | for each in x:
199 | order = []
200 | content = []
201 | for e in each:
202 | order.append(e[0:4])
203 | content.append(e[4:])
204 | order_name = " ".join(order)
205 | content = " ".join(content)
206 | permute_object[order_name] = [content, " ".join(each)]
207 |
208 | quad_list.append(permute_object)
209 |
210 | order_scores = order_scores_function(quad_list, sent, model, tokenizer,
211 | device, task)
212 | for e in order_scores:
213 | index = all_orders_list.index(e)
214 | scores[index] += order_scores[e]['entropy']
215 |
216 | indexes = np.argsort(np.array(scores)) # [::-1]
217 | returned_orders = []
218 | for i in indexes:
219 | returned_orders.append(all_orders_list[i])
220 |
221 | print("Orders:", returned_orders)
222 | return returned_orders
223 |
224 |
225 | def parse_aste_tuple(_tuple, sent):
226 | if isinstance(_tuple[0], str):
227 | res = _tuple
228 | elif isinstance(_tuple[0], list):
229 | # parse at
230 | start_idx = _tuple[0][0]
231 | end_idx = _tuple[0][-1] if len(_tuple[0]) > 1 else start_idx
232 | at = ' '.join(sent[start_idx:end_idx + 1])
233 |
234 | # parse ot
235 | start_idx = _tuple[1][0]
236 | end_idx = _tuple[1][-1] if len(_tuple[1]) > 1 else start_idx
237 | ot = ' '.join(sent[start_idx:end_idx + 1])
238 | res = [at, ot, _tuple[2]]
239 | else:
240 | print(_tuple)
241 | raise NotImplementedError
242 | return res
243 |
244 |
245 | def get_task_tuple(_tuple, task):
246 | if task == "aste":
247 | at, ot, sp = _tuple
248 | ac = None
249 | elif task == "tasd":
250 | at, ac, sp = _tuple
251 | ot = None
252 | elif task in ["asqp", "acos"]:
253 | at, ac, sp, ot = _tuple
254 | else:
255 | raise NotImplementedError
256 |
257 | if sp:
258 | sp = sentword2opinion[sp.lower()] if sp in sentword2opinion \
259 | else senttag2opinion[sp.lower()] # 'POS' -> 'good'
260 | if at and at.lower() == 'null': # for implicit aspect term
261 | at = 'it'
262 |
263 | return at, ac, sp, ot
264 |
265 |
266 | def add_prompt(sent, orders, task, data_name, args):
267 | if args.multi_task:
268 | # add task and data prefix
269 | sent = [task, ":", data_name, ":"] + sent
270 |
271 | # add ctrl_token
272 | if args.ctrl_token == "none":
273 | pass
274 | elif args.ctrl_token == "post":
275 | sent = sent + orders
276 | elif args.ctrl_token == "pre":
277 | sent = orders + sent
278 | else:
279 | raise NotImplementedError
280 | return sent
281 |
282 |
283 | def get_para_targets(sents, labels, data_name, data_type, top_k, task, args):
284 | """
285 | Obtain the target sentence under the paraphrase paradigm
286 | """
287 | targets = []
288 | new_sents = []
289 | if task in ['aste', 'tasd']:
290 | # at most 5 orders for triple tasks
291 | top_k = min(5, top_k)
292 |
293 | optim_orders = get_orders(task, data_name, args, sents, labels)[:top_k]
294 |
295 | for i in range(len(sents)):
296 | label = labels[i]
297 | cur_sent = sents[i]
298 | cur_sent_str = " ".join(cur_sent)
299 |
300 | # ASTE: parse at & ot
301 | if task == 'aste':
302 | assert len(label[0]) == 3
303 | parsed_label = []
304 | for _tuple in label:
305 | parsed_tuple = parse_aste_tuple(_tuple, sents[i])
306 | parsed_label.append(parsed_tuple)
307 | label = parsed_label
308 |
309 | # sort label by order of appearance
310 | # at, ac, sp, ot
311 | if args.sort_label and len(label) > 1:
312 | label_pos = {}
313 | for _tuple in label:
314 | at, ac, sp, ot = get_task_tuple(_tuple, task)
315 |
316 | # get last at / ot position
317 | at_pos = cur_sent_str.find(at) if at else -1
318 | ot_pos = cur_sent_str.find(ot) if ot else -1
319 | last_pos = max(at_pos, ot_pos)
320 | last_pos = 1e4 if last_pos < 0 else last_pos
321 | label_pos[tuple(_tuple)] = last_pos
322 | new_label = [
323 | list(k)
324 | for k, _ in sorted(label_pos.items(), key=lambda x: x[1])
325 | ]
326 | label = new_label
327 |
328 | quad_list = []
329 | for _tuple in label:
330 | at, ac, sp, ot = get_task_tuple(_tuple, task)
331 | element_dict = {"[A]": at, "[O]": ot, "[C]": ac, "[S]": sp}
332 | token_end = 3
333 |
334 | element_list = []
335 | for key in optim_orders[0].split(" "):
336 | element_list.append("{} {}".format(key, element_dict[key]))
337 |
338 | x = permutations(element_list)
339 | permute_object = {}
340 | for each in x:
341 | order = []
342 | content = []
343 | for e in each:
344 | order.append(e[0:token_end])
345 | content.append(e[token_end:])
346 | order_name = " ".join(order)
347 | content = " ".join(content)
348 | permute_object[order_name] = [content, " ".join(each)]
349 |
350 | quad_list.append(permute_object)
351 |
352 | for o in optim_orders:
353 | tar = []
354 | for each_q in quad_list:
355 | tar.append(each_q[o][1])
356 |
357 | targets.append(" [SSEP] ".join(tar))
358 | # add prompt
359 | new_sent = add_prompt(cur_sent, o.split(), task, data_name, args)
360 | new_sents.append(new_sent)
361 |
362 | return new_sents, targets
363 |
364 |
365 | def get_para_targets_dev(sents, labels, data_name, task, args):
366 | """
367 | Obtain the target sentence under the paraphrase paradigm
368 | """
369 | new_sents = []
370 | targets = []
371 | optim_orders = get_orders(task, data_name, args, sents=None, labels=None)
372 | top_order = optim_orders[0].split(" ")
373 | for sent, label in zip(sents, labels):
374 | all_quad_sentences = []
375 | for _tuple in label:
376 | # parse ASTE tuple
377 | if task == "aste":
378 | _tuple = parse_aste_tuple(_tuple, sent)
379 |
380 | at, ac, sp, ot = get_task_tuple(_tuple, task)
381 |
382 | element_dict = {"[A]": at, "[O]": ot, "[C]": ac, "[S]": sp}
383 | element_list = []
384 | for key in top_order:
385 | element_list.append("{} {}".format(key, element_dict[key]))
386 |
387 | one_quad_sentence = " ".join(element_list)
388 | all_quad_sentences.append(one_quad_sentence)
389 |
390 | target = ' [SSEP] '.join(all_quad_sentences)
391 | targets.append(target)
392 |
393 | # add prompt
394 | sent = add_prompt(sent, top_order, task, data_name, args)
395 |
396 | new_sents.append(sent)
397 | return new_sents, targets
398 |
399 |
400 | def get_transformed_io(data_path, data_name, data_type, top_k, args):
401 | """
402 | The main function to transform input & target according to the task
403 | """
404 | tasks, datas, sents, labels = read_line_examples_from_file(
405 | data_path, args.task, args.dataset, args.lowercase)
406 |
407 | # the input is just the raw sentence
408 | inputs = [s.copy() for s in sents]
409 |
410 | # low resource
411 | if data_type == 'train' and args.data_ratio != 1.0:
412 | num_sample = int(len(inputs) * args.data_ratio)
413 | sample_indices = random.sample(list(range(0, len(inputs))), num_sample)
414 | sample_inputs = [inputs[i] for i in sample_indices]
415 | sample_labels = [labels[i] for i in sample_indices]
416 | inputs, labels = sample_inputs, sample_labels
417 | print(
418 | f"Low resource: {args.data_ratio}, total train examples = {num_sample}")
419 | if num_sample <= 20:
420 | print("Labels:", sample_labels)
421 |
422 | if data_type == "train" or args.eval_data_split == "dev" or data_type == "test":
423 | new_inputs, targets = get_para_targets(inputs, labels, data_name,
424 | data_type, top_k, args.task,
425 | args)
426 | else:
427 | new_inputs, targets = get_para_targets_dev(inputs, labels, data_name,
428 | args.task, args)
429 |
430 | print(len(inputs), len(new_inputs), len(targets))
431 | return new_inputs, targets
432 |
433 |
434 | def get_transformed_io_unified(data_path, task_name, data_name, data_type,
435 | top_k, args):
436 | """
437 | The main function to transform input & target according to the task
438 | """
439 | tasks, datas, sents, labels = read_line_examples_from_file(
440 | data_path, task_name, data_name, lowercase=args.lowercase)
441 | sents = [s.copy() for s in sents]
442 | new_inputs, targets = [], []
443 | for task, data, sent, label in zip(tasks, datas, sents, labels):
444 | if data_type == "train" or (data_type == "test" and args.multi_path):
445 | new_input, target = get_para_targets([sent], [label], data,
446 | data_type, top_k, task, args)
447 | else:
448 | new_input, target = get_para_targets_dev([sent], [label], data,
449 | task, args)
450 | new_inputs.extend(new_input)
451 | targets.extend(target)
452 |
453 | print("Ori sent size:", len(sents))
454 | print("Input size:", len(new_inputs), len(targets))
455 | print("Examples:")
456 | print(new_inputs[:10])
457 | print(targets[:10])
458 |
459 | return new_inputs, targets
460 |
461 |
462 | class ABSADataset(Dataset):
463 |
464 | def __init__(self,
465 | tokenizer,
466 | task_name,
467 | data_name,
468 | data_type,
469 | top_k,
470 | args,
471 | max_len=128):
472 | self.data_path = f'{args.data_path}/{task_name}/{data_name}/{data_type}.txt'
473 | self.max_len = max_len
474 | self.tokenizer = tokenizer
475 | self.task_name = task_name
476 | self.data_name = data_name
477 | self.data_type = data_type
478 | self.args = args
479 |
480 | self.top_k = top_k
481 |
482 | self.inputs = []
483 | self.targets = []
484 |
485 | self._build_examples()
486 |
487 | def __len__(self):
488 | return len(self.inputs)
489 |
490 | def __getitem__(self, index):
491 | source_ids = self.inputs[index]["input_ids"].squeeze()
492 | target_ids = self.targets[index]["input_ids"].squeeze()
493 |
494 | src_mask = self.inputs[index]["attention_mask"].squeeze(
495 | ) # might need to squeeze
496 | target_mask = self.targets[index]["attention_mask"].squeeze(
497 | ) # might need to squeeze
498 | return {
499 | "source_ids": source_ids,
500 | "source_mask": src_mask,
501 | "target_ids": target_ids,
502 | "target_mask": target_mask
503 | }
504 |
505 | def _build_examples(self):
506 |
507 | if self.args.multi_task:
508 | inputs, targets = get_transformed_io_unified(
509 | self.data_path, self.task_name, self.data_name, self.data_type,
510 | self.top_k, self.args)
511 | else:
512 | inputs, targets = get_transformed_io(self.data_path,
513 | self.data_name,
514 | self.data_type, self.top_k,
515 | self.args)
516 |
517 | for i in range(len(inputs)):
518 | # change input and target to two strings
519 | input = ' '.join(inputs[i])
520 | target = targets[i]
521 |
522 | tokenized_input = self.tokenizer.batch_encode_plus(
523 | [input],
524 | max_length=self.max_len,
525 | padding="max_length",
526 | truncation=True,
527 | return_tensors="pt")
528 |
529 | # for ACOS Restaurant and Laptop dataset
530 | # the max target length is much longer than 200
531 | # we need to set a larger max length for inference
532 | target_max_length = 1024 if self.data_type == "test" else self.max_len
533 |
534 | tokenized_target = self.tokenizer.batch_encode_plus(
535 | [target],
536 | max_length=target_max_length,
537 | padding="max_length",
538 | truncation=True,
539 | return_tensors="pt")
540 |
541 | self.inputs.append(tokenized_input)
542 | self.targets.append(tokenized_target)
543 |
--------------------------------------------------------------------------------
/src/eval_utils.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | import numpy as np
4 |
5 |
6 | def extract_spans_para(seq, seq_type):
7 | quads = []
8 | sents = [s.strip() for s in seq.split('[SSEP]')]
9 | for s in sents:
10 | try:
11 | tok_list = ["[C]", "[S]", "[A]", "[O]"]
12 |
13 | for tok in tok_list:
14 | if tok not in s:
15 | s += " {} null".format(tok)
16 | index_ac = s.index("[C]")
17 | index_sp = s.index("[S]")
18 | index_at = s.index("[A]")
19 | index_ot = s.index("[O]")
20 |
21 | combined_list = [index_ac, index_sp, index_at, index_ot]
22 | arg_index_list = list(np.argsort(combined_list))
23 |
24 | result = []
25 | for i in range(len(combined_list)):
26 | start = combined_list[i] + 4
27 | sort_index = arg_index_list.index(i)
28 | if sort_index < 3:
29 | next_ = arg_index_list[sort_index + 1]
30 | re = s[start:combined_list[next_]]
31 | else:
32 | re = s[start:]
33 | result.append(re.strip())
34 |
35 | ac, sp, at, ot = result
36 |
37 | # if the aspect term is implicit
38 | if at.lower() == 'it':
39 | at = 'null'
40 | except ValueError:
41 | try:
42 | print(f'In {seq_type} seq, cannot decode: {s}')
43 | pass
44 | except UnicodeEncodeError:
45 | print(f'In {seq_type} seq, a string cannot be decoded')
46 | pass
47 | ac, at, sp, ot = '', '', '', ''
48 |
49 | quads.append((ac, at, sp, ot))
50 |
51 | return quads
52 |
53 |
54 | def compute_f1_scores(pred_pt, gold_pt, verbose=True):
55 | """
56 | Function to compute F1 scores with pred and gold quads
57 | The input needs to be already processed
58 | """
59 | # number of true postive, gold standard, predictions
60 | n_tp, n_gold, n_pred = 0, 0, 0
61 |
62 | for i in range(len(pred_pt)):
63 | n_gold += len(gold_pt[i])
64 | n_pred += len(pred_pt[i])
65 |
66 | for t in pred_pt[i]:
67 | if t in gold_pt[i]:
68 | n_tp += 1
69 |
70 | if verbose:
71 | print(
72 | f"number of gold spans: {n_gold}, predicted spans: {n_pred}, hit: {n_tp}"
73 | )
74 |
75 | precision = float(n_tp) / float(n_pred) if n_pred != 0 else 0
76 | recall = float(n_tp) / float(n_gold) if n_gold != 0 else 0
77 | f1 = 2 * precision * recall / (
78 | precision + recall) if precision != 0 or recall != 0 else 0
79 | scores = {
80 | 'precision': precision * 100,
81 | 'recall': recall * 100,
82 | 'f1': f1 * 100
83 | }
84 |
85 | return scores
86 |
87 |
88 | def compute_scores(pred_seqs, gold_seqs, verbose=True):
89 | """
90 | Compute model performance
91 | """
92 | assert len(pred_seqs) == len(gold_seqs), (len(pred_seqs), len(gold_seqs))
93 | num_samples = len(gold_seqs)
94 |
95 | all_labels, all_preds = [], []
96 |
97 | for i in range(num_samples):
98 | gold_list = extract_spans_para(gold_seqs[i], 'gold')
99 | pred_list = extract_spans_para(pred_seqs[i], 'pred')
100 | if verbose and i < 10:
101 |
102 | print("gold ", gold_seqs[i])
103 | print("pred ", pred_seqs[i])
104 | print()
105 |
106 | all_labels.append(gold_list)
107 | all_preds.append(pred_list)
108 |
109 | scores = compute_f1_scores(all_preds, all_labels)
110 |
111 | return scores, all_labels, all_preds
112 |
--------------------------------------------------------------------------------
/src/llms/api.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import requests
4 | import openai
5 |
6 |
7 | openai.api_key = os.environ["OPENAI_API_KEY"]
8 |
9 | def llm_completion(prompt, stop=None):
10 | response = openai.Completion.create(
11 | model="text-davinci-003",
12 | prompt=prompt,
13 | temperature=0,
14 | max_tokens=200,
15 | top_p=1,
16 | frequency_penalty=0.0,
17 | presence_penalty=0.0,
18 | logprobs=None,
19 | stop=stop
20 | )
21 | print(response)
22 | return response["choices"][0]["text"]
23 |
24 | def llm_chat(prompt, stop=None):
25 | response = openai.ChatCompletion.create(
26 | model="gpt-3.5-turbo",
27 | messages=[
28 | {"role": "user", "content": prompt}
29 | ],
30 | temperature=0,
31 | max_tokens=200,
32 | stop="\n\n"
33 | )
34 |
35 | result = ''
36 | for choice in response.choices:
37 | result += choice.message.content
38 | return result
39 |
40 |
41 | if __name__ == "__main__":
42 | prompt = "Q: American Callan Pinckney’s eponymously named system became a best-selling (1980s-2000s) book/video franchise in what genre?\nA:"
43 |
44 | print(llm_chat(prompt, stop=["\n"]))
45 |
--------------------------------------------------------------------------------
/src/llms/eval.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import json
3 | import ast
4 | sys.path.append(".")
5 |
6 | from eval_utils import compute_f1_scores
7 |
8 | def eval_log(file_path):
9 | """
10 | read the LLMs log file and compute the F1 scores
11 | """
12 | all_labels, all_preds = [], []
13 |
14 | with open(file_path, 'r', encoding='utf-8') as fp:
15 | for line in fp:
16 | if line.startswith("Sentiment Elements:"):
17 | line = line.split("Sentiment Elements: ")[1].strip()
18 | try:
19 | pred_list = ast.literal_eval(line)
20 | except:
21 | # print(">>>", line)
22 | pred_list = []
23 | elif line.startswith("Gold:"):
24 | line = line.split("Gold:")[1].strip()
25 | gold_list = ast.literal_eval(line)
26 | all_labels.append(gold_list)
27 | all_preds.append(pred_list)
28 |
29 | scores = compute_f1_scores(all_preds, all_labels)
30 | print("Count:", len(all_preds))
31 | print(scores)
32 |
33 |
34 | if __name__ == "__main__":
35 | log_files = [
36 | "llms/results/chatgpt_test_200_acos_rest16_0shot.log",
37 | "llms/results/chatgpt_test_200_acos_rest16_10shot.log",
38 | "llms/results/chatgpt_test_200_asqp_rest15_0shot.log",
39 | "llms/results/chatgpt_test_200_asqp_rest15_10shot.log",
40 | "llms/results/chatgpt_test_200_aste_laptop14_0shot.log",
41 | "llms/results/chatgpt_test_200_aste_laptop14_10shot.log",
42 | "llms/results/chatgpt_test_200_tasd_rest16_0shot.log",
43 | "llms/results/chatgpt_test_200_tasd_rest16_10shot.log"
44 | ]
45 |
46 | for log_file in log_files:
47 | print(log_file)
48 | eval_log(log_file)
49 | print()
50 |
--------------------------------------------------------------------------------
/src/llms/infer.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import argparse
3 | import time
4 | import random
5 |
6 | sys.path.append(".")
7 | from data_utils import get_transformed_io
8 | from eval_utils import extract_spans_para
9 | from main import init_args, set_seed
10 | from llms.api import llm_chat
11 |
12 |
13 | opinion2sentword = {'great': 'positive', 'bad': 'negative', 'ok': 'neutral'}
14 |
15 | def load_prompt(task, data, prompt_type):
16 | prompt_path = f"llms/prompts/{task}_{data}_{prompt_type}.txt"
17 | with open(prompt_path, 'r', encoding='utf-8') as fp:
18 | prompt = fp.read().strip() + "\n\n"
19 | return prompt
20 |
21 |
22 | def inference(args, start_idx=0, end_idx=200):
23 | data_path = f'{args.data_path}/{args.task}/{args.dataset}/{args.data_type}.txt'
24 | sources, targets = get_transformed_io(data_path,
25 | args.dataset,
26 | args.data_type, top_k=1, args=args)
27 |
28 | # sample `num_sample` samples from sources and targets
29 | samples = random.sample(list(zip(sources, targets)), args.num_sample)
30 |
31 | prompt = load_prompt(args.task, args.dataset, args.prompt_type)
32 |
33 | for i, (source, target) in enumerate(samples):
34 | if i < start_idx or i > end_idx:
35 | continue
36 | print(i)
37 | try:
38 | source = " ".join(source)
39 | gold_list = extract_spans_para(target, 'gold')
40 | print(gold_list)
41 |
42 | if args.task in ['asqp', 'acos']:
43 | gold_list = [(at, ot, ac, opinion2sentword[sp]) for (ac, at, sp, ot) in gold_list]
44 | elif args.task == "aste":
45 | gold_list = [(at, ot, opinion2sentword[sp]) for (ac, at, sp, ot) in gold_list]
46 | elif args.task == "tasd":
47 | gold_list = [(at, ac, opinion2sentword[sp]) for (ac, at, sp, ot) in gold_list]
48 |
49 | context = f"Text: {source}\n"
50 | context += "Sentiment Elements: "
51 | res = llm_chat(prompt + context)
52 | print(context + res)
53 | print(f"Gold: {gold_list}\n")
54 | time.sleep(3)
55 | except BaseException as e: # jump wrong case
56 | print(">" * 30, "exception:", e)
57 | exit()
58 | continue
59 |
60 |
61 | if __name__ == "__main__":
62 | args = init_args()
63 | set_seed(args.seed)
64 |
65 | # default parameters
66 | args.data_type = "test"
67 | args.num_sample = 200
68 | args.prompt_type = "0shot"
69 |
70 | ## tasks:
71 | # args.task = "acos"
72 | # args.dataset = "rest16"
73 |
74 | args.task = "asqp"
75 | args.dataset = "rest15"
76 |
77 | # args.task = "aste"
78 | # args.dataset = "laptop14"
79 |
80 | # args.task = "tasd"
81 | # args.dataset = "rest16"
82 |
83 | inference(args, start_idx=0, end_idx=200)
84 |
--------------------------------------------------------------------------------
/src/llms/prompts/acos_rest16_0shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service, the aspect term might be 'null' for implicit opinion.
5 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
6 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
7 |
8 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'aspect category', 'sentiment polarity'), ...]:
--------------------------------------------------------------------------------
/src/llms/prompts/acos_rest16_10shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service, the aspect term might be 'null' for implicit opinion.
5 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
6 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
7 |
8 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'aspect category', 'sentiment polarity'), ...]:
9 |
10 | Text: but that is highly forgivable .
11 | Sentiment Elements: [('null', 'forgivable', 'restaurant miscellaneous', 'great')]
12 |
13 | Text: i have to say that i am pleasantly suprised and i will most likely stop in again if i am in the neighborhood .
14 | Sentiment Elements: [('null', 'pleasantly suprised', 'restaurant general', 'great')]
15 |
16 | Text: the signs , the specials menus , food , and even all the waitstaff are all totally japanese .
17 | Sentiment Elements: [('signs', 'japanese', 'restaurant miscellaneous', 'great'), ('specials menus', 'japanese', 'food style_options', 'great'), ('food', 'japanese', 'food quality', 'great'), ('waitstaff', 'japanese', 'service general', 'great')]
18 |
19 | Text: i like cafe noir dont get me wrong , it is jsut that the people who work there are evil and incompetent ! !
20 | Sentiment Elements: [('cafe noir', 'like', 'restaurant general', 'great'), ('people', 'evil', 'service general', 'bad'), ('people', 'incompetent', 'service general', 'bad')]
21 |
22 | Text: the waiter was attentive , the food was delicious and the views of the city were great .
23 | Sentiment Elements: [('waiter', 'attentive', 'service general', 'great'), ('food', 'delicious', 'food quality', 'great'), ('views of the city', 'great', 'location general', 'great')]
24 |
25 | Text: i love it .
26 | Sentiment Elements: [('null', 'love', 'restaurant general', 'great')]
27 |
28 | Text: a cool bar with great food , and tons of excellent beer .
29 | Sentiment Elements: [('bar', 'cool', 'ambience general', 'great'), ('food', 'great', 'food quality', 'great'), ('beer', 'excellent', 'drinks quality', 'great'), ('beer', 'excellent', 'drinks style_options', 'great')]
30 |
31 | Text: guacamole + shrimp appetizer was really great , we both had the filet , very good , did n ' t much like the frites that came with , but the filet was so good , neither of us cared .
32 | Sentiment Elements: [('guacamole + shrimp appetizer', 'great', 'food quality', 'great'), ('filet', 'good', 'food quality', 'great'), ('frites', 'null', 'food quality', 'bad')]
33 |
34 | Text: i have never before eaten 40 pieces of relatively good nigiri .
35 | Sentiment Elements: [('nigiri', 'good', 'food quality', 'ok')]
36 |
37 | Text: the service was attentive , yet discreet .
38 | Sentiment Elements: [('service', 'attentive', 'service general', 'great'), ('service', 'discreet', 'service general', 'great')]
--------------------------------------------------------------------------------
/src/llms/prompts/asqp_rest15_0shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service, the aspect term might be 'null' for implicit opinion.
5 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
6 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
7 |
8 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'aspect category', 'sentiment polarity'), ...]:
--------------------------------------------------------------------------------
/src/llms/prompts/asqp_rest15_10shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service, the aspect term might be 'null' for implicit opinion.
5 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
6 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
7 |
8 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'aspect category', 'sentiment polarity'), ...]:
9 |
10 | Text: never again !
11 | Sentiment Elements: [('null', 'never', 'restaurant general', 'bad')]
12 |
13 | Text: the food was mediocre at best but it was the horrible service that made me vow never to go back .
14 | Sentiment Elements: [('food', 'mediocre', 'food quality', 'bad'), ('service', 'horrible', 'service general', 'bad')]
15 |
16 | Text: we had the lobster sandwich and it was fantastic .
17 | Sentiment Elements: [('lobster sandwich', 'fantastic', 'food quality', 'great')]
18 |
19 | Text: they have it all -- great price , food , and service .
20 | Sentiment Elements: [('null', 'great', 'restaurant prices', 'great'), ('food', 'great', 'food quality', 'great'), ('service', 'great', 'service general', 'great')]
21 |
22 | Text: they even scoop it out nice ( for those on a diet ) not too much not to little .
23 | Sentiment Elements: [('null', 'nice', 'food style_options', 'great')]
24 |
25 | Text: also it 's great to have dinner in a very romantic and comfortable place , the service it 's just perfect ... they 're so frendly that we never want to live the place !
26 | Sentiment Elements: [('place', 'romantic', 'ambience general', 'great'), ('place', 'comfortable', 'ambience general', 'great'), ('service', 'perfect', 'service general', 'great')]
27 |
28 | Text: my friend from milan and myself were pleasantly surprised when we arrived and everyone spoke italian .
29 | Sentiment Elements: [('null', 'pleasantly surprised', 'restaurant miscellaneous', 'great')]
30 |
31 | Text: i had their eggs benedict for brunch , which were the worst in my entire life , i tried removing the hollondaise sauce completely that was how failed it was .
32 | Sentiment Elements: [('eggs benedict', 'worst', 'food quality', 'bad')]
33 |
34 | Text: the food is authentic italian - delicious !
35 | Sentiment Elements: [('food', 'authentic italian', 'food quality', 'great'), ('food', 'delicious', 'food quality', 'great')]
36 |
37 | Text: a little pricey but it really hits the spot on a sunday morning !
38 | Sentiment Elements: [('null', 'pricey', 'restaurant prices', 'bad'), ('null', 'hits the spot', 'restaurant general', 'great')]
--------------------------------------------------------------------------------
/src/llms/prompts/aste_laptop14_0shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service.
5 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
6 |
7 | Recognize all sentiment elements with their corresponding aspect terms, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'sentiment polarity'), ...]:
--------------------------------------------------------------------------------
/src/llms/prompts/aste_laptop14_10shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about.
4 | - The 'opinion term' refers to the sentiment or attitude expressed by a user towards a particular aspect or feature of a product or service.
5 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
6 |
7 | Recognize all sentiment elements with their corresponding aspect terms, opinion terms and sentiment polarity in the following text with the format of [('aspect term', 'opinion term', 'sentiment polarity'), ...]:
8 |
9 | Text: my computer froze on several occasion , had buttons that randomely would fall off and even had moments when the computer would refuse to turn on at all .
10 | Sentiment Elements: [('buttons', 'fall off', 'bad')]
11 |
12 | Text: everything from the design to the os is simple and to the point .
13 | Sentiment Elements: [('design', 'simple', 'great'), ('os', 'simple', 'great'), ('design', 'to the point', 'great'), ('os', 'to the point', 'great')]
14 |
15 | Text: treat yourself to a more expensive , long-lasting laptop of quality like a sony , apple , or toshiba .
16 | Sentiment Elements: [('quality', 'long-lasting', 'great')]
17 |
18 | Text: however the frozen screens kept happening .
19 | Sentiment Elements: [('screens', 'frozen', 'bad')]
20 |
21 | Text: everything is so easy to use , mac software is just so much simpler than microsoft software .
22 | Sentiment Elements: [('use', 'easy', 'great'), ('mac software', 'easy', 'great'), ('microsoft software', 'simpler than', 'bad')]
23 |
24 | Text: great os , fabulous improvements to the existing line bumping up the processor speed and adding the thunderbolt port .
25 | Sentiment Elements: [('os', 'great', 'great'), ('os', 'fabulous', 'great'), ('processor speed', 'fabulous', 'great'), ('thunderbolt port', 'adding', 'great')]
26 |
27 | Text: now when i order i did not go full scale for the webcam or full keyboard i wanted something for basics of being easy to carry when i use crutchs or wheelchair and with a backpack laptop bag .
28 | Sentiment Elements: [('carry', 'easy', 'great')]
29 |
30 | Text: also the battery is completely shot .
31 | Sentiment Elements: [('battery', 'completely shot', 'bad')]
32 |
33 | Text: the screen is bright and vivid and the keyboard is very easy to use , very important for use quick typers .
34 | Sentiment Elements: [('screen', 'bright', 'great'), ('screen', 'vivid', 'great'), ('keyboard', 'easy to use', 'great')]
35 |
36 | Text: it is so simple to use , i use it more than my desktop .
37 | Sentiment Elements: [('use', 'simple', 'great')]
--------------------------------------------------------------------------------
/src/llms/prompts/tasd_rest16_0shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
5 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
6 |
7 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, and sentiment polarity in the following text with the format of [('aspect term', 'aspect category', 'sentiment polarity'), ...]:
--------------------------------------------------------------------------------
/src/llms/prompts/tasd_rest16_10shot.txt:
--------------------------------------------------------------------------------
1 | According to the following sentiment elements definition:
2 |
3 | - The 'aspect term' refers to a specific feature, attribute, or aspect of a product or service that a user may express an opinion about, the aspect term might be 'null' for implicit aspect.
4 | - The 'aspect category' refers to the category that aspect belongs to, and the available catgories includes: 'location general', 'food prices', 'food quality', 'food general', 'ambience general', 'service general', 'restaurant prices', 'drinks prices', 'restaurant miscellaneous', 'drinks quality', 'drinks style_options', 'restaurant general' and 'food style_options'.
5 | - The 'sentiment polarity' refers to the degree of positivity, negativity or neutrality expressed in the opinion towards a particular aspect or feature of a product or service, and the available polarities inlcudes: 'positive', 'negative' and 'neutral'.
6 |
7 | Recognize all sentiment elements with their corresponding aspect terms, aspect categories, and sentiment polarity in the following text with the format of [('aspect term', 'aspect category', 'sentiment polarity'), ...]:
8 |
9 | Text: be sure not to get anything other than bagels ! . .
10 | Sentiment Elements: [('bagels', 'food quality', 'great'), ('null', 'food quality', 'bad')]
11 |
12 | Text: the service leaves much to be desired , from feeling like you are rushed the place your order , to being ignored the rest of the night .
13 | Sentiment Elements: [('service', 'service general', 'bad')]
14 |
15 | Text: have eaten at ginger house several times , and it 's always good .
16 | Sentiment Elements: [('ginger house', 'restaurant general', 'great')]
17 |
18 | Text: the pizza is overpriced and soggy .
19 | Sentiment Elements: [('pizza', 'food quality', 'bad'), ('pizza', 'food prices', 'bad')]
20 |
21 | Text: they wouldnt even let me finish my glass of wine before offering another .
22 | Sentiment Elements: [('null', 'service general', 'bad')]
23 |
24 | Text: great indian food and the service is incredible .
25 | Sentiment Elements: [('indian food', 'food quality', 'great'), ('service', 'service general', 'great')]
26 |
27 | Text: the best pad thai i 've ever had .
28 | Sentiment Elements: [('pad thai', 'food quality', 'great')]
29 |
30 | Text: you can 't go wrong with this place .
31 | Sentiment Elements: [('place', 'restaurant general', 'great')]
32 |
33 | Text: so , i switch with my boyfriend again to see if maybe i could stomach the meat and spinach again , but the spinach was so undercooked that i just could not bite through it .
34 | Sentiment Elements: [('spinach', 'food quality', 'bad')]
35 |
36 | Text: the design of the space is good .
37 | Sentiment Elements: [('space', 'ambience general', 'great')]
--------------------------------------------------------------------------------
/src/t5.py:
--------------------------------------------------------------------------------
1 | # based on: https://github.com/hmt2014/AspectQuad/blob/main/DLO/t5.py
2 | import torch.nn as nn
3 | import torch
4 | from transformers.models.t5.modeling_t5 import *
5 | from transformers.file_utils import ModelOutput
6 | from transformers.generation_utils import *
7 | from transformers.generation_beam_search import *
8 | import copy
9 |
10 | _CONFIG_FOR_DOC = "T5Config"
11 |
12 | PARALLELIZE_DOCSTRING = r"""
13 | This is an experimental feature and is a subject to change at a moment's notice.
14 | Uses a device map to distribute attention modules of the model across several devices. If no device map is given,
15 | it will evenly distribute blocks across all devices.
16 | Args:
17 | device_map (`Dict[int, list]`, optional, defaults to None):
18 | A dictionary that maps attention modules to devices. Note that the embedding module and LMHead are always
19 | automatically mapped to the first device (for esoteric reasons). That means that the first device should
20 | have fewer attention modules mapped to it than other devices. For reference, the t5 models have the
21 | following number of attention modules:
22 | - t5-small: 6
23 | - t5-base: 12
24 | - t5-large: 24
25 | - t5-3b: 24
26 | - t5-11b: 24
27 | Example:
28 | ```python
29 | # Here is an example of a device map on a machine with 4 GPUs using t5-3b, which has a total of 24 attention modules:
30 | model = T5ForConditionalGeneration.from_pretrained('t5-3b')
31 | device_map = {0: [0, 1, 2],
32 | 1: [3, 4, 5, 6, 7, 8, 9],
33 | 2: [10, 11, 12, 13, 14, 15, 16],
34 | 3: [17, 18, 19, 20, 21, 22, 23]}
35 | model.parallelize(device_map)
36 | ```
37 | """
38 | DEPARALLELIZE_DOCSTRING = r"""
39 | Moves the model to cpu from a model parallel state.
40 | Example:
41 | ```python
42 | # On a 4 GPU machine with t5-3b:
43 | model = T5ForConditionalGeneration.from_pretrained('t5-3b')
44 | device_map = {0: [0, 1, 2],
45 | 1: [3, 4, 5, 6, 7, 8, 9],
46 | 2: [10, 11, 12, 13, 14, 15, 16],
47 | 3: [17, 18, 19, 20, 21, 22, 23]}
48 | model.parallelize(device_map) # Splits the model across several devices
49 | model.deparallelize() # Put the model back on cpu and cleans memory by calling torch.cuda.empty_cache()
50 | ```
51 | """
52 |
53 | add_start_docstrings("""T5 Model with a `language modeling` head on top. """, T5_START_DOCSTRING)
54 | @add_start_docstrings("""T5 Model with a `language modeling` head on top. """, T5_START_DOCSTRING)
55 | class MyT5ForConditionalGeneration(T5PreTrainedModel):
56 | authorized_missing_keys = [r"encoder\.embed_tokens\.weight", r"decoder\.embed_tokens\.weight", r"lm_head\.weight"]
57 |
58 | def __init__(self, config):
59 | super().__init__(config)
60 | self.model_dim = config.d_model
61 |
62 | self.shared = nn.Embedding(config.vocab_size, config.d_model)
63 |
64 | encoder_config = copy.deepcopy(config)
65 | encoder_config.use_cache = False
66 | encoder_config.is_encoder_decoder = False
67 | self.encoder = T5Stack(encoder_config, self.shared)
68 |
69 | decoder_config = copy.deepcopy(config)
70 | decoder_config.is_decoder = True
71 | decoder_config.is_encoder_decoder = False
72 | decoder_config.num_layers = config.num_decoder_layers
73 | self.decoder = T5Stack(decoder_config, self.shared)
74 |
75 | self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
76 |
77 | self.init_weights()
78 |
79 | def get_input_embeddings(self):
80 | return self.shared
81 |
82 | def set_input_embeddings(self, new_embeddings):
83 | self.shared = new_embeddings
84 | self.encoder.set_input_embeddings(new_embeddings)
85 | self.decoder.set_input_embeddings(new_embeddings)
86 |
87 | def get_output_embeddings(self):
88 | return self.lm_head
89 |
90 | def get_encoder(self):
91 | return self.encoder
92 |
93 | def get_decoder(self):
94 | return self.decoder
95 |
96 | @add_start_docstrings_to_model_forward(T5_INPUTS_DOCSTRING)
97 | @replace_return_docstrings(output_type=Seq2SeqLMOutput, config_class=_CONFIG_FOR_DOC)
98 | def forward(
99 | self,
100 | input_ids=None,
101 | attention_mask=None,
102 | decoder_input_ids=None,
103 | decoder_attention_mask=None,
104 | encoder_outputs=None,
105 | past_key_values=None,
106 | head_mask=None,
107 | inputs_embeds=None,
108 | decoder_inputs_embeds=None,
109 | labels=None,
110 | use_cache=None,
111 | output_attentions=None,
112 | output_hidden_states=None,
113 | return_dict=None,
114 | **kwargs,
115 | ):
116 | r"""
117 | labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`):
118 | Labels for computing the sequence classification/regression loss. Indices should be in :obj:`[-100, 0, ...,
119 | config.vocab_size - 1]`. All labels set to ``-100`` are ignored (masked), the loss is only computed for
120 | labels in ``[0, ..., config.vocab_size]``
121 | kwargs (:obj:`Dict[str, any]`, optional, defaults to `{}`):
122 | Used to hide legacy arguments that have been deprecated.
123 |
124 | Returns:
125 |
126 | Examples::
127 |
128 | >>> from transformers import T5Tokenizer, T5ForConditionalGeneration
129 |
130 | >>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
131 | >>> model = T5ForConditionalGeneration.from_pretrained('t5-small', return_dict=True)
132 |
133 | >>> input_ids = tokenizer('The walks in park', return_tensors='pt').input_ids
134 | >>> labels = tokenizer(' cute dog the ', return_tensors='pt').input_ids
135 | >>> outputs = model(input_ids=input_ids, labels=labels)
136 | >>> loss = outputs.loss
137 | >>> logits = outputs.logits
138 |
139 | >>> input_ids = tokenizer("summarize: studies have shown that owning a dog is good for you ", return_tensors="pt").input_ids # Batch size 1
140 | >>> outputs = model.generate(input_ids)
141 | """
142 |
143 | if "lm_labels" in kwargs:
144 | warnings.warn(
145 | "The `lm_labels` argument is deprecated and will be removed in a future version, use `labels` instead.",
146 | FutureWarning,
147 | )
148 | labels = kwargs.pop("lm_labels")
149 | if "decoder_past_key_value_states" in kwargs:
150 | warnings.warn(
151 | "The `decoder_past_key_value_states` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
152 | FutureWarning,
153 | )
154 | past_key_values = kwargs.pop("decoder_past_key_value_states")
155 | if "decoder_past_key_values" in kwargs:
156 | warnings.warn(
157 | "The `decoder_past_key_values` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
158 | FutureWarning,
159 | )
160 | past_key_values = kwargs.pop("decoder_past_key_values")
161 | assert kwargs == {}, f"Unexpected keyword arguments: {list(kwargs.keys())}."
162 |
163 | use_cache = use_cache if use_cache is not None else self.config.use_cache
164 | return_dict = return_dict if return_dict is not None else self.config.use_return_dict
165 |
166 | # Encode if needed (training, first prediction pass)
167 | if encoder_outputs is None:
168 | # Convert encoder inputs in embeddings if needed
169 | encoder_outputs = self.encoder(
170 | input_ids=input_ids,
171 | attention_mask=attention_mask,
172 | inputs_embeds=inputs_embeds,
173 | head_mask=head_mask,
174 | output_attentions=output_attentions,
175 | output_hidden_states=output_hidden_states,
176 | return_dict=return_dict,
177 | )
178 | elif return_dict and not isinstance(encoder_outputs, BaseModelOutput):
179 | encoder_outputs = BaseModelOutput(
180 | last_hidden_state=encoder_outputs[0],
181 | hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
182 | attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
183 | )
184 |
185 | hidden_states = encoder_outputs[0]
186 |
187 | if labels is not None and decoder_input_ids is None and decoder_inputs_embeds is None:
188 | # get decoder inputs from shifting lm labels to the right
189 | decoder_input_ids = self._shift_right(labels)
190 |
191 | # If decoding with past key value states, only the last tokens
192 | # should be given as an input
193 | if past_key_values is not None:
194 | assert labels is None, "Decoder should not use cached key value states when training."
195 | if decoder_input_ids is not None:
196 | decoder_input_ids = decoder_input_ids[:, -1:]
197 | if decoder_inputs_embeds is not None:
198 | decoder_inputs_embeds = decoder_inputs_embeds[:, -1:]
199 |
200 | # Decode
201 | decoder_outputs = self.decoder(
202 | input_ids=decoder_input_ids,
203 | attention_mask=decoder_attention_mask,
204 | inputs_embeds=decoder_inputs_embeds,
205 | past_key_values=past_key_values,
206 | encoder_hidden_states=hidden_states,
207 | encoder_attention_mask=attention_mask,
208 | head_mask=head_mask,
209 | use_cache=use_cache,
210 | output_attentions=output_attentions,
211 | output_hidden_states=output_hidden_states,
212 | return_dict=return_dict,
213 | )
214 |
215 | sequence_output = decoder_outputs[0]
216 | # Rescale output before projecting on vocab
217 | # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586
218 | sequence_output = sequence_output * (self.model_dim ** -0.5)
219 | lm_logits = self.lm_head(sequence_output)
220 |
221 | loss = None
222 | if labels is not None:
223 | loss_fct = CrossEntropyLoss(ignore_index=-100)
224 | loss = loss_fct(lm_logits.view(-1, lm_logits.size(-1)), labels.view(-1))
225 | #lm_logits_max, lm_logits_max_index = torch.max(lm_logits, dim=-1)
226 |
227 | if not return_dict:
228 | output = (lm_logits,) + decoder_outputs[1:] + encoder_outputs
229 | return ((loss,) + output) if loss is not None else output
230 |
231 | return Seq2SeqLMOutput(
232 | loss=loss,
233 | logits=lm_logits,
234 | past_key_values=decoder_outputs.past_key_values,
235 | decoder_hidden_states=decoder_outputs.hidden_states,
236 | decoder_attentions=decoder_outputs.attentions,
237 | cross_attentions=decoder_outputs.cross_attentions,
238 | encoder_last_hidden_state=encoder_outputs.last_hidden_state,
239 | encoder_hidden_states=encoder_outputs.hidden_states,
240 | encoder_attentions=encoder_outputs.attentions,
241 | )
242 |
243 | def prepare_inputs_for_generation(
244 | self, input_ids, past=None, attention_mask=None, use_cache=None, encoder_outputs=None, **kwargs
245 | ):
246 |
247 | # cut decoder_input_ids if past is used
248 | if past is not None:
249 | input_ids = input_ids[:, -1:]
250 |
251 | return {
252 | "decoder_input_ids": input_ids,
253 | "past_key_values": past,
254 | "encoder_outputs": encoder_outputs,
255 | "attention_mask": attention_mask,
256 | "use_cache": use_cache,
257 | }
258 |
259 | def _reorder_cache(self, past, beam_idx):
260 | # if decoder past is not included in output
261 | # speedy decoding is disabled and no need to reorder
262 | if past is None:
263 | logger.warning("You might want to consider setting `use_cache=True` to speed up decoding")
264 | return past
265 |
266 | reordered_decoder_past = ()
267 | for layer_past_states in past:
268 | # get the correct batch idx from layer past batch dim
269 | # batch dim of `past` is at 2nd position
270 | reordered_layer_past_states = ()
271 | for layer_past_state in layer_past_states:
272 | # need to set correct `past` for each of the four key / value states
273 | reordered_layer_past_states = reordered_layer_past_states + (
274 | layer_past_state.index_select(0, beam_idx),
275 | )
276 |
277 | assert reordered_layer_past_states[0].shape == layer_past_states[0].shape
278 | assert len(reordered_layer_past_states) == len(layer_past_states)
279 |
280 | reordered_decoder_past = reordered_decoder_past + (reordered_layer_past_states,)
281 | return reordered_decoder_past
--------------------------------------------------------------------------------
/src/t5_score.py:
--------------------------------------------------------------------------------
1 | # based on: https://github.com/hmt2014/AspectQuad/blob/main/DLO/t5_score.py
2 | import torch.nn as nn
3 | import torch
4 | from transformers.models.t5.modeling_t5 import *
5 | from transformers.file_utils import ModelOutput
6 | from transformers.generation_utils import *
7 | from transformers.generation_beam_search import *
8 | import copy
9 |
10 | _CONFIG_FOR_DOC = "T5Config"
11 |
12 | PARALLELIZE_DOCSTRING = r"""
13 | This is an experimental feature and is a subject to change at a moment's notice.
14 | Uses a device map to distribute attention modules of the model across several devices. If no device map is given,
15 | it will evenly distribute blocks across all devices.
16 | Args:
17 | device_map (`Dict[int, list]`, optional, defaults to None):
18 | A dictionary that maps attention modules to devices. Note that the embedding module and LMHead are always
19 | automatically mapped to the first device (for esoteric reasons). That means that the first device should
20 | have fewer attention modules mapped to it than other devices. For reference, the t5 models have the
21 | following number of attention modules:
22 | - t5-small: 6
23 | - t5-base: 12
24 | - t5-large: 24
25 | - t5-3b: 24
26 | - t5-11b: 24
27 | Example:
28 | ```python
29 | # Here is an example of a device map on a machine with 4 GPUs using t5-3b, which has a total of 24 attention modules:
30 | model = T5ForConditionalGeneration.from_pretrained('t5-3b')
31 | device_map = {0: [0, 1, 2],
32 | 1: [3, 4, 5, 6, 7, 8, 9],
33 | 2: [10, 11, 12, 13, 14, 15, 16],
34 | 3: [17, 18, 19, 20, 21, 22, 23]}
35 | model.parallelize(device_map)
36 | ```
37 | """
38 | DEPARALLELIZE_DOCSTRING = r"""
39 | Moves the model to cpu from a model parallel state.
40 | Example:
41 | ```python
42 | # On a 4 GPU machine with t5-3b:
43 | model = T5ForConditionalGeneration.from_pretrained('t5-3b')
44 | device_map = {0: [0, 1, 2],
45 | 1: [3, 4, 5, 6, 7, 8, 9],
46 | 2: [10, 11, 12, 13, 14, 15, 16],
47 | 3: [17, 18, 19, 20, 21, 22, 23]}
48 | model.parallelize(device_map) # Splits the model across several devices
49 | model.deparallelize() # Put the model back on cpu and cleans memory by calling torch.cuda.empty_cache()
50 | ```
51 | """
52 |
53 | def calc_entropy(input_tensor):
54 | lsm = nn.LogSoftmax()
55 | log_probs = lsm(input_tensor)
56 | probs = torch.exp(log_probs)
57 | p_log_p = log_probs * probs
58 | entropy = -p_log_p.sum()
59 | return entropy
60 |
61 | add_start_docstrings("""T5 Model with a `language modeling` head on top. """, T5_START_DOCSTRING)
62 | @add_start_docstrings("""T5 Model with a `language modeling` head on top. """, T5_START_DOCSTRING)
63 | class MyT5ForConditionalGenerationScore(T5PreTrainedModel):
64 | authorized_missing_keys = [r"encoder\.embed_tokens\.weight", r"decoder\.embed_tokens\.weight", r"lm_head\.weight"]
65 |
66 | def __init__(self, config):
67 | super().__init__(config)
68 | self.model_dim = config.d_model
69 |
70 | self.shared = nn.Embedding(config.vocab_size, config.d_model)
71 |
72 | encoder_config = copy.deepcopy(config)
73 | encoder_config.use_cache = False
74 | encoder_config.is_encoder_decoder = False
75 | self.encoder = T5Stack(encoder_config, self.shared)
76 |
77 | decoder_config = copy.deepcopy(config)
78 | decoder_config.is_decoder = True
79 | decoder_config.is_encoder_decoder = False
80 | decoder_config.num_layers = config.num_decoder_layers
81 | self.decoder = T5Stack(decoder_config, self.shared)
82 |
83 | self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
84 |
85 | self.init_weights()
86 |
87 | def get_input_embeddings(self):
88 | return self.shared
89 |
90 | def set_input_embeddings(self, new_embeddings):
91 | self.shared = new_embeddings
92 | self.encoder.set_input_embeddings(new_embeddings)
93 | self.decoder.set_input_embeddings(new_embeddings)
94 |
95 | def get_output_embeddings(self):
96 | return self.lm_head
97 |
98 | def get_encoder(self):
99 | return self.encoder
100 |
101 | def get_decoder(self):
102 | return self.decoder
103 |
104 | @add_start_docstrings_to_model_forward(T5_INPUTS_DOCSTRING)
105 | @replace_return_docstrings(output_type=Seq2SeqLMOutput, config_class=_CONFIG_FOR_DOC)
106 | def forward(
107 | self,
108 | input_ids=None,
109 | attention_mask=None,
110 | decoder_input_ids=None,
111 | decoder_attention_mask=None,
112 | encoder_outputs=None,
113 | past_key_values=None,
114 | head_mask=None,
115 | inputs_embeds=None,
116 | decoder_inputs_embeds=None,
117 | labels=None,
118 | use_cache=None,
119 | output_attentions=None,
120 | output_hidden_states=None,
121 | return_dict=None,
122 | **kwargs,
123 | ):
124 | r"""
125 | labels (:obj:`torch.LongTensor` of shape :obj:`(batch_size,)`, `optional`):
126 | Labels for computing the sequence classification/regression loss. Indices should be in :obj:`[-100, 0, ...,
127 | config.vocab_size - 1]`. All labels set to ``-100`` are ignored (masked), the loss is only computed for
128 | labels in ``[0, ..., config.vocab_size]``
129 | kwargs (:obj:`Dict[str, any]`, optional, defaults to `{}`):
130 | Used to hide legacy arguments that have been deprecated.
131 |
132 | Returns:
133 |
134 | Examples::
135 |
136 | >>> from transformers import T5Tokenizer, T5ForConditionalGeneration
137 |
138 | >>> tokenizer = T5Tokenizer.from_pretrained('t5-small')
139 | >>> model = T5ForConditionalGeneration.from_pretrained('t5-small', return_dict=True)
140 |
141 | >>> input_ids = tokenizer('The walks in park', return_tensors='pt').input_ids
142 | >>> labels = tokenizer(' cute dog the ', return_tensors='pt').input_ids
143 | >>> outputs = model(input_ids=input_ids, labels=labels)
144 | >>> loss = outputs.loss
145 | >>> logits = outputs.logits
146 |
147 | >>> input_ids = tokenizer("summarize: studies have shown that owning a dog is good for you ", return_tensors="pt").input_ids # Batch size 1
148 | >>> outputs = model.generate(input_ids)
149 | """
150 |
151 | if "lm_labels" in kwargs:
152 | warnings.warn(
153 | "The `lm_labels` argument is deprecated and will be removed in a future version, use `labels` instead.",
154 | FutureWarning,
155 | )
156 | labels = kwargs.pop("lm_labels")
157 | if "decoder_past_key_value_states" in kwargs:
158 | warnings.warn(
159 | "The `decoder_past_key_value_states` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
160 | FutureWarning,
161 | )
162 | past_key_values = kwargs.pop("decoder_past_key_value_states")
163 | if "decoder_past_key_values" in kwargs:
164 | warnings.warn(
165 | "The `decoder_past_key_values` argument is deprecated and will be removed in a future version, use `past_key_values` instead.",
166 | FutureWarning,
167 | )
168 | past_key_values = kwargs.pop("decoder_past_key_values")
169 | assert kwargs == {}, f"Unexpected keyword arguments: {list(kwargs.keys())}."
170 |
171 | use_cache = use_cache if use_cache is not None else self.config.use_cache
172 | return_dict = return_dict if return_dict is not None else self.config.use_return_dict
173 |
174 | # Encode if needed (training, first prediction pass)
175 | if encoder_outputs is None:
176 | # Convert encoder inputs in embeddings if needed
177 | encoder_outputs = self.encoder(
178 | input_ids=input_ids,
179 | attention_mask=attention_mask,
180 | inputs_embeds=inputs_embeds,
181 | head_mask=head_mask,
182 | output_attentions=output_attentions,
183 | output_hidden_states=output_hidden_states,
184 | return_dict=return_dict,
185 | )
186 | elif return_dict and not isinstance(encoder_outputs, BaseModelOutput):
187 | encoder_outputs = BaseModelOutput(
188 | last_hidden_state=encoder_outputs[0],
189 | hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
190 | attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
191 | )
192 |
193 | hidden_states = encoder_outputs[0]
194 |
195 | if labels is not None and decoder_input_ids is None and decoder_inputs_embeds is None:
196 | # get decoder inputs from shifting lm labels to the right
197 | decoder_input_ids = self._shift_right(labels)
198 |
199 | # If decoding with past key value states, only the last tokens
200 | # should be given as an input
201 | if past_key_values is not None:
202 | assert labels is None, "Decoder should not use cached key value states when training."
203 | if decoder_input_ids is not None:
204 | decoder_input_ids = decoder_input_ids[:, -1:]
205 | if decoder_inputs_embeds is not None:
206 | decoder_inputs_embeds = decoder_inputs_embeds[:, -1:]
207 |
208 | # Decode
209 | decoder_outputs = self.decoder(
210 | input_ids=decoder_input_ids,
211 | attention_mask=decoder_attention_mask,
212 | inputs_embeds=decoder_inputs_embeds,
213 | past_key_values=past_key_values,
214 | encoder_hidden_states=hidden_states,
215 | encoder_attention_mask=attention_mask,
216 | head_mask=head_mask,
217 | use_cache=use_cache,
218 | output_attentions=output_attentions,
219 | output_hidden_states=output_hidden_states,
220 | return_dict=return_dict,
221 | )
222 |
223 | sequence_output = decoder_outputs[0]
224 | # Rescale output before projecting on vocab
225 | # See https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/transformer/transformer.py#L586
226 | sequence_output = sequence_output * (self.model_dim ** -0.5)
227 | lm_logits = self.lm_head(sequence_output)
228 |
229 | loss = None
230 | if labels is not None:
231 | loss_fct = CrossEntropyLoss(ignore_index=-100, reduction="sum")
232 | loss = []
233 | entropy = []
234 | for i in range(lm_logits.size()[0]):
235 | loss_i = loss_fct(lm_logits[i], labels[i])
236 | ent = calc_entropy(lm_logits[i, 0: decoder_attention_mask[i].sum().item()])
237 | loss.append(loss_i.item())
238 | entropy.append(ent.item())
239 | loss = [loss, entropy]
240 | # TODO(thom): Add z_loss https://github.com/tensorflow/mesh/blob/fa19d69eafc9a482aff0b59ddd96b025c0cb207d/mesh_tensorflow/layers.py#L666
241 | if not return_dict:
242 | output = (lm_logits,) + decoder_outputs[1:] + encoder_outputs
243 | return ((loss,) + output) if loss is not None else output
244 |
245 | return Seq2SeqLMOutput(
246 | loss=loss,
247 | logits=lm_logits,
248 | past_key_values=decoder_outputs.past_key_values,
249 | decoder_hidden_states=decoder_outputs.hidden_states,
250 | decoder_attentions=decoder_outputs.attentions,
251 | cross_attentions=decoder_outputs.cross_attentions,
252 | encoder_last_hidden_state=encoder_outputs.last_hidden_state,
253 | encoder_hidden_states=encoder_outputs.hidden_states,
254 | encoder_attentions=encoder_outputs.attentions,
255 | )
256 |
257 | def prepare_inputs_for_generation(
258 | self, input_ids, past=None, attention_mask=None, use_cache=None, encoder_outputs=None, **kwargs
259 | ):
260 |
261 | # cut decoder_input_ids if past is used
262 | if past is not None:
263 | input_ids = input_ids[:, -1:]
264 |
265 | return {
266 | "decoder_input_ids": input_ids,
267 | "past_key_values": past,
268 | "encoder_outputs": encoder_outputs,
269 | "attention_mask": attention_mask,
270 | "use_cache": use_cache,
271 | }
272 |
273 | def _reorder_cache(self, past, beam_idx):
274 | # if decoder past is not included in output
275 | # speedy decoding is disabled and no need to reorder
276 | if past is None:
277 | logger.warning("You might want to consider setting `use_cache=True` to speed up decoding")
278 | return past
279 |
280 | reordered_decoder_past = ()
281 | for layer_past_states in past:
282 | # get the correct batch idx from layer past batch dim
283 | # batch dim of `past` is at 2nd position
284 | reordered_layer_past_states = ()
285 | for layer_past_state in layer_past_states:
286 | # need to set correct `past` for each of the four key / value states
287 | reordered_layer_past_states = reordered_layer_past_states + (
288 | layer_past_state.index_select(0, beam_idx),
289 | )
290 |
291 | assert reordered_layer_past_states[0].shape == layer_past_states[0].shape
292 | assert len(reordered_layer_past_states) == len(layer_past_states)
293 |
294 | reordered_decoder_past = reordered_decoder_past + (reordered_layer_past_states,)
295 | return reordered_decoder_past
--------------------------------------------------------------------------------