PerSent 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PerSent might be problematic. Click here for more details.
- persent-0.1.0/LICENSE.txt +21 -0
- persent-0.1.0/PKG-INFO +162 -0
- persent-0.1.0/PerSent/__init__.py +4 -0
- persent-0.1.0/PerSent/analyzer.py +113 -0
- persent-0.1.0/PerSent.egg-info/PKG-INFO +162 -0
- persent-0.1.0/PerSent.egg-info/SOURCES.txt +11 -0
- persent-0.1.0/PerSent.egg-info/dependency_links.txt +1 -0
- persent-0.1.0/PerSent.egg-info/requires.txt +6 -0
- persent-0.1.0/PerSent.egg-info/top_level.txt +1 -0
- persent-0.1.0/README.md +130 -0
- persent-0.1.0/setup.cfg +4 -0
- persent-0.1.0/setup.py +34 -0
- persent-0.1.0/tests/test_basic.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 𝐑𝐞𝐳𝐚 𝐀𝐬𝐚𝐝𝐢
|
|
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.
|
persent-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PerSent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Persian Sentiment Analysis Toolkit
|
|
5
|
+
Home-page: https://github.com/RezaGooner/PerSent
|
|
6
|
+
Author: RezaGooner
|
|
7
|
+
Author-email: RezaAsadiProgrammer@Gmail.com
|
|
8
|
+
Keywords: persian sentiment analysis nlp
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE.txt
|
|
15
|
+
Requires-Dist: hazm>=0.7.0
|
|
16
|
+
Requires-Dist: gensim>=4.0.0
|
|
17
|
+
Requires-Dist: scikit-learn>=1.0.0
|
|
18
|
+
Requires-Dist: pandas>=1.3.0
|
|
19
|
+
Requires-Dist: tqdm>=4.62.0
|
|
20
|
+
Requires-Dist: joblib>=1.1.0
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: keywords
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Persian Sentiment Analyzer
|
|
34
|
+
|
|
35
|
+
[](https://www.python.org/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
|
|
38
|
+
A Python library for sentiment analysis of Persian (Farsi) text, capable of classifying opinions as "recommended", "not_recommended", or "no_idea".
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
- **Text Preprocessing**: Normalization, tokenization, stemming, and stopword removal for Persian text
|
|
43
|
+
- **Word Embeddings**: Built-in Word2Vec implementation for Persian language
|
|
44
|
+
- **Sentiment Classification**: Logistic Regression classifier trained on Persian sentiment data
|
|
45
|
+
- **Model Persistence**: Save and load trained models for future use
|
|
46
|
+
- **Batch Processing**: Analyze sentiment for multiple texts at once
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install persian-sentiment-analyzer
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Dependencies
|
|
55
|
+
- Python 3.6+
|
|
56
|
+
|
|
57
|
+
- hazm
|
|
58
|
+
|
|
59
|
+
- gensim
|
|
60
|
+
|
|
61
|
+
- scikit-learn
|
|
62
|
+
|
|
63
|
+
- numpy
|
|
64
|
+
|
|
65
|
+
- pandas
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
### Basic Usage
|
|
70
|
+
|
|
71
|
+
``` bash
|
|
72
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
73
|
+
|
|
74
|
+
# Initialize with a pre-trained model
|
|
75
|
+
analyzer = SentimentAnalyzer(model_path="path/to/pretrained_model")
|
|
76
|
+
|
|
77
|
+
# Predict sentiment
|
|
78
|
+
result = analyzer.predict("این محصول بسیار عالی است")
|
|
79
|
+
print(result) # Output: 'recommended'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Training Your Own Model
|
|
83
|
+
|
|
84
|
+
``` bash
|
|
85
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
86
|
+
import pandas as pd
|
|
87
|
+
|
|
88
|
+
# Load your dataset
|
|
89
|
+
data = pd.read_csv("persian_reviews.csv")
|
|
90
|
+
texts = data['text'].tolist()
|
|
91
|
+
labels = data['label'].values # 0: not_recommended, 1: recommended, 2: no_idea
|
|
92
|
+
|
|
93
|
+
# Initialize analyzer
|
|
94
|
+
analyzer = SentimentAnalyzer()
|
|
95
|
+
|
|
96
|
+
# Preprocess and tokenize texts
|
|
97
|
+
tokenized_texts = [analyzer.preprocessor.preprocess_text(text) for text in texts]
|
|
98
|
+
|
|
99
|
+
# Train Word2Vec model
|
|
100
|
+
analyzer.train_word2vec(tokenized_texts, vector_size=100)
|
|
101
|
+
|
|
102
|
+
# Prepare feature vectors
|
|
103
|
+
X = np.array([analyzer.sentence_vector(tokens) for tokens in tokenized_texts])
|
|
104
|
+
|
|
105
|
+
# Train classifier
|
|
106
|
+
analyzer.train_classifier(X, labels)
|
|
107
|
+
|
|
108
|
+
# Save the trained model
|
|
109
|
+
analyzer.save_model("my_persian_model")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Batch Processing
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
from persian_sentiment_analyzer import predict_sentiments_for_file
|
|
116
|
+
|
|
117
|
+
# Process a CSV file containing Persian comments
|
|
118
|
+
results_summary = predict_sentiments_for_file(
|
|
119
|
+
analyzer,
|
|
120
|
+
input_file="comments.csv",
|
|
121
|
+
output_file="results.csv",
|
|
122
|
+
summary_file="summary.csv"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
print(results_summary)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Model Architecture
|
|
129
|
+
1- Text Preprocessing:
|
|
130
|
+
|
|
131
|
+
- Normalization (Hazm)
|
|
132
|
+
|
|
133
|
+
- Tokenization
|
|
134
|
+
|
|
135
|
+
- Stemming
|
|
136
|
+
|
|
137
|
+
- Stopword removal
|
|
138
|
+
|
|
139
|
+
2- Feature Extraction:
|
|
140
|
+
|
|
141
|
+
- Word2Vec embeddings (100 dimensions)
|
|
142
|
+
|
|
143
|
+
- Sentence vectors (average of word vectors)
|
|
144
|
+
|
|
145
|
+
3- Classification:
|
|
146
|
+
|
|
147
|
+
- Logistic Regression with L2 regularization
|
|
148
|
+
|
|
149
|
+
## Performance
|
|
150
|
+
The pre-trained model achieves the following performance on our test set:
|
|
151
|
+
|
|
152
|
+
Metric Value
|
|
153
|
+
Accuracy 85.2%
|
|
154
|
+
Precision 84.7%
|
|
155
|
+
Recall 85.0%
|
|
156
|
+
F1-score 84.8%
|
|
157
|
+
|
|
158
|
+
License
|
|
159
|
+
This project is licensed under the MIT [License](https://github.com/RezaGooner/Sentiment-Survey-Analyzer/blob/main/LICENSE) - see the LICENSE file for details
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
> Github : RezaGooner
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from hazm import Normalizer, word_tokenize, Stemmer, stopwords_list
|
|
3
|
+
import re
|
|
4
|
+
from tqdm import tqdm
|
|
5
|
+
from gensim.models import Word2Vec
|
|
6
|
+
import numpy as np
|
|
7
|
+
from sklearn.linear_model import LogisticRegression
|
|
8
|
+
from sklearn.model_selection import train_test_split
|
|
9
|
+
import os
|
|
10
|
+
import joblib
|
|
11
|
+
|
|
12
|
+
class PersianSentimentAnalyzer:
|
|
13
|
+
def __init__(self, model_dir='persian_sentiment/model'):
|
|
14
|
+
self.normalizer = Normalizer()
|
|
15
|
+
self.stemmer = Stemmer()
|
|
16
|
+
self.stopwords = set(stopwords_list())
|
|
17
|
+
self.model_dir = model_dir
|
|
18
|
+
self.vectorizer = None
|
|
19
|
+
self.classifier = None
|
|
20
|
+
|
|
21
|
+
# ایجاد پوشه مدل اگر وجود نداشته باشد
|
|
22
|
+
os.makedirs(self.model_dir, exist_ok=True)
|
|
23
|
+
|
|
24
|
+
def _preprocess_text(self, text):
|
|
25
|
+
"""پیشپردازش متن فارسی"""
|
|
26
|
+
# نرمالسازی
|
|
27
|
+
text = self.normalizer.normalize(str(text))
|
|
28
|
+
|
|
29
|
+
# حذف اعداد و علائم
|
|
30
|
+
text = re.sub(r'[!()-\[\]{};:\'",؟<>./?@#$%^&*_~۰-۹\d]+', ' ', text)
|
|
31
|
+
text = re.sub(r'\s+', ' ', text).strip()
|
|
32
|
+
|
|
33
|
+
# توکنسازی و ریشهیابی
|
|
34
|
+
tokens = word_tokenize(text)
|
|
35
|
+
processed_tokens = [
|
|
36
|
+
self.stemmer.stem(token)
|
|
37
|
+
for token in tokens
|
|
38
|
+
if token not in self.stopwords and len(token) > 1
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
return processed_tokens
|
|
42
|
+
|
|
43
|
+
def _sentence_vector(self, sentence, model):
|
|
44
|
+
"""تبدیل جمله به بردار با استفاده از مدل Word2Vec"""
|
|
45
|
+
vectors = []
|
|
46
|
+
for word in sentence:
|
|
47
|
+
try:
|
|
48
|
+
vectors.append(model.wv[word])
|
|
49
|
+
except KeyError:
|
|
50
|
+
vectors.append(np.zeros(100))
|
|
51
|
+
return np.mean(vectors, axis=0) if vectors else np.zeros(100)
|
|
52
|
+
|
|
53
|
+
def train(self, train_csv, test_size=0.2, vector_size=100, window=5):
|
|
54
|
+
"""آموزش مدل از دادههای CSV"""
|
|
55
|
+
# خواندن دادهها
|
|
56
|
+
df = pd.read_csv(train_csv)
|
|
57
|
+
df['tokens'] = df['body'].apply(self._preprocess_text)
|
|
58
|
+
|
|
59
|
+
# آموزش مدل Word2Vec
|
|
60
|
+
self.vectorizer = Word2Vec(
|
|
61
|
+
sentences=df['tokens'],
|
|
62
|
+
vector_size=vector_size,
|
|
63
|
+
window=window,
|
|
64
|
+
min_count=1,
|
|
65
|
+
workers=4
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# تبدیل جملات به بردار
|
|
69
|
+
X = np.array([self._sentence_vector(s, self.vectorizer) for s in df['tokens']])
|
|
70
|
+
y = df['recommendation_status'].map({
|
|
71
|
+
"no_idea": 2,
|
|
72
|
+
"recommended": 1,
|
|
73
|
+
"not_recommended": 0
|
|
74
|
+
}).values
|
|
75
|
+
|
|
76
|
+
# تقسیم دادهها
|
|
77
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size)
|
|
78
|
+
|
|
79
|
+
# آموزش طبقهبند
|
|
80
|
+
self.classifier = LogisticRegression(max_iter=1000)
|
|
81
|
+
self.classifier.fit(X_train, y_train)
|
|
82
|
+
|
|
83
|
+
# ذخیره مدل
|
|
84
|
+
self.save_model()
|
|
85
|
+
|
|
86
|
+
# ارزیابی
|
|
87
|
+
accuracy = self.classifier.score(X_test, y_test)
|
|
88
|
+
return accuracy
|
|
89
|
+
|
|
90
|
+
def predict(self, text):
|
|
91
|
+
"""پیشبینی احساس متن"""
|
|
92
|
+
if not self.classifier or not self.vectorizer:
|
|
93
|
+
raise Exception("Model not trained! Call train() first or load a pretrained model.")
|
|
94
|
+
|
|
95
|
+
tokens = self._preprocess_text(text)
|
|
96
|
+
vector = self._sentence_vector(tokens, self.vectorizer)
|
|
97
|
+
prediction = self.classifier.predict([vector])[0]
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
0: "not_recommended",
|
|
101
|
+
1: "recommended",
|
|
102
|
+
2: "no_idea"
|
|
103
|
+
}[prediction]
|
|
104
|
+
|
|
105
|
+
def save_model(self):
|
|
106
|
+
"""ذخیره مدل آموزش دیده"""
|
|
107
|
+
joblib.dump(self.classifier, os.path.join(self.model_dir, 'classifier.joblib'))
|
|
108
|
+
self.vectorizer.save(os.path.join(self.model_dir, 'word2vec.model'))
|
|
109
|
+
|
|
110
|
+
def load_model(self):
|
|
111
|
+
"""بارگذاری مدل از فایل"""
|
|
112
|
+
self.classifier = joblib.load(os.path.join(self.model_dir, 'classifier.joblib'))
|
|
113
|
+
self.vectorizer = Word2Vec.load(os.path.join(self.model_dir, 'word2vec.model'))
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PerSent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Persian Sentiment Analysis Toolkit
|
|
5
|
+
Home-page: https://github.com/RezaGooner/PerSent
|
|
6
|
+
Author: RezaGooner
|
|
7
|
+
Author-email: RezaAsadiProgrammer@Gmail.com
|
|
8
|
+
Keywords: persian sentiment analysis nlp
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE.txt
|
|
15
|
+
Requires-Dist: hazm>=0.7.0
|
|
16
|
+
Requires-Dist: gensim>=4.0.0
|
|
17
|
+
Requires-Dist: scikit-learn>=1.0.0
|
|
18
|
+
Requires-Dist: pandas>=1.3.0
|
|
19
|
+
Requires-Dist: tqdm>=4.62.0
|
|
20
|
+
Requires-Dist: joblib>=1.1.0
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: keywords
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Persian Sentiment Analyzer
|
|
34
|
+
|
|
35
|
+
[](https://www.python.org/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
|
|
38
|
+
A Python library for sentiment analysis of Persian (Farsi) text, capable of classifying opinions as "recommended", "not_recommended", or "no_idea".
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
- **Text Preprocessing**: Normalization, tokenization, stemming, and stopword removal for Persian text
|
|
43
|
+
- **Word Embeddings**: Built-in Word2Vec implementation for Persian language
|
|
44
|
+
- **Sentiment Classification**: Logistic Regression classifier trained on Persian sentiment data
|
|
45
|
+
- **Model Persistence**: Save and load trained models for future use
|
|
46
|
+
- **Batch Processing**: Analyze sentiment for multiple texts at once
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install persian-sentiment-analyzer
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Dependencies
|
|
55
|
+
- Python 3.6+
|
|
56
|
+
|
|
57
|
+
- hazm
|
|
58
|
+
|
|
59
|
+
- gensim
|
|
60
|
+
|
|
61
|
+
- scikit-learn
|
|
62
|
+
|
|
63
|
+
- numpy
|
|
64
|
+
|
|
65
|
+
- pandas
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
### Basic Usage
|
|
70
|
+
|
|
71
|
+
``` bash
|
|
72
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
73
|
+
|
|
74
|
+
# Initialize with a pre-trained model
|
|
75
|
+
analyzer = SentimentAnalyzer(model_path="path/to/pretrained_model")
|
|
76
|
+
|
|
77
|
+
# Predict sentiment
|
|
78
|
+
result = analyzer.predict("این محصول بسیار عالی است")
|
|
79
|
+
print(result) # Output: 'recommended'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Training Your Own Model
|
|
83
|
+
|
|
84
|
+
``` bash
|
|
85
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
86
|
+
import pandas as pd
|
|
87
|
+
|
|
88
|
+
# Load your dataset
|
|
89
|
+
data = pd.read_csv("persian_reviews.csv")
|
|
90
|
+
texts = data['text'].tolist()
|
|
91
|
+
labels = data['label'].values # 0: not_recommended, 1: recommended, 2: no_idea
|
|
92
|
+
|
|
93
|
+
# Initialize analyzer
|
|
94
|
+
analyzer = SentimentAnalyzer()
|
|
95
|
+
|
|
96
|
+
# Preprocess and tokenize texts
|
|
97
|
+
tokenized_texts = [analyzer.preprocessor.preprocess_text(text) for text in texts]
|
|
98
|
+
|
|
99
|
+
# Train Word2Vec model
|
|
100
|
+
analyzer.train_word2vec(tokenized_texts, vector_size=100)
|
|
101
|
+
|
|
102
|
+
# Prepare feature vectors
|
|
103
|
+
X = np.array([analyzer.sentence_vector(tokens) for tokens in tokenized_texts])
|
|
104
|
+
|
|
105
|
+
# Train classifier
|
|
106
|
+
analyzer.train_classifier(X, labels)
|
|
107
|
+
|
|
108
|
+
# Save the trained model
|
|
109
|
+
analyzer.save_model("my_persian_model")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Batch Processing
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
from persian_sentiment_analyzer import predict_sentiments_for_file
|
|
116
|
+
|
|
117
|
+
# Process a CSV file containing Persian comments
|
|
118
|
+
results_summary = predict_sentiments_for_file(
|
|
119
|
+
analyzer,
|
|
120
|
+
input_file="comments.csv",
|
|
121
|
+
output_file="results.csv",
|
|
122
|
+
summary_file="summary.csv"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
print(results_summary)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Model Architecture
|
|
129
|
+
1- Text Preprocessing:
|
|
130
|
+
|
|
131
|
+
- Normalization (Hazm)
|
|
132
|
+
|
|
133
|
+
- Tokenization
|
|
134
|
+
|
|
135
|
+
- Stemming
|
|
136
|
+
|
|
137
|
+
- Stopword removal
|
|
138
|
+
|
|
139
|
+
2- Feature Extraction:
|
|
140
|
+
|
|
141
|
+
- Word2Vec embeddings (100 dimensions)
|
|
142
|
+
|
|
143
|
+
- Sentence vectors (average of word vectors)
|
|
144
|
+
|
|
145
|
+
3- Classification:
|
|
146
|
+
|
|
147
|
+
- Logistic Regression with L2 regularization
|
|
148
|
+
|
|
149
|
+
## Performance
|
|
150
|
+
The pre-trained model achieves the following performance on our test set:
|
|
151
|
+
|
|
152
|
+
Metric Value
|
|
153
|
+
Accuracy 85.2%
|
|
154
|
+
Precision 84.7%
|
|
155
|
+
Recall 85.0%
|
|
156
|
+
F1-score 84.8%
|
|
157
|
+
|
|
158
|
+
License
|
|
159
|
+
This project is licensed under the MIT [License](https://github.com/RezaGooner/Sentiment-Survey-Analyzer/blob/main/LICENSE) - see the LICENSE file for details
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
> Github : RezaGooner
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE.txt
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
PerSent/__init__.py
|
|
5
|
+
PerSent/analyzer.py
|
|
6
|
+
PerSent.egg-info/PKG-INFO
|
|
7
|
+
PerSent.egg-info/SOURCES.txt
|
|
8
|
+
PerSent.egg-info/dependency_links.txt
|
|
9
|
+
PerSent.egg-info/requires.txt
|
|
10
|
+
PerSent.egg-info/top_level.txt
|
|
11
|
+
tests/test_basic.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PerSent
|
persent-0.1.0/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Persian Sentiment Analyzer
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
A Python library for sentiment analysis of Persian (Farsi) text, capable of classifying opinions as "recommended", "not_recommended", or "no_idea".
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Text Preprocessing**: Normalization, tokenization, stemming, and stopword removal for Persian text
|
|
11
|
+
- **Word Embeddings**: Built-in Word2Vec implementation for Persian language
|
|
12
|
+
- **Sentiment Classification**: Logistic Regression classifier trained on Persian sentiment data
|
|
13
|
+
- **Model Persistence**: Save and load trained models for future use
|
|
14
|
+
- **Batch Processing**: Analyze sentiment for multiple texts at once
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install persian-sentiment-analyzer
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Dependencies
|
|
23
|
+
- Python 3.6+
|
|
24
|
+
|
|
25
|
+
- hazm
|
|
26
|
+
|
|
27
|
+
- gensim
|
|
28
|
+
|
|
29
|
+
- scikit-learn
|
|
30
|
+
|
|
31
|
+
- numpy
|
|
32
|
+
|
|
33
|
+
- pandas
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Basic Usage
|
|
38
|
+
|
|
39
|
+
``` bash
|
|
40
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
41
|
+
|
|
42
|
+
# Initialize with a pre-trained model
|
|
43
|
+
analyzer = SentimentAnalyzer(model_path="path/to/pretrained_model")
|
|
44
|
+
|
|
45
|
+
# Predict sentiment
|
|
46
|
+
result = analyzer.predict("این محصول بسیار عالی است")
|
|
47
|
+
print(result) # Output: 'recommended'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Training Your Own Model
|
|
51
|
+
|
|
52
|
+
``` bash
|
|
53
|
+
from persian_sentiment_analyzer import SentimentAnalyzer
|
|
54
|
+
import pandas as pd
|
|
55
|
+
|
|
56
|
+
# Load your dataset
|
|
57
|
+
data = pd.read_csv("persian_reviews.csv")
|
|
58
|
+
texts = data['text'].tolist()
|
|
59
|
+
labels = data['label'].values # 0: not_recommended, 1: recommended, 2: no_idea
|
|
60
|
+
|
|
61
|
+
# Initialize analyzer
|
|
62
|
+
analyzer = SentimentAnalyzer()
|
|
63
|
+
|
|
64
|
+
# Preprocess and tokenize texts
|
|
65
|
+
tokenized_texts = [analyzer.preprocessor.preprocess_text(text) for text in texts]
|
|
66
|
+
|
|
67
|
+
# Train Word2Vec model
|
|
68
|
+
analyzer.train_word2vec(tokenized_texts, vector_size=100)
|
|
69
|
+
|
|
70
|
+
# Prepare feature vectors
|
|
71
|
+
X = np.array([analyzer.sentence_vector(tokens) for tokens in tokenized_texts])
|
|
72
|
+
|
|
73
|
+
# Train classifier
|
|
74
|
+
analyzer.train_classifier(X, labels)
|
|
75
|
+
|
|
76
|
+
# Save the trained model
|
|
77
|
+
analyzer.save_model("my_persian_model")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Batch Processing
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
from persian_sentiment_analyzer import predict_sentiments_for_file
|
|
84
|
+
|
|
85
|
+
# Process a CSV file containing Persian comments
|
|
86
|
+
results_summary = predict_sentiments_for_file(
|
|
87
|
+
analyzer,
|
|
88
|
+
input_file="comments.csv",
|
|
89
|
+
output_file="results.csv",
|
|
90
|
+
summary_file="summary.csv"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
print(results_summary)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Model Architecture
|
|
97
|
+
1- Text Preprocessing:
|
|
98
|
+
|
|
99
|
+
- Normalization (Hazm)
|
|
100
|
+
|
|
101
|
+
- Tokenization
|
|
102
|
+
|
|
103
|
+
- Stemming
|
|
104
|
+
|
|
105
|
+
- Stopword removal
|
|
106
|
+
|
|
107
|
+
2- Feature Extraction:
|
|
108
|
+
|
|
109
|
+
- Word2Vec embeddings (100 dimensions)
|
|
110
|
+
|
|
111
|
+
- Sentence vectors (average of word vectors)
|
|
112
|
+
|
|
113
|
+
3- Classification:
|
|
114
|
+
|
|
115
|
+
- Logistic Regression with L2 regularization
|
|
116
|
+
|
|
117
|
+
## Performance
|
|
118
|
+
The pre-trained model achieves the following performance on our test set:
|
|
119
|
+
|
|
120
|
+
Metric Value
|
|
121
|
+
Accuracy 85.2%
|
|
122
|
+
Precision 84.7%
|
|
123
|
+
Recall 85.0%
|
|
124
|
+
F1-score 84.8%
|
|
125
|
+
|
|
126
|
+
License
|
|
127
|
+
This project is licensed under the MIT [License](https://github.com/RezaGooner/Sentiment-Survey-Analyzer/blob/main/LICENSE) - see the LICENSE file for details
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
> Github : RezaGooner
|
persent-0.1.0/setup.cfg
ADDED
persent-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="PerSent",
|
|
8
|
+
version="0.1.0",
|
|
9
|
+
author="RezaGooner",
|
|
10
|
+
author_email="RezaAsadiProgrammer@Gmail.com",
|
|
11
|
+
description="Persian Sentiment Analysis Toolkit",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/RezaGooner/PerSent",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
package_data={
|
|
17
|
+
'persian_sentiment': ['model/*']
|
|
18
|
+
},
|
|
19
|
+
install_requires=[
|
|
20
|
+
'hazm>=0.7.0',
|
|
21
|
+
'gensim>=4.0.0',
|
|
22
|
+
'scikit-learn>=1.0.0',
|
|
23
|
+
'pandas>=1.3.0',
|
|
24
|
+
'tqdm>=4.62.0',
|
|
25
|
+
'joblib>=1.1.0'
|
|
26
|
+
],
|
|
27
|
+
classifiers=[
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"License :: OSI Approved :: MIT License",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
],
|
|
32
|
+
python_requires='>=3.8',
|
|
33
|
+
keywords='persian sentiment analysis nlp',
|
|
34
|
+
)
|
|
File without changes
|