|
|
# ការវិភាគអារម្មណ៍ជាមួយការវាយតម្លៃសណ្ឋាគារ
|
|
|
|
|
|
ឥឡូវនេះបន្ទាប់ពីអ្នកបានស្វែងយល់ពីឯកសារទិន្នន័យលម្អិតរួចហើយ គឺពេលវេលាដើម្បីចម្រោះជួរឈរនានា ហើយបន្ទាប់មកប្រើបច្ចេកទេស NLP លើឯកសារទិន្នន័យ ដើម្បីទទួលបានចំណេះដំណឹងថ្មីអំពីសណ្ឋាគារ។
|
|
|
|
|
|
## [សំណួរសម្រៀងមុនមុខវិជ្ជា](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
|
|
### ការចម្រោះនិងប្រតិបត្ដិការវិភាគអារម្មណ៍
|
|
|
|
|
|
ដូចដែលអ្នកប្រហែលជាសង្កេតបាន ឯកសារទិន្នន័យមានបញ្ហាខ្លះៗ។ ជួរឈរខ្លះពេញទៅដោយព័ត៌មានដែលមិនមានប្រយោជន៍ អ្នកខ្លះមើលទៅមិនត្រឹមត្រូវឡើយ។ ប្រសិនបើវាត្រឹមត្រូវ វាមិនច្បាស់ថាតើយ៉ាងដូចម្តេចដែលវាត្រូវបានគណនាឡើង ហើយចម្លើយមិនអាចបញ្ជាក់ដោយការគណនារបស់អ្នកបានឡើយ។
|
|
|
|
|
|
## ការអនុវត្ត៖ ដំណើរការទិន្នន័យបន្ថែមបន្តិចទៀត
|
|
|
|
|
|
សម្អាតទិន្នន័យបន្តិចទៀត។ បន្ថែមជួរឈរដែលមានប្រយោជន៍ក្រោយនេះ ប្ដូរតម្លៃនៅជួរឈរផ្សេងៗ និងបោះបង់ជួរឈរតិចៗទាំងមូល។
|
|
|
|
|
|
1. ការដំណើរការជួរឈរកដំបូង
|
|
|
|
|
|
1. បោះបង់ `lat` និង `lng`
|
|
|
|
|
|
2. ផ្លាស់ប្តូរតម្លៃ `Hotel_Address` ជាមួយតម្លៃតទៅនេះ (បើអាសយដ្ឋានមានឈ្មោះទីក្រុង និងប្រទេសដូចគ្នា សូមផ្លាស់ប្ដូរឲ្យជាតែទីក្រុង និងប្រទេសប៉ុណ្ណោះ)។
|
|
|
|
|
|
នេះជាទីក្រុង និងប្រទេសតែមួយៗក្នុងឯកសារទិន្នន័យ៖
|
|
|
|
|
|
Amsterdam, Netherlands
|
|
|
|
|
|
Barcelona, Spain
|
|
|
|
|
|
London, United Kingdom
|
|
|
|
|
|
Milan, Italy
|
|
|
|
|
|
Paris, France
|
|
|
|
|
|
Vienna, Austria
|
|
|
|
|
|
```python
|
|
|
def replace_address(row):
|
|
|
if "Netherlands" in row["Hotel_Address"]:
|
|
|
return "Amsterdam, Netherlands"
|
|
|
elif "Barcelona" in row["Hotel_Address"]:
|
|
|
return "Barcelona, Spain"
|
|
|
elif "United Kingdom" in row["Hotel_Address"]:
|
|
|
return "London, United Kingdom"
|
|
|
elif "Milan" in row["Hotel_Address"]:
|
|
|
return "Milan, Italy"
|
|
|
elif "France" in row["Hotel_Address"]:
|
|
|
return "Paris, France"
|
|
|
elif "Vienna" in row["Hotel_Address"]:
|
|
|
return "Vienna, Austria"
|
|
|
|
|
|
# ជំនួសអាសយដ្ឋានទាំងអស់ជាមួយទម្រង់ខ្លីដែលមានប្រយោជន៍ច្រើនជាងមុន
|
|
|
df["Hotel_Address"] = df.apply(replace_address, axis = 1)
|
|
|
# បរិមាណនៃ value_counts() គួរត្រូវបានបូកសរុបទៅនឹងចំនួនសរុបនៃការវាយតម្លៃ
|
|
|
print(df["Hotel_Address"].value_counts())
|
|
|
```
|
|
|
|
|
|
ឥឡូវអ្នកអាចសំណួរទិន្នន័យកម្រិតប្រទេសបាន៖
|
|
|
|
|
|
```python
|
|
|
display(df.groupby("Hotel_Address").agg({"Hotel_Name": "nunique"}))
|
|
|
```
|
|
|
|
|
|
| Hotel_Address | Hotel_Name |
|
|
|
| :--------------------- | :--------: |
|
|
|
| Amsterdam, Netherlands | 105 |
|
|
|
| Barcelona, Spain | 211 |
|
|
|
| London, United Kingdom | 400 |
|
|
|
| Milan, Italy | 162 |
|
|
|
| Paris, France | 458 |
|
|
|
| Vienna, Austria | 158 |
|
|
|
|
|
|
2. ដំណើរការជួរឈរសង្ខេបមតិយោបល់សណ្ឋាគារ
|
|
|
|
|
|
1. បោះបង់ `Additional_Number_of_Scoring`
|
|
|
|
|
|
1. ផ្លាស់ប្តូរ `Total_Number_of_Reviews` ជាចំនួនសរុបនៃការវាយតម្លៃសម្រាប់សណ្ឋាគានោះដែលមាននៅក្នុងឯកសារទិន្នន័យបច្ចុប្បន្ន
|
|
|
|
|
|
1. ផ្លាស់ប្តូរ `Average_Score` ជាពិន្ទុខ្លួនឯងដែលគណនាឡើង
|
|
|
|
|
|
```python
|
|
|
# ដក `Additional_Number_of_Scoring` ចេញ
|
|
|
df.drop(["Additional_Number_of_Scoring"], axis = 1, inplace=True)
|
|
|
# ជំនួស `Total_Number_of_Reviews` និង `Average_Score` ជាមួយតម្លៃដែលយើងគណនាឡើងឯង
|
|
|
df.Total_Number_of_Reviews = df.groupby('Hotel_Name').transform('count')
|
|
|
df.Average_Score = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)
|
|
|
```
|
|
|
|
|
|
3. ដំណើរការជួរឈរពិនិត្យមតិ
|
|
|
|
|
|
1. បោះបង់ `Review_Total_Negative_Word_Counts`, `Review_Total_Positive_Word_Counts`, `Review_Date` និង `days_since_review`
|
|
|
|
|
|
2. រក្សា `Reviewer_Score`, `Negative_Review`, និង `Positive_Review` ដូចដែលវាជា,
|
|
|
|
|
|
3. រក្សា `Tags` នៅពេលនេះ
|
|
|
|
|
|
- យើងនឹងធ្វើការចម្រោះបន្ថែមលើ Tags នៅក្នុងផ្នែកបន្ទាប់ ហើយ Tags នឹងត្រូវបានបោះបង់
|
|
|
|
|
|
4. ដំណើរការជួរឈរពិនិត្យមតិជាភ្ញៀវ
|
|
|
|
|
|
1. បោះបង់ `Total_Number_of_Reviews_Reviewer_Has_Given`
|
|
|
|
|
|
2. រក្សា `Reviewer_Nationality`
|
|
|
|
|
|
### ជួរឈរ Tags
|
|
|
|
|
|
ជួរឈរ `Tag` គឺមានបញ្ហា ពីព្រោះវាជាបញ្ជី (ក្នុងទំរង់អត្ថបទ) ដែលបានផ្ទុកក្នុងជួរឈរ។ អ្នកមិនសង្ឃឹមថាលំដាប់ និងចំនួនអថេររងនៅក្នុងជួរឈរនេះតែមួយគ្នាទេ។ វាពិបាកសម្រាប់មនុស្សក្នុងការដឹងពីអត្ថន័យត្រឹមត្រូវដែលគួរឲ្យចាប់អារម្មណ៍ ពីព្រោះមានជួរដេក ៥១៥,០០០ និងសណ្ឋាគារ ១៤២៧ និងនីមួយៗមានជម្រើសខុសគ្នាខ្លះៗដែលអ្នកវាយតម្លៃអាចជ្រើសរើសបាន។ នេះជាកន្លែងដែល NLP ស្មោះត្រង់។ អ្នកអាចស្កេនអត្ថបទ និងស្វែងរកប្រយោជន៍គំនិតដែលពេញនិយមបំផុត ហើយរាប់វា។
|
|
|
|
|
|
អសូរណាស់ អ្នកមិនចាប់អារម្មណ៍លើពាក្យតែមួយទេ ប៉ុន្តែចាប់អារម្មណ៍លើពាក្យច្រើនពាក្យ (ឧ. *Business trip*)។ រត់ប្រព័ន្ធចែករំលែកភាពញឹកញាប់ពាក្យច្រើនពាក្យលើទិន្នន័យច្រើនបែបនេះ (៦,៧៦២,៦៤៦ ពាក្យ) អាចចំណាយពេលវេលាយ៉ាងខ្លាំង ប៉ុន្តែក្រោយមិនមើលទិន្នន័យ វាហាក់ដូចជាការចំណាយដែលចាំបាច់។ នេះជាកន្លែងដែលការវិភាគទិន្នន័យស្មើស្មាញមានប្រយោជន៍ ពីព្រោះអ្នកបានឃើញ ឧទាហរណ៍នៃ Tags ដូចជា `[' Business trip ', ' Solo traveler ', ' Single Room ', ' Stayed 5 nights ', ' Submitted from a mobile device ']` អ្នកអាចចាប់ផ្តើមសួរថា តើអាចកាត់បន្ថយដំណើរការដែលអ្នកត្រូវធ្វើបានយ៉ាងខ្លាំងដែរឬទេ។ សំណាងល្អ វាអាចបាន – ប៉ុន្ត្រ្តត្រូវជំហានមួយចំនួនដើម្បីកំណត់ Tags ដែលគួរឲ្យចាប់អារម្មណ៍។
|
|
|
|
|
|
### ចម្រោះ Tags
|
|
|
|
|
|
ចូរចងចាំថាគោលបំណងឯកសារទិន្នន័យគឺដើម្បីបន្ថែមអារម្មណ៍ និងជួរឈរដែលជួយអ្នកក្នុងការជ្រើសសណ្ឋាគារល្អបំផុត (សម្រាប់ខ្លួនឯង ឬអតិថិជនដែលចង់ឲ្យអ្នកបង្កើត bot ផ្តល់អនុសាសន៍សណ្ឋាគារ)។ អ្នកត្រូវសួរខ្លួនឯងថា Tags មានប្រយោជន៍ឬអត់ក្នុងឯកសារទិន្នន័យចុងក្រោយ។ នេះជាការពន្យល់មួយ (បើអ្នកត្រូវការឯកសារទិន្នន័យសម្រាប់ហេតុផលផ្សេង Tags ខ្លះអាចត្រូវឬមិនត្រូវបានរួចចេញពីការ selection)៖
|
|
|
|
|
|
1. ប្រភេទដំណើរត្រូវបានពាក់ព័ន្ធ ហើយគួរត្រូវបានរក្សាទុក
|
|
|
2. ប្រភេទក្រុមភ្ញៀវមានសារៈសំខាន់ ហើយគួរត្រូវបានរក្សាទុក
|
|
|
3. ប្រភេទបន្ទប់ ស៊ុយត ឬស្ទូឌីយោដែលភ្ញៀវបានស្នាក់នៅគ្មានសារៈសំខាន់ (សណ្ឋាគារទាំងអស់មានបន្ទប់ដូចគ្នាផ្ទាល់)
|
|
|
4. ឧបករណ៍ដែលបានដាក់តំបន់មតិគ្មានសារៈសំខាន់
|
|
|
5. ចំនួនយប់ដែលភ្ញៀវស្នាក់នៅ *អាច*មានប្រយោជន៍ ប្រសិនបើអ្នកភ្ជាប់ការស្នាក់នៅយូរជាមួយចំណង់ចំណូលចិត្តសណ្ឋាគារលើស แต่វាគឺជាការព្យាយាម ហើយប្រហែលជាគ្មានប្រយោជន៍
|
|
|
|
|
|
ជាភាគចុងក្រោយ **រក្សា Tags ២ ប្រភេទ និងដក Tags ផ្សេងទៀតចេញ**។
|
|
|
|
|
|
ដំបូង អ្នកមិនចង់រាប់ Tags ទាល់តែពួកវានៅក្នុងទម្រង់ល្អជាងនេះទេ ដូច្នេះមានន័យថាត្រូវដកសញ្ញាគូសនិងសញ្ញាក្រដាសចេញ។ អ្នកអាចធ្វើវិធីនោះបានជាច្រើន ប៉ុន្តែអ្នកចង់បានរហ័សបំផុត ព្រោះវាអាចចំណាយពេលយូរនៅបំផុតដើម្បីដំណើរការទិន្នន័យច្រើន។ ដំណឹងល្អ គឺ pandas មានវិធីងាយស្រួលដើម្បីធ្វើជំហានទាំងនេះ។
|
|
|
|
|
|
```Python
|
|
|
# ដកសញ្ញាគូបួសបើក និងបិទចេញ
|
|
|
df.Tags = df.Tags.str.strip("[']")
|
|
|
# ដកសញ្ញាដូចគ្នាសាំងទាំងអស់ផងដែរ
|
|
|
df.Tags = df.Tags.str.replace(" ', '", ",", regex = False)
|
|
|
```
|
|
|
|
|
|
សៀវភៅ Tag ទាំងអស់ធ្វើឡើងជាម៉ូដុល: `Business trip, Solo traveler, Single Room, Stayed 5 nights, Submitted from a mobile device`។
|
|
|
|
|
|
បន្ទាប់មកយើងឃើញបញ្ហា។ ពិនិត្យមតិខ្លះ ឬជួរដេកខ្លះ មាន ៥ ជួរឈរ មាន ៣ មាន ៦ ។ នេះគឺជាលទ្ធផលដែលឯកសារទិន្នន័យត្រូវបានបង្កើត ហើយពិបាកកែប្រែ។ អ្នកចង់ទទួលពិន្ទុញឹកញាប់នៃពាក្យនីមួយៗ ប៉ុន្តែពួកវានៅក្នុងលំដាប់ផ្សេងគ្នាក្នុងពិនិត្យមតិគ្រប់មួយ ដូច្នេះប្រហែលជាចំនួនពាក្យនឹងខុស ហើយសណ្ឋាគារព្រមទាំងមិនទទួលបាន Tag ដែលគួរត្រូវបានផ្ដល់។
|
|
|
|
|
|
ផ្ទុយពីនេះ អ្នកនឹងប្រើលំដាប់ខុសគ្នានេះជាសេចក្ដីអត្ថប្រយោជន៍ ព្រោះ Tag មួយៗមានពាក្យច្រើនប៉ុន្តែត្រូវបំភ័យដោយសញ្ញាក្បៀស! វិធីងាយស្រួលបំផុតគឺបង្កើតជួរឈរបណ្តោះអាសន្ន ៦ ជួរឈរជាមួយ Tag ខុសៗគ្នាដាក់នៅជួរឈរតាមលំដាប់ក្នុង Tag។ អ្នកអាចផ្សំនៅជួរឈរទាំង ៦ ទៅជាជួរឈរធំមួយ ហើយរត់មុខងារ `value_counts()` លើជួរឈរដែលបានបង្កើត។ បោះពុម្ពមើល អ្នកនឹងឃើញមាន Tag ផ្សេងៗចំនួន ២៤២៨។ នេះជាឧទាហរណ៍តិចតួច៖
|
|
|
|
|
|
| Tag | Count |
|
|
|
| ------------------------------ | ------ |
|
|
|
| Leisure trip | 417778 |
|
|
|
| Submitted from a mobile device | 307640 |
|
|
|
| Couple | 252294 |
|
|
|
| Stayed 1 night | 193645 |
|
|
|
| Stayed 2 nights | 133937 |
|
|
|
| Solo traveler | 108545 |
|
|
|
| Stayed 3 nights | 95821 |
|
|
|
| Business trip | 82939 |
|
|
|
| Group | 65392 |
|
|
|
| Family with young children | 61015 |
|
|
|
| Stayed 4 nights | 47817 |
|
|
|
| Double Room | 35207 |
|
|
|
| Standard Double Room | 32248 |
|
|
|
| Superior Double Room | 31393 |
|
|
|
| Family with older children | 26349 |
|
|
|
| Deluxe Double Room | 24823 |
|
|
|
| Double or Twin Room | 22393 |
|
|
|
| Stayed 5 nights | 20845 |
|
|
|
| Standard Double or Twin Room | 17483 |
|
|
|
| Classic Double Room | 16989 |
|
|
|
| Superior Double or Twin Room | 13570 |
|
|
|
| 2 rooms | 12393 |
|
|
|
|
|
|
Tag ទូទៅមួយចំនួនដូចជា `Submitted from a mobile device` គ្មានប្រយោជន៍សម្រាប់យើង ដូច្នេះវាមានតម្លៃក្នុងការដកចេញមុនរាប់ផែនទី ប៉ុន្តែវាជាលំហូរយ៉ាងលឿន អ្នកអាចរក្សាទុកវានិងមិនប្រើវាបាន។
|
|
|
|
|
|
### ការដក Tag សម្រាប់រយៈពេលស្នាក់នៅចេញ
|
|
|
|
|
|
ការដក Tags ទាំងនេះចេញគឺជាជំហានទី១ វាកាត់បន្ថយចំនួន Tag ដែលត្រូវគិតបន្តិចតិច។ សូមចំណាំថាអ្នកមិនដកវាចេញពីឯកសារទិន្នន័យទេ តែក្នុងការកាត់បន្ថយជួរតម្លៃនៃការរាប់ករណី/រក្សាទុកនៅក្នុងឯកសារពិនិត្យមតិ។
|
|
|
|
|
|
| Length of stay | Count |
|
|
|
| ---------------- | ------ |
|
|
|
| Stayed 1 night | 193645 |
|
|
|
| Stayed 2 nights | 133937 |
|
|
|
| Stayed 3 nights | 95821 |
|
|
|
| Stayed 4 nights | 47817 |
|
|
|
| Stayed 5 nights | 20845 |
|
|
|
| Stayed 6 nights | 9776 |
|
|
|
| Stayed 7 nights | 7399 |
|
|
|
| Stayed 8 nights | 2502 |
|
|
|
| Stayed 9 nights | 1293 |
|
|
|
| ... | ... |
|
|
|
|
|
|
មានប្រភេទបន្ទប់ ស៊ុយត ស្ទូឌីយ៉ូ អាផាតមិនជាច្រើន ។ ពួកវាមានអត្ថន័យដូចគ្នា និងមិនពាក់ព័ន្ធ ទោះបីជាអ្នកដកចេញពីការពិចារណាទេ។
|
|
|
|
|
|
| Type of room | Count |
|
|
|
| ----------------------------- | ----- |
|
|
|
| Double Room | 35207 |
|
|
|
| Standard Double Room | 32248 |
|
|
|
| Superior Double Room | 31393 |
|
|
|
| Deluxe Double Room | 24823 |
|
|
|
| Double or Twin Room | 22393 |
|
|
|
| Standard Double or Twin Room | 17483 |
|
|
|
| Classic Double Room | 16989 |
|
|
|
| Superior Double or Twin Room | 13570 |
|
|
|
|
|
|
ចុងក្រោយ នេះគឺគួរឱ្យរីករាយ (ដោយព្រោះវាមិនចំណាយពេលដំណើរការលើសកម្រិតទេ) អ្នកនឹងទទួលបាន *Tags ប្រយោជន៍* ដូចខាងក្រោម៖
|
|
|
|
|
|
| Tag | Count |
|
|
|
| --------------------------------------------- | ------ |
|
|
|
| Leisure trip | 417778 |
|
|
|
| Couple | 252294 |
|
|
|
| Solo traveler | 108545 |
|
|
|
| Business trip | 82939 |
|
|
|
| Group (combined with Travellers with friends) | 67535 |
|
|
|
| Family with young children | 61015 |
|
|
|
| Family with older children | 26349 |
|
|
|
| With a pet | 1405 |
|
|
|
|
|
|
អ្នកអាចអះអាងថា `Travellers with friends` គឺដូចជា `Group` ប្រហែល ភាគច្រើន ហើយវា គឺសមហេតុផលក្នុងការបញ្ចូលទាំងពីរជាមួយគ្នា ដូចបានបង្ហាញខាងលើ។ កូដសម្រាប់កំណត់ Tags ត្រឹមត្រូវគឺ [កំណត់ហេតុ Tags](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb)។
|
|
|
|
|
|
ជំហានចុងក្រោយគឺបង្កើតជួរឈរថ្មីសម្រាប់Tags ទាំងនេះ។ បន្ទាប់មក សម្រាប់ជួរដេកពិនិត្យមតិគ្រប់រូប ត្រូវបើកបង្ហាញថាជួរឈរ `Tag` ផ្គូផ្គងជាមួយជួរឈរថ្មីណាមួយ សូមបន្ថែមលេខ ១ ប្រសិនមិនគ្នា សូមបន្ថែមលេខ ០។ លទ្ធផលចុងក្រោយនឹងជាចំនួនអ្នកបើកបង្ហាញដែលបានជ្រើសសណ្ឋាគារនេះ (ក្នុងសរុប) ដូចជា សម្រាប់អាជីវកម្មទេសចរណ៍ ឬសម្រាប់លំហែកាយជាមួយសត្វចិញ្ចឹម ហើយនេះជាព័ត៌មានមានប្រយោជន៍នៅពេលផ្តល់អនុសាសន៍សណ្ឋាគារ។
|
|
|
|
|
|
```python
|
|
|
# ដំណើរការស្លាកទៅជាជួរឈរថ្មី
|
|
|
# ឯកសារ Hotel_Reviews_Tags.py កំណត់ស្លាកសំខាន់បំផុត
|
|
|
# ដំណើរកម្សាន្ត, គូស្នេហា, អ្នកដំណើរតែម្នាក់, ដំណើរជំនួញ, ក្រុមរួមជាមួយ អ្នកដំណើរជាមួយមិត្តភក្តិ,
|
|
|
# គ្រួសារជាមួយកុមារតូច, គ្រួសារជាមួយកុមារចាស់, ជាមួយសត្វចិញ្ចឹម
|
|
|
df["Leisure_trip"] = df.Tags.apply(lambda tag: 1 if "Leisure trip" in tag else 0)
|
|
|
df["Couple"] = df.Tags.apply(lambda tag: 1 if "Couple" in tag else 0)
|
|
|
df["Solo_traveler"] = df.Tags.apply(lambda tag: 1 if "Solo traveler" in tag else 0)
|
|
|
df["Business_trip"] = df.Tags.apply(lambda tag: 1 if "Business trip" in tag else 0)
|
|
|
df["Group"] = df.Tags.apply(lambda tag: 1 if "Group" in tag or "Travelers with friends" in tag else 0)
|
|
|
df["Family_with_young_children"] = df.Tags.apply(lambda tag: 1 if "Family with young children" in tag else 0)
|
|
|
df["Family_with_older_children"] = df.Tags.apply(lambda tag: 1 if "Family with older children" in tag else 0)
|
|
|
df["With_a_pet"] = df.Tags.apply(lambda tag: 1 if "With a pet" in tag else 0)
|
|
|
|
|
|
```
|
|
|
|
|
|
### រក្សាទុកឯកសារ
|
|
|
|
|
|
ចុងក្រោយ សូមរក្សាទុកឯកសារទិន្នន័យអោយថ្មីជាមួយឈ្មោះថ្មី។
|
|
|
|
|
|
```python
|
|
|
df.drop(["Review_Total_Negative_Word_Counts", "Review_Total_Positive_Word_Counts", "days_since_review", "Total_Number_of_Reviews_Reviewer_Has_Given"], axis = 1, inplace=True)
|
|
|
|
|
|
# កំពុងរក្សាទុកឯកសារទិន្នន័យថ្មីជាមួយជួរឈរដែលបានគិតផ្លូវរួចហើយ
|
|
|
print("Saving results to Hotel_Reviews_Filtered.csv")
|
|
|
df.to_csv(r'../data/Hotel_Reviews_Filtered.csv', index = False)
|
|
|
```
|
|
|
|
|
|
## ប្រតិបត្ដិការវិភាគអារម្មណ៍
|
|
|
|
|
|
នៅក្នុងផ្នែកចុងក្រោយនេះ អ្នកនឹងអនុវត្តវិភាគអារម្មណ៍ទៅលើជួរឈរពិនិត្យមតិ ហើយរក្សាលទ្ធផលនៅក្នុងឯកសារទិន្នន័យ។
|
|
|
|
|
|
## ការអនុវត្ត៖ ដំណើរការនិងរក្សាទុកទិន្នន័យចម្រោះ
|
|
|
|
|
|
ចំណាំថាឥឡូវនេះ អ្នកកំពុងផ្ទុកឯកសារទិន្នន័យចម្រោះដែលបានរក្សាទុកនៅផ្នែកមុន ហើយមិនមែនឯកសារដើមទេ។
|
|
|
|
|
|
```python
|
|
|
import time
|
|
|
import pandas as pd
|
|
|
import nltk as nltk
|
|
|
from nltk.corpus import stopwords
|
|
|
from nltk.sentiment.vader import SentimentIntensityAnalyzer
|
|
|
nltk.download('vader_lexicon')
|
|
|
|
|
|
# ទាញយកការត្រួតពិនិត្យសណ្ឋាគារដែលបានត្រងពីឯកសារ CSV
|
|
|
df = pd.read_csv('../../data/Hotel_Reviews_Filtered.csv')
|
|
|
|
|
|
# កូដរបស់អ្នកនឹងត្រូវបានបញ្ចូលនៅទីនេះ
|
|
|
|
|
|
|
|
|
# ចុងក្រោយ សូមចងចាំរក្សាទុកការត្រួតពិនិត្យសណ្ឋាគារជាមួយទិន្នន័យ NLP ថ្មីដែលបានបន្ថែម
|
|
|
print("Saving results to Hotel_Reviews_NLP.csv")
|
|
|
df.to_csv(r'../data/Hotel_Reviews_NLP.csv', index = False)
|
|
|
```
|
|
|
|
|
|
### ការដកពាក្យឈប់
|
|
|
|
|
|
បើអ្នកចង់រត់វិភាគអារម្មណ៍លើជួរឈរពិនិត្យមតិ Negative និង Positive វាអាចចំណាយពេលយូរ។ បានធ្វើតេស្តជាមួយកុំព្យូទ័រយួរដៃមាន CPU លឿន វាចំណាយពេល 12-14 នាទី អាស្រ័យលើបណ្ណាល័យអារម្មណ៍ដែលបានប្រើ។ វាក្នុងរយៈពេលខ្លី ប៉ុន្តែក៏គួរតែពិចារណាថាតើអាចបង្កើនល្បឿនបានទេ។
|
|
|
|
|
|
ការដកពាក្យឈប់ ឬពាក្យជាភាសាអង់គ្លេសធម្មតាដែលមិនប៉ះពាល់អារម្មណ៍នៃប្រយោគ គឺជាជំហានទីមួយ។ ដោយដកពួកវាចេញ អ្នកវិភាគអារម្មណ៍គួររត់បានលឿនជាងមុន ប៉ុន្តែមិនត្រឹមត្រូវតិចជាងមុនឡើយ (ព្រោះពាក្យឈប់មិនមានអារម្មណ៍ ប៉ុន្តែពួកវាធ្វើឲ្យការវិភាគយឺត)។
|
|
|
|
|
|
ការពិនិត្យមតិអវិជ្ជមានវែងបំផុតមាន ៣៩៥ ពាក្យ ប៉ុន្ត្រ្ទចាប់តាំងពីដកពាក្យឈប់ចេញ គឺនៅ ១៩៥ ពាក្យ។
|
|
|
|
|
|
ការដកពាក្យឈប់ក៏ជាការអនុវត្តលឿនដែរ ការដកពាក្យឈប់ពីជួរឈរពិនិត្យមតិ ២ ជួរពីជួរដេក ៥១៥,០០០ ចំណាយពេល ៣.៣ វិនាទីនៅលើឧបករណ៍ភ្ជាប់សាកល្បង។ វាអាចយឺតឬឆាប់ជាងនេះសម្រាប់អ្នកขึ้นដោយប្រើឧបករណ៍ CPU មួយ RAM បទពិសោធន៍ មានវត្ថុចល័ត SSD ឬគ្មានហើយប៉ុន្តាយ៉ាងណាក៏ដោយ។ រយៈពេលខ្លីនេះមានន័យថាបើវាជួយបង្កើនល្បឿនវិភាគអារម្មណ៍ វាគួរតែបានធ្វើ។
|
|
|
|
|
|
```python
|
|
|
from nltk.corpus import stopwords
|
|
|
|
|
|
# ដាក់ទិន្នន័យពិនិត្យផ្ញើសណ្ឋាគារពី CSV
|
|
|
df = pd.read_csv("../../data/Hotel_Reviews_Filtered.csv")
|
|
|
|
|
|
# លុបពាក្យបញ្ឈប់ - ប្រហែលជាស៊ីជម្រៅសម្រាប់អត្ថបទច្រើន!
|
|
|
# Ryan Han (ryanxjhan លើ Kaggle) មានអត្ថបទល្អអំពីការវាស់វែងលទ្ធភាពនៃវិធីលុបពាក្យបញ្ឈប់ផ្សេងៗ
|
|
|
# https://www.kaggle.com/ryanxjhan/fast-stop-words-removal # ប្រើវិធីដែល Ryan ប្រាប់ដាក់
|
|
|
start = time.time()
|
|
|
cache = set(stopwords.words("english"))
|
|
|
def remove_stopwords(review):
|
|
|
text = " ".join([word for word in review.split() if word not in cache])
|
|
|
return text
|
|
|
|
|
|
# លុបពាក្យបញ្ឈប់ពីទាំងពីរបន្ទាត់ទិន្នន័យ
|
|
|
df.Negative_Review = df.Negative_Review.apply(remove_stopwords)
|
|
|
df.Positive_Review = df.Positive_Review.apply(remove_stopwords)
|
|
|
```
|
|
|
|
|
|
### បំពេញវិភាគអារម្មណ៍
|
|
|
|
|
|
ឥឡូវអ្នកគួរតែគណនាវិភាគអារម្មណ៍សម្រាប់ជួរឈរពិនិត្យមតិទាំងអវិជ្ជមាន និងវិជ្ជមាន ហើយរក្សាលទ្ធផលនៅក្នុង ២ ជួរឈរថ្មី។ ការតេស្តវីភាគអារម្មណ៍ គឺប្រៀបធៀបជាមួយពិន្ទុអ្នកផ្តល់មតិសម្រាប់ពិនិត្យមតិបែបដូចគ្នា។ ឧទាហរណ៍ បើអារម្មណ៍ថាពិនិត្យអវិជ្ជមានមានអារម្មណ៍ ១ (អារម្មណ៍វិជ្ជមានខ្លាំង) ហើយពិនិត្យវិជ្ជមានគឺ ១ ប៉ុន្ត្រអ្នកផ្តល់មតិយ៉ាងហោចណាស់លើសណ្ឋាគារមានពិន្ទុទាបបំផុត ពោលគឺអត្ថបទពិនិត្យមមិនផ្គូផ្គងនឹងពិន្ទុ ឬអ្នកវិភាគអារម្មណ៍មិនអាចទទួលស្គាល់អារម្មណ៍ត្រឹមត្រូវបាន។ អ្នកគួរមានការរំពឹតថា ពិន្ទុអារម្មណ៍ខ្លះគឺខុសបំពានពេញលេញ ហើយជាញឹកញាប់វាអាចពន្យល់បាន ដោយឧទាហរណ៍ មតិយោបល់អាចជារឿងសិចសេរី "មិនអូស លោកខ្ញុំស្រលាញ់ការគេងក្នុងបន្ទប់គ្មានប្រេងកំដៅ" ហើយអ្នកវិភាគអារម្មណ៍សន្និដ្ឋានថាវាជាអារម្មណ៍វិជ្ជមាន ទោះបីជាមនុស្សអាននោះដឹងថាវាជាការអះអាង។
|
|
|
|
|
|
NLTK ផ្តល់អ្នកវិភាគអារម្មណ៍មួយចំនួនផ្សេងៗសម្រាប់រៀន ហើយអ្នកអាចជំនួសពួកវាបាន ហើយមើលថា អារម្មណ៍មានត្រឹមត្រូវខ្លះ ឬក៍ខ្វះ។ វិភាគអារម្មណ៍ VADER ត្រូវបានប្រើនៅទីនេះ។
|
|
|
> Hutto, C.J. & Gilbert, E.E. (2014). VADER: ម៉ូដែលរៀបចំលក្ខខ័ណ្ឌមានលក្ខណៈសាមញ្ញសម្រាប់វិភាគអារម្មណ៍នៃអត្ថបទបណ្តាញសង្គម។ កិច្ចសន្និបាតអន្ដរជាតិជាលើកទីប្រាំបីលើបណ្តាញអ៊ីនធឺរណែត និងបណ្តាញសង្គម (ICWSM-14)។ Ann Arbor, MI, ខែមិថុនា ២០១៤។
|
|
|
|
|
|
```python
|
|
|
from nltk.sentiment.vader import SentimentIntensityAnalyzer
|
|
|
|
|
|
# បង្កើតកម្មវិធីវិភាគអារម្មណ៍ vader (មានកម្មវិធីផ្សេងទៀតនៅក្នុង NLTK ដែលអ្នកអាចសាកល្បងបានផងដែរ)
|
|
|
vader_sentiment = SentimentIntensityAnalyzer()
|
|
|
# Hutto, C.J. & Gilbert, E.E. (2014). VADER: ម៉ូដែលផ្អែកលើច្បាប់តិចតួចសម្រាប់វិភាគអារម្មណ៍នៃអត្ថបទប្រព័ន្ធផ្សព្វផ្សាយសង្គម។ សន្និសីទអន្តរជាតិលើកទីប្រាំបួនអំពីបន្ទាត់បណ្ដាញនិងប្រព័ន្ធផ្សព្វផ្សាយសង្គម (ICWSM-14)។ អាន់អាប់ប៊ើរ, MI, ខែមិថុនា 2014។
|
|
|
|
|
|
# មានជម្រើស 3 សម្រាប់ការបញ្ចូលមួយសម្រាប់ការវាយតម្លៃ៖
|
|
|
# វាអាចជា "គ្មានអវិជ្ជមាន", ក្នុងករណីនេះ សូមបង្វិល 0
|
|
|
# វាអាចជា "គ្មានវិជ្ជមាន", ក្នុងករណីនេះ សូមបង្វិល 0
|
|
|
# វាអាចជាការវាយតម្លៃមួយ, ក្នុងករណីនេះ គណនាអារម្មណ៍នោះ
|
|
|
def calc_sentiment(review):
|
|
|
if review == "No Negative" or review == "No Positive":
|
|
|
return 0
|
|
|
return vader_sentiment.polarity_scores(review)["compound"]
|
|
|
```
|
|
|
|
|
|
បន្ទាប់ពីក្នុងកម្មវិធីរបស់អ្នក នៅពេលដែលអ្នករួចរាល់ក្នុងការគណនាអារម្មណ៍ អ្នកអាចអនុវត្តវាទៅលើការពិនិត្យមតិមួយមួយដូចតទៅ៖
|
|
|
|
|
|
```python
|
|
|
# បន្ថែមជួរឈរពីអារម្មណ៍អវិជ្ជមាន និងអារម្មណ៍វិជ្ជមាន
|
|
|
print("Calculating sentiment columns for both positive and negative reviews")
|
|
|
start = time.time()
|
|
|
df["Negative_Sentiment"] = df.Negative_Review.apply(calc_sentiment)
|
|
|
df["Positive_Sentiment"] = df.Positive_Review.apply(calc_sentiment)
|
|
|
end = time.time()
|
|
|
print("Calculating sentiment took " + str(round(end - start, 2)) + " seconds")
|
|
|
```
|
|
|
|
|
|
នេះចំណាយពេលប្រហែល ១២០ វិនាទីនៅលើកុំព្យូទ័ររបស់ខ្ញុំ ប៉ុន្តែវានឹងផ្លាស់ប្តូរតាមកុំព្យូទ័រនីមួយៗ។ ប្រសិនបើអ្នកចង់បោះពុម្ពលទ្ធផល ហើយមើលថាអារម្មណ៍សមស្របនឹងការពិនិត្យមតិយ៉ាងដែរឬទេ៖
|
|
|
|
|
|
```python
|
|
|
df = df.sort_values(by=["Negative_Sentiment"], ascending=True)
|
|
|
print(df[["Negative_Review", "Negative_Sentiment"]])
|
|
|
df = df.sort_values(by=["Positive_Sentiment"], ascending=True)
|
|
|
print(df[["Positive_Review", "Positive_Sentiment"]])
|
|
|
```
|
|
|
|
|
|
រឿងចុងក្រោយណាស់ដែលត្រូវធ្វើជាមួយឯកសារមុនប្រើវាក្នុងការប្រកួតប្រជែង គឺត្រូវរក្សាទុកវា! អ្នកគួរតែពិចារណាលំដាប់ជួរឈរថ្មីទាំងអស់របស់អ្នក ដើម្បីឲ្យវាងាយស្រួលដំណើរការជាមួយ (សម្រាប់មនុស្ស វាជាការផ្លាស់ប្តូរផ្នែកសម្រស់)។
|
|
|
|
|
|
```python
|
|
|
# បញ្ជាលំដាប់ជួរឈរ (នេះគឺគ្រាន់តែមួយរូបរាង ប៉ុន្តែដើម្បីឲ្យងាយស្រួលស្វែងរកទិន្នន័យនៅពេលក្រោយ)
|
|
|
df = df.reindex(["Hotel_Name", "Hotel_Address", "Total_Number_of_Reviews", "Average_Score", "Reviewer_Score", "Negative_Sentiment", "Positive_Sentiment", "Reviewer_Nationality", "Leisure_trip", "Couple", "Solo_traveler", "Business_trip", "Group", "Family_with_young_children", "Family_with_older_children", "With_a_pet", "Negative_Review", "Positive_Review"], axis=1)
|
|
|
|
|
|
print("Saving results to Hotel_Reviews_NLP.csv")
|
|
|
df.to_csv(r"../data/Hotel_Reviews_NLP.csv", index = False)
|
|
|
```
|
|
|
|
|
|
អ្នកគួរតែដំណើរការកូដទាំងមូលសម្រាប់ [កំណត់ត្រាវិភាគ](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/5-Hotel-Reviews-2/solution/3-notebook.ipynb) (បន្ទាប់ពីអ្នកបានដំណើរការកំណត់ត្រា [ការតម្រៀប](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb) ដើម្បីបង្កើតឯកសារ Hotel_Reviews_Filtered.csv)។
|
|
|
|
|
|
ដើម្បីពិនិត្យមើលម្តងទៀត ជំហានគឺ៖
|
|
|
|
|
|
1. ឯកសារដើមទិន្នន័យ **Hotel_Reviews.csv** ត្រូវបានស្ទង់មតិនៅមេរៀនមុនជាមួយ [កំណត់ត្រាអ្នកស្ទង់មតិ](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/4-Hotel-Reviews-1/solution/notebook.ipynb)
|
|
|
2. Hotel_Reviews.csv ត្រូវបានតម្រៀបដោយ [កំណត់ត្រាការតម្រៀប](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/5-Hotel-Reviews-2/solution/1-notebook.ipynb) បណ្តាលឲ្យមាន **Hotel_Reviews_Filtered.csv**
|
|
|
3. Hotel_Reviews_Filtered.csv ត្រូវបានដំណើរការដោយ [កំណត់ត្រាវិភាគអារម្មណ៍](https://github.com/microsoft/ML-For-Beginners/blob/main/6-NLP/5-Hotel-Reviews-2/solution/3-notebook.ipynb) បណ្តាលឲ្យមាន **Hotel_Reviews_NLP.csv**
|
|
|
4. ប្រើប្រាស់ Hotel_Reviews_NLP.csv ក្នុងការប្រកួត NLP ខាងក្រោម
|
|
|
|
|
|
### សេចក្ដីសន្និដ្ឋាន
|
|
|
|
|
|
នៅពេលដែលអ្នកចាប់ផ្តើម អ្នកមានទិន្នន័យជាមួយជួរឈរ និងទិន្នន័យ ប៉ុន្តែមិនអាចផ្ទៀងផ្ទាត់ឬប្រើប្រាស់ទាំងអស់បានទេ។ អ្នកបានស្ទង់មតិទិន្នន័យ ដកចេញអ្វីដែលអ្នកមិនត្រូវការ បម្លែងស្លាកឲ្យទៅជាអ្វីដែលមានប្រយោជន៍ គណនាមធ្យមភាគរបស់ខ្លួន បន្ថែមជួរឈរអារម្មណ៍មួយចំនួន ហើយសង្ឃឹមថា បានរៀនអ្វីដែលគួរឱ្យចាប់អារម្មណ៍អំពីការប្រែប្រួលអត្ថបទធម្មជាតិ។
|
|
|
|
|
|
## [លំហាត់តេស្តបិទមុខវិជ្ជា](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
|
|
## ការប្រកួតប្រជែង
|
|
|
|
|
|
ឥឡូវនេះដែលអ្នកបានវិភាគទិន្នន័យរបស់អ្នកសម្រាប់អារម្មណ៍ សូមពិនិត្យមើលថាតើអ្នកអាចប្រើយុទ្ធសាស្រ្តដែលបានរៀនក្នុងកម្មវិធីនេះ (ដូចជាការបែងចែកក្រុម អាចជា?) ដើម្បីកំណត់លំនាំជុំវិញអារម្មណ៍។
|
|
|
|
|
|
## ការត្រួតពិនិត្យ និងរៀនផ្ទាល់ខ្លួន
|
|
|
|
|
|
យក [មុខងារសិក្សានេះ](https://docs.microsoft.com/en-us/learn/modules/classify-user-feedback-with-the-text-analytics-api/?WT.mc_id=academic-77952-leestott) ដើម្បីរៀនបន្ថែម និងប្រើឧបករណ៍ផ្សេងៗដើម្បីស្ទង់មតិអារម្មណ៍ក្នុងអត្ថបទ។
|
|
|
## ផ្ញើកិច្ចការរៀន
|
|
|
|
|
|
[សាកល្បងទិន្នន័យផ្សេង](assignment.md)
|
|
|
|
|
|
---
|
|
|
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
|
|
|
**ការបដិសេធ**៖
|
|
|
ឯកសារនេះត្រូវបានបកប្រែដោយប្រើសេវាកម្មបកប្រែ AI [Co-op Translator](https://github.com/Azure/co-op-translator)។ ខណៈពេលដែលយើងព្យាយាមឲ្យមានភាពត្រឹមត្រូវ សូមយកចិត្តទុកដាក់ទៅថាការបកប្រែដោយស្វ័យប្រវត្តិនេះអាចមានកំហុស ឬការខ្វះត្រឹមត្រូវបាន។ ឯកសារដើមជាភាសាមាតុភាគត្រូវបានគិតថាជា ប្រភពពិតប្រាកដ។ សម្រាប់ព័ត៌មានសំខាន់ៗ ការបកប្រែដោយមនុស្សជំនាញត្រូវបានអនុញ្ញាត។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកប្រែខុសពីការប្រើប្រាស់ការបកប្រែនេះទេ។
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER END --> |