stuzha 0.1.2__py3-none-any.whl
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.
- stuzha/AMT.py +1019 -0
- stuzha/AoA.py +919 -0
- stuzha/CIS.py +1511 -0
- stuzha/ML.py +1513 -0
- stuzha/__init__.py +4 -0
- stuzha-0.1.2.dist-info/METADATA +3 -0
- stuzha-0.1.2.dist-info/RECORD +10 -0
- stuzha-0.1.2.dist-info/WHEEL +5 -0
- stuzha-0.1.2.dist-info/entry_points.txt +39 -0
- stuzha-0.1.2.dist-info/top_level.txt +1 -0
stuzha/AMT.py
ADDED
|
@@ -0,0 +1,1019 @@
|
|
|
1
|
+
def amt_1():
|
|
2
|
+
print('''
|
|
3
|
+
|
|
4
|
+
#Data Preprocessing
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
df = pd.read_csv('data.csv')
|
|
9
|
+
|
|
10
|
+
#Dropping the irrelevant columns
|
|
11
|
+
columns_to_drop = [
|
|
12
|
+
'col_name',
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
df = df.drop(columns=columns_to_drop)
|
|
16
|
+
print(df.columns)
|
|
17
|
+
|
|
18
|
+
#Checking the null values and removing them
|
|
19
|
+
print(df.isnull().sum())
|
|
20
|
+
df = df[df['comment_text'].notna()]
|
|
21
|
+
df = df[df['language'].notna()]
|
|
22
|
+
print(df.isnull().sum())
|
|
23
|
+
|
|
24
|
+
#Box plot to check for outliers
|
|
25
|
+
import matplotlib.pyplot as plt
|
|
26
|
+
|
|
27
|
+
plt.figure(figsize=(8, 4))
|
|
28
|
+
plt.boxplot(df['like_count'], vert=False)
|
|
29
|
+
plt.title('Boxplot of Like Count')
|
|
30
|
+
plt.xlabel('Like Count')
|
|
31
|
+
plt.grid(True)
|
|
32
|
+
plt.show()
|
|
33
|
+
|
|
34
|
+
plt.figure(figsize=(8, 4))
|
|
35
|
+
plt.boxplot(df['like_count'], vert=False)
|
|
36
|
+
plt.title('Boxplot of Reply Count')
|
|
37
|
+
plt.xlabel('Reply Count')
|
|
38
|
+
plt.grid(True)
|
|
39
|
+
plt.show()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
#Removing the outliers
|
|
43
|
+
df = df[df['like_count'] <= 5000]
|
|
44
|
+
df = df[df['reply_count'] <= 500]
|
|
45
|
+
print("Remaining rows:", df.shape[0])
|
|
46
|
+
|
|
47
|
+
#Filtering and removing the values other than spam and not spam
|
|
48
|
+
df = df[df['label_spam'].isin(['spam', 'not spam'])]
|
|
49
|
+
df['spam_label'] = df['label_spam'].map({'not spam': 0, 'spam': 1})
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
heatmap_data = df[['like_count', 'reply_count', 'spam_label']]
|
|
53
|
+
|
|
54
|
+
correlation = heatmap_data.corr()
|
|
55
|
+
|
|
56
|
+
plt.figure(figsize=(6, 4))
|
|
57
|
+
plt.imshow(correlation, cmap='coolwarm')
|
|
58
|
+
plt.colorbar()
|
|
59
|
+
|
|
60
|
+
plt.xticks(range(len(correlation.columns)), correlation.columns)
|
|
61
|
+
plt.yticks(range(len(correlation.columns)), correlation.columns)
|
|
62
|
+
|
|
63
|
+
plt.title("Correlation Heatmap")
|
|
64
|
+
plt.tight_layout()
|
|
65
|
+
plt.show()
|
|
66
|
+
|
|
67
|
+
''')
|
|
68
|
+
|
|
69
|
+
def amt_2():
|
|
70
|
+
print('''
|
|
71
|
+
|
|
72
|
+
#EDA
|
|
73
|
+
|
|
74
|
+
import pandas as pd
|
|
75
|
+
import numpy as np
|
|
76
|
+
import seaborn as sns
|
|
77
|
+
import matplotlib.pyplot as plt
|
|
78
|
+
import plotly.express as px
|
|
79
|
+
import numpy as np
|
|
80
|
+
import re
|
|
81
|
+
|
|
82
|
+
df = pd.read_csv('anime_data.csv')
|
|
83
|
+
|
|
84
|
+
#Clean airing date, duration and demographic
|
|
85
|
+
df['Aired_from'] = df['Aired'].str.extract(r'^(.*) to')[0]
|
|
86
|
+
df['Aired_from'] = pd.to_datetime(df['Aired_from'])
|
|
87
|
+
|
|
88
|
+
df['Duration_min'] = df['Duration'].str.extract(r'(\d+)').astype(float)
|
|
89
|
+
|
|
90
|
+
df['Demographic'] = df['Demographic'].str.replace(r'(\w+)\1', r'\1', regex=True)
|
|
91
|
+
|
|
92
|
+
# Extract broadcast day
|
|
93
|
+
df['Broadcast_Day'] = df['Broadcast'].str.extract(r'(\w+days?)')
|
|
94
|
+
# Extract time (e.g., "23:00")
|
|
95
|
+
df['Broadcast_Time'] = df['Broadcast'].str.extract(r'(\d{2}:\d{2})')
|
|
96
|
+
|
|
97
|
+
# Fix repeated genre words
|
|
98
|
+
def clean_genres(text):
|
|
99
|
+
if pd.isna(text):
|
|
100
|
+
return text
|
|
101
|
+
return re.sub(r'(\w+)\1', r'\1', text)
|
|
102
|
+
|
|
103
|
+
# Apply the function to the 'Genres' column
|
|
104
|
+
df['Genres'] = df['Genres'].apply(clean_genres)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
df['Genres'] = df['Genres'].str.split(', ')
|
|
108
|
+
df['Producers'] = df['Producers'].str.split(', ')
|
|
109
|
+
df['Studios'] = df['Studios'].str.split(', ')
|
|
110
|
+
|
|
111
|
+
df['Rating'] = df['Rating'].str.extract(r'^(.*?)(?:\s*-|$)')[0].str.strip()
|
|
112
|
+
|
|
113
|
+
df = df[df['Episodes'] != 'Unknown']
|
|
114
|
+
df['Episodes'] = df['Episodes'].astype(int)
|
|
115
|
+
|
|
116
|
+
columns_to_drop = ['Column Name', ]
|
|
117
|
+
df = df.drop(columns=columns_to_drop)
|
|
118
|
+
|
|
119
|
+
df.head()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
#Mean, Median & Mode:
|
|
123
|
+
columns_to_analyze = ['Score', 'Rank', 'Episodes', "Duration_min"]
|
|
124
|
+
desc_stats = df[columns_to_analyze].agg(['mean', 'median'])
|
|
125
|
+
mode_stats = df[columns_to_analyze].mode().iloc[0]
|
|
126
|
+
|
|
127
|
+
print(desc_stats)
|
|
128
|
+
print(mode_stats)
|
|
129
|
+
|
|
130
|
+
for col in columns_to_analyze:
|
|
131
|
+
|
|
132
|
+
mean = df[col].mean()
|
|
133
|
+
median = df[col].median()
|
|
134
|
+
if abs(mean - median) < 1:
|
|
135
|
+
print(f"{col}: Symmetric (mean ≈ median)")
|
|
136
|
+
elif mean > median:
|
|
137
|
+
print(f"{col}: Right-skewed (mean > median)")
|
|
138
|
+
else:
|
|
139
|
+
print(f"{col}: Left-skewed (mean < median)")
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
#Bar & Stacked Bar Plot:
|
|
143
|
+
|
|
144
|
+
sns.countplot(x='Type', data=df)
|
|
145
|
+
plt.title("Anime Count by Type")
|
|
146
|
+
plt.show()
|
|
147
|
+
|
|
148
|
+
pd.crosstab(df['Demographic'], df['Rating']).plot(kind='bar', stacked=True)
|
|
149
|
+
plt.title("Stacked Bar: Demographic vs Rating")
|
|
150
|
+
plt.ylabel("Count")
|
|
151
|
+
plt.show()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
#Histogram
|
|
155
|
+
|
|
156
|
+
# plt.figure(figsize=(30, 15))
|
|
157
|
+
sns.histplot(df['Type'], bins=20 )
|
|
158
|
+
plt.title("Distribution of Episodes")
|
|
159
|
+
plt.show()
|
|
160
|
+
|
|
161
|
+
#Scatter Plot
|
|
162
|
+
|
|
163
|
+
sns.scatterplot(x='Score', y='Popularity', hue='Type', data=df)
|
|
164
|
+
plt.title("Score vs Popularity by Type")
|
|
165
|
+
plt.show()
|
|
166
|
+
|
|
167
|
+
#Boxplot
|
|
168
|
+
|
|
169
|
+
sns.boxplot(x='Broadcast_Day', y='Score', data=df)
|
|
170
|
+
plt.title("Score by Broadcast Day")
|
|
171
|
+
plt.show()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
#Line Chart
|
|
175
|
+
|
|
176
|
+
df['Year'] = pd.to_datetime(df['Aired_from']).dt.year
|
|
177
|
+
df['Year'].value_counts().sort_index().plot(kind='line')
|
|
178
|
+
plt.title("Anime Releases Over Time")
|
|
179
|
+
plt.xlabel("Year")
|
|
180
|
+
plt.ylabel("Number of Anime")
|
|
181
|
+
plt.show()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
#Violin
|
|
185
|
+
|
|
186
|
+
sns.violinplot(x='Rating', y='Episodes', data=df)
|
|
187
|
+
plt.title("Episodes by Rating")
|
|
188
|
+
plt.show()
|
|
189
|
+
|
|
190
|
+
#Swarm
|
|
191
|
+
|
|
192
|
+
sns.swarmplot(x='Type', y='Score', data=df)
|
|
193
|
+
plt.title("Score Distribution by Type")
|
|
194
|
+
plt.show()
|
|
195
|
+
|
|
196
|
+
#Donut
|
|
197
|
+
|
|
198
|
+
source_counts = df['Source'].value_counts()
|
|
199
|
+
plt.pie(source_counts, labels=source_counts.index, autopct='%1.1f%%', startangle=140, wedgeprops={'width':0.4})
|
|
200
|
+
plt.title("Donut Chart: Anime by Source")
|
|
201
|
+
plt.show()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
#3D Scatter Plot
|
|
205
|
+
|
|
206
|
+
fig = plt.figure()
|
|
207
|
+
ax = fig.add_subplot(111, projection='3d')
|
|
208
|
+
ax.scatter(df['Score'], df['Popularity'], df['Rank'], c='skyblue', s=50)
|
|
209
|
+
ax.set_xlabel('Score')
|
|
210
|
+
ax.set_ylabel('Popularity')
|
|
211
|
+
ax.set_zlabel('Episodes')
|
|
212
|
+
plt.title("3D Scatter: Score vs Popularity vs Episodes")
|
|
213
|
+
plt.show()
|
|
214
|
+
|
|
215
|
+
#Heatmap
|
|
216
|
+
|
|
217
|
+
num_cols = ['Score', 'Popularity', 'Rank', 'Episodes', 'Duration_min']
|
|
218
|
+
corr = df[num_cols].corr()
|
|
219
|
+
sns.heatmap(corr, annot=True, cmap='coolwarm')
|
|
220
|
+
plt.title("Correlation Heatmap")
|
|
221
|
+
plt.show()
|
|
222
|
+
|
|
223
|
+
''')
|
|
224
|
+
|
|
225
|
+
def amt_3():
|
|
226
|
+
print('''
|
|
227
|
+
|
|
228
|
+
#Classification
|
|
229
|
+
|
|
230
|
+
# Create correlation heatmap
|
|
231
|
+
heatmap_features = ['scaled_reviews_like_rate', 'scaled_all_reviews_number', 'scaled_price', 'scaled_difficulty', 'scaled_length', 'high_rated']
|
|
232
|
+
heatmap_data = df[heatmap_features]
|
|
233
|
+
correlation = heatmap_data.corr()
|
|
234
|
+
|
|
235
|
+
plt.figure(figsize=(8, 6))
|
|
236
|
+
plt.imshow(correlation, cmap='coolwarm', vmin=-1, vmax=1)
|
|
237
|
+
plt.colorbar()
|
|
238
|
+
|
|
239
|
+
plt.xticks(range(len(correlation.columns)), correlation.columns, rotation=45)
|
|
240
|
+
plt.yticks(range(len(correlation.columns)), correlation.columns)
|
|
241
|
+
|
|
242
|
+
plt.title("Correlation Heatmap")
|
|
243
|
+
plt.tight_layout()
|
|
244
|
+
plt.show()
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
#Train test split
|
|
249
|
+
|
|
250
|
+
from sklearn.model_selection import train_test_split
|
|
251
|
+
from sklearn.metrics import classification_report
|
|
252
|
+
|
|
253
|
+
X = df[['scaled_reviews_like_rate', 'scaled_all_reviews_number', 'scaled_price', 'scaled_difficulty', 'scaled_length', 'scaled_estimated_downloads', 'age_restriction']]
|
|
254
|
+
y = df['high_rated']
|
|
255
|
+
|
|
256
|
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
#Logistic Regression
|
|
261
|
+
|
|
262
|
+
from sklearn.linear_model import LogisticRegression
|
|
263
|
+
|
|
264
|
+
model = LogisticRegression(max_iter=1000)
|
|
265
|
+
model.fit(X_train, y_train)
|
|
266
|
+
|
|
267
|
+
y_pred = model.predict(X_test)
|
|
268
|
+
|
|
269
|
+
print("\nLogistic Regression Classification Report:")
|
|
270
|
+
print(classification_report(y_test, y_pred))
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
#Decision Tree
|
|
274
|
+
|
|
275
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
276
|
+
|
|
277
|
+
# Apply Decision Tree model
|
|
278
|
+
dt_model = DecisionTreeClassifier(random_state=42)
|
|
279
|
+
dt_model.fit(X_train, y_train)
|
|
280
|
+
|
|
281
|
+
y_pred = dt_model.predict(X_test)
|
|
282
|
+
|
|
283
|
+
print("\nDecision Tree Classification Report:")
|
|
284
|
+
print(classification_report(y_test, y_pred))
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
#Gaussian Naive Bayes
|
|
290
|
+
|
|
291
|
+
from sklearn.naive_bayes import GaussianNB
|
|
292
|
+
from sklearn.metrics import classification_report
|
|
293
|
+
|
|
294
|
+
# Apply Gaussian Naive Bayes model
|
|
295
|
+
nb_model = GaussianNB()
|
|
296
|
+
nb_model.fit(X_train, y_train)
|
|
297
|
+
|
|
298
|
+
y_pred = nb_model.predict(X_test)
|
|
299
|
+
|
|
300
|
+
print("\nNaive Bayes (Gaussian) Classification Report:")
|
|
301
|
+
print(classification_report(y_test, y_pred))
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
#SVC
|
|
307
|
+
|
|
308
|
+
from sklearn.svm import SVC
|
|
309
|
+
from sklearn.metrics import classification_report
|
|
310
|
+
|
|
311
|
+
# Apply Support Vector Classifier model
|
|
312
|
+
svc_model = SVC(kernel='linear', random_state=42)
|
|
313
|
+
svc_model.fit(X_train, y_train)
|
|
314
|
+
|
|
315
|
+
y_pred = svc_model.predict(X_test)
|
|
316
|
+
|
|
317
|
+
print("\nSupport Vector Classifier Report:")
|
|
318
|
+
print(classification_report(y_test, y_pred))
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
#Random Forest
|
|
324
|
+
|
|
325
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
326
|
+
|
|
327
|
+
# Apply Random Forest model
|
|
328
|
+
rf_model = RandomForestClassifier(random_state=42)
|
|
329
|
+
rf_model.fit(X_train, y_train)
|
|
330
|
+
|
|
331
|
+
y_pred = rf_model.predict(X_test)
|
|
332
|
+
|
|
333
|
+
print("\nRandom Forest Classification Report:")
|
|
334
|
+
print(classification_report(y_test, y_pred))
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
#PCA
|
|
340
|
+
|
|
341
|
+
from sklearn.decomposition import PCA
|
|
342
|
+
from sklearn.metrics import classification_report
|
|
343
|
+
|
|
344
|
+
pca = PCA(n_components=5)
|
|
345
|
+
X_train_pca = pca.fit_transform(X_train)
|
|
346
|
+
X_test_pca = pca.transform(X_test)
|
|
347
|
+
|
|
348
|
+
pca_model = LogisticRegression(random_state=42)
|
|
349
|
+
pca_model.fit(X_train_pca, y_train)
|
|
350
|
+
|
|
351
|
+
y_pred = pca_model.predict(X_test_pca)
|
|
352
|
+
|
|
353
|
+
print(classification_report(y_test, y_pred))
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
#ROC Curve
|
|
359
|
+
|
|
360
|
+
from sklearn.metrics import roc_curve, roc_auc_score
|
|
361
|
+
import matplotlib.pyplot as plt
|
|
362
|
+
|
|
363
|
+
# Apply Logistic Regression for ROC analysis
|
|
364
|
+
roc_model = LogisticRegression(random_state=42)
|
|
365
|
+
roc_model.fit(X_train, y_train)
|
|
366
|
+
y_pred_proba = roc_model.predict_proba(X_test)[:, 1]
|
|
367
|
+
|
|
368
|
+
# Calculate ROC curve
|
|
369
|
+
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
|
|
370
|
+
auc_score = roc_auc_score(y_test, y_pred_proba)
|
|
371
|
+
|
|
372
|
+
# Plot ROC curve
|
|
373
|
+
plt.figure(figsize=(8, 6))
|
|
374
|
+
plt.plot(fpr, tpr)
|
|
375
|
+
plt.plot([0, 1], [0, 1], 'k--', label='Random')
|
|
376
|
+
plt.xlabel('False Positive Rate')
|
|
377
|
+
plt.ylabel('True Positive Rate')
|
|
378
|
+
plt.title('ROC Curve')
|
|
379
|
+
plt.grid(True)
|
|
380
|
+
plt.show()
|
|
381
|
+
|
|
382
|
+
print(f"\nROC AUC Score: {auc_score:.3f}")
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
#Bagging
|
|
388
|
+
|
|
389
|
+
from sklearn.ensemble import BaggingClassifier
|
|
390
|
+
from sklearn.metrics import classification_report
|
|
391
|
+
|
|
392
|
+
# Apply Bagging Classifier
|
|
393
|
+
bagging_model = BaggingClassifier(random_state=42, n_estimators=100)
|
|
394
|
+
bagging_model.fit(X_train, y_train)
|
|
395
|
+
|
|
396
|
+
y_pred = bagging_model.predict(X_test)
|
|
397
|
+
|
|
398
|
+
print("\nBagging Classifier Classification Report:")
|
|
399
|
+
print(classification_report(y_test, y_pred))
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
#Boosting - Ada boosting and Gradient Boosting
|
|
405
|
+
|
|
406
|
+
from sklearn.ensemble import AdaBoostClassifier
|
|
407
|
+
from sklearn.metrics import classification_report
|
|
408
|
+
|
|
409
|
+
# Apply AdaBoost Classifier
|
|
410
|
+
boosting_model = AdaBoostClassifier(random_state=42, n_estimators=100)
|
|
411
|
+
boosting_model.fit(X_train, y_train)
|
|
412
|
+
|
|
413
|
+
y_pred = boosting_model.predict(X_test)
|
|
414
|
+
|
|
415
|
+
print("\nAdaBoost (Boosting) Classification Report:")
|
|
416
|
+
print(classification_report(y_test, y_pred))
|
|
417
|
+
|
|
418
|
+
from sklearn.ensemble import GradientBoostingClassifier
|
|
419
|
+
from sklearn.metrics import classification_report
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# Apply Gradient Boosting Classifier
|
|
423
|
+
boosting_model = GradientBoostingClassifier(random_state=42, n_estimators=100)
|
|
424
|
+
boosting_model.fit(X_train, y_train)
|
|
425
|
+
|
|
426
|
+
y_pred = boosting_model.predict(X_test)
|
|
427
|
+
|
|
428
|
+
print("\nGradient Boosting (Boosting) Classification Report:")
|
|
429
|
+
print(classification_report(y_test, y_pred))
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
#Cross Validation - Random Forest
|
|
434
|
+
|
|
435
|
+
from sklearn.model_selection import cross_val_score
|
|
436
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
437
|
+
from sklearn.metrics import classification_report
|
|
438
|
+
|
|
439
|
+
# Apply Cross Validation with Random Forest
|
|
440
|
+
cv_model = RandomForestClassifier(random_state=42)
|
|
441
|
+
|
|
442
|
+
# Perform 5-fold cross validation
|
|
443
|
+
cv_scores = cross_val_score(cv_model, X_train, y_train, cv=5, scoring='accuracy')
|
|
444
|
+
|
|
445
|
+
cv_model.fit(X_train, y_train)
|
|
446
|
+
y_pred = cv_model.predict(X_test)
|
|
447
|
+
|
|
448
|
+
print(f"{cv_scores}")
|
|
449
|
+
print(classification_report(y_test, y_pred))
|
|
450
|
+
|
|
451
|
+
''')
|
|
452
|
+
|
|
453
|
+
def amt_4():
|
|
454
|
+
print('''
|
|
455
|
+
|
|
456
|
+
#Clustering
|
|
457
|
+
|
|
458
|
+
import pandas as pd
|
|
459
|
+
import numpy as np
|
|
460
|
+
import matplotlib.pyplot as plt
|
|
461
|
+
from sklearn.cluster import KMeans, AgglomerativeClustering
|
|
462
|
+
from sklearn.metrics import silhouette_score
|
|
463
|
+
from sklearn.preprocessing import StandardScaler
|
|
464
|
+
from sklearn.decomposition import PCA
|
|
465
|
+
|
|
466
|
+
# Load the dataset
|
|
467
|
+
anime_data = pd.read_csv("anime_data.csv")
|
|
468
|
+
|
|
469
|
+
# Explore the dataset
|
|
470
|
+
print(anime_data.describe())
|
|
471
|
+
print(anime_data.columns)
|
|
472
|
+
|
|
473
|
+
# Prepare data for clustering
|
|
474
|
+
numerical_cols = ['Score', 'Episodes', 'Duration_min',]
|
|
475
|
+
|
|
476
|
+
anime_data_copy = anime_data.copy()
|
|
477
|
+
anime_data_copy['Episodes'] = pd.to_numeric(anime_data_copy['Episodes'], errors='coerce')
|
|
478
|
+
anime_data_copy['Duration_min'] = anime_data_copy['Duration'].str.extract(r'(\d+)').astype(float)
|
|
479
|
+
|
|
480
|
+
new_data = anime_data_copy[numerical_cols].dropna()
|
|
481
|
+
|
|
482
|
+
print(new_data.head())
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
#K-Means
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
# K-Means clustering
|
|
491
|
+
|
|
492
|
+
kmeans = KMeans(n_clusters=4, random_state=42)
|
|
493
|
+
kmeans.fit(new_data)
|
|
494
|
+
|
|
495
|
+
# Add cluster labels to the cleaned data
|
|
496
|
+
new_data_with_clusters = new_data.copy()
|
|
497
|
+
new_data_with_clusters['kmeans_cluster'] = kmeans.labels_
|
|
498
|
+
print("Number of data points:", len(new_data_with_clusters))
|
|
499
|
+
|
|
500
|
+
# Elbow method to find optimal k
|
|
501
|
+
wss = []
|
|
502
|
+
for k in range(1, 16):
|
|
503
|
+
kmeans = KMeans(n_clusters=k, random_state=42)
|
|
504
|
+
kmeans.fit(new_data)
|
|
505
|
+
wss.append(kmeans.inertia_)
|
|
506
|
+
|
|
507
|
+
plt.plot(range(1, 16), wss, marker='o')
|
|
508
|
+
plt.xlabel('Number of clusters k')
|
|
509
|
+
plt.ylabel('Total within-clusters sum of square')
|
|
510
|
+
plt.show()
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
# Standardize the data
|
|
515
|
+
scaler = StandardScaler()
|
|
516
|
+
X_std = scaler.fit_transform(new_data)
|
|
517
|
+
|
|
518
|
+
# Reduce dimensions for visualization
|
|
519
|
+
pca = PCA(n_components=2)
|
|
520
|
+
X_pca = pca.fit_transform(X_std)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
# Visualize the clusters
|
|
524
|
+
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=kmeans.labels_, cmap='viridis')
|
|
525
|
+
plt.title('K-means Clustering')
|
|
526
|
+
plt.xlabel('Principal Component 1')
|
|
527
|
+
plt.ylabel('Principal Component 2')
|
|
528
|
+
plt.show()
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
#Agglomerative Clustering
|
|
532
|
+
|
|
533
|
+
agglomerative = AgglomerativeClustering(n_clusters=3)
|
|
534
|
+
hierarchical_labels = agglomerative.fit_predict(new_data)
|
|
535
|
+
|
|
536
|
+
# Add hierarchical cluster labels to the data
|
|
537
|
+
new_data_with_clusters['hierarchical_cluster'] = hierarchical_labels
|
|
538
|
+
|
|
539
|
+
# Visualize Hierarchical clusters using PCA-reduced data
|
|
540
|
+
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=hierarchical_labels, cmap='viridis', alpha=0.6, s=50)
|
|
541
|
+
plt.xlabel('Principal Component 1')
|
|
542
|
+
plt.ylabel('Principal Component 2')
|
|
543
|
+
plt.title('Hierarchical Clustering')
|
|
544
|
+
plt.show()
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
silhoutte_avg = silhouette_score(new_data, hierarchical_labels)
|
|
549
|
+
print(f'Silhouette Score for Hierarchical Clustering: {silhoutte_avg}
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
#DBSCAN CLustering
|
|
555
|
+
|
|
556
|
+
from sklearn.cluster import DBSCAN
|
|
557
|
+
|
|
558
|
+
dbscan = DBSCAN(eps=1.5, min_samples=5)
|
|
559
|
+
dbscan_labels = dbscan.fit_predict(new_data)
|
|
560
|
+
|
|
561
|
+
new_data_with_clusters['dbscan_cluster'] = dbscan_labels
|
|
562
|
+
|
|
563
|
+
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=dbscan_labels, cmap='coolwarm', alpha=0.6, s=50)
|
|
564
|
+
plt.xlabel('Principal Component 1')
|
|
565
|
+
plt.ylabel('Principal Component 2')
|
|
566
|
+
plt.title('DBSCAN Clustering')
|
|
567
|
+
plt.show()
|
|
568
|
+
|
|
569
|
+
silhouette_avg_dbscan = silhouette_score(new_data, dbscan_labels)
|
|
570
|
+
print("Mean Silhouette Width for DBSCAN Clustering:", silhouette_avg_dbscan)
|
|
571
|
+
''')
|
|
572
|
+
|
|
573
|
+
def amt_5():
|
|
574
|
+
print('''
|
|
575
|
+
|
|
576
|
+
#CURE Clustering
|
|
577
|
+
|
|
578
|
+
import pandas as pd
|
|
579
|
+
from pyclustering.cluster.cure import cure
|
|
580
|
+
from sklearn.decomposition import PCA
|
|
581
|
+
import matplotlib.pyplot as plt
|
|
582
|
+
import numpy as np
|
|
583
|
+
|
|
584
|
+
url = "https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv"
|
|
585
|
+
df = pd.read_csv(url)
|
|
586
|
+
|
|
587
|
+
df = df.drop(["species"], axis=1)
|
|
588
|
+
df = df.drop_duplicates()
|
|
589
|
+
|
|
590
|
+
print(df.head())
|
|
591
|
+
|
|
592
|
+
data = df.values.tolist()
|
|
593
|
+
cure_instance = cure(data, 3)
|
|
594
|
+
cure_instance.process()
|
|
595
|
+
|
|
596
|
+
clusters = cure_instance.get_clusters()
|
|
597
|
+
cluster_labels = np.full(len(data), fill_value=-1, dtype=int)
|
|
598
|
+
for cluster_id, cluster in enumerate(clusters):
|
|
599
|
+
cluster_labels[cluster] = cluster_id
|
|
600
|
+
|
|
601
|
+
pca = PCA(n_components=2)
|
|
602
|
+
reduced_data = pca.fit_transform(df)
|
|
603
|
+
|
|
604
|
+
plt.figure(figsize=(7.5, 5))
|
|
605
|
+
scatter = plt.scatter(reduced_data[:, 0], reduced_data[:, 1], c=cluster_labels)
|
|
606
|
+
plt.xlabel('Petal length, Petal width')
|
|
607
|
+
plt.ylabel('Sepal length, Sepal width')
|
|
608
|
+
plt.title('Cure Clustering on Iris Dataset')
|
|
609
|
+
plt.show()
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
#Scatter Plot
|
|
614
|
+
|
|
615
|
+
import pandas as pd
|
|
616
|
+
from pyclustering.cluster.cure import cure
|
|
617
|
+
from sklearn.decomposition import PCA
|
|
618
|
+
import matplotlib.pyplot as plt
|
|
619
|
+
import numpy as np
|
|
620
|
+
|
|
621
|
+
df = pd.read_csv(url)
|
|
622
|
+
|
|
623
|
+
df = df.drop(["species"], axis=1)
|
|
624
|
+
df = df.drop_duplicates()
|
|
625
|
+
|
|
626
|
+
data = df.values.tolist()
|
|
627
|
+
cure_instance = cure(data, 3)
|
|
628
|
+
cure_instance.process()
|
|
629
|
+
|
|
630
|
+
clusters = cure_instance.get_clusters()
|
|
631
|
+
cluster_labels = np.full(len(data), fill_value=-1, dtype=int)
|
|
632
|
+
for cluster_id, cluster in enumerate(clusters):
|
|
633
|
+
cluster_labels[cluster] = cluster_id
|
|
634
|
+
|
|
635
|
+
pca = PCA(n_components=2)
|
|
636
|
+
reduced_data = pca.fit_transform(df)
|
|
637
|
+
|
|
638
|
+
plt.figure(figsize=(10, 7))
|
|
639
|
+
for cluster_id in np.unique(cluster_labels):
|
|
640
|
+
plt.scatter(
|
|
641
|
+
reduced_data[cluster_labels == cluster_id, 0],
|
|
642
|
+
reduced_data[cluster_labels == cluster_id, 1],
|
|
643
|
+
label=f'Cluster {cluster_id}'
|
|
644
|
+
)
|
|
645
|
+
plt.xlabel('Principal Component 1')
|
|
646
|
+
plt.ylabel('Principal Component 2')
|
|
647
|
+
plt.title('CURE Clustering on Iris Dataset')
|
|
648
|
+
plt.legend()
|
|
649
|
+
plt.show()
|
|
650
|
+
|
|
651
|
+
''')
|
|
652
|
+
|
|
653
|
+
def amt_6():
|
|
654
|
+
print('''
|
|
655
|
+
|
|
656
|
+
#Recommendation Engine
|
|
657
|
+
|
|
658
|
+
import pandas as pd
|
|
659
|
+
from sklearn.feature_extraction.text import TfidfVectorizer
|
|
660
|
+
from sklearn.metrics.pairwise import linear_kernel
|
|
661
|
+
import ast
|
|
662
|
+
|
|
663
|
+
df = pd.read_csv("games.csv")
|
|
664
|
+
df = df.drop_duplicates(subset='Title').reset_index(drop=True)
|
|
665
|
+
|
|
666
|
+
for col in ['Genres', 'Team', 'Summary']:
|
|
667
|
+
df[col] = df[col].fillna('')
|
|
668
|
+
|
|
669
|
+
df['Genres'] = df['Genres'].apply(lambda x: ' '.join(ast.literal_eval(x)) if x.startswith('[') else x)
|
|
670
|
+
df['Team'] = df['Team'].apply(lambda x: ' '.join(ast.literal_eval(x)) if x.startswith('[') else x)
|
|
671
|
+
df['combined'] = df['Genres'] + ' ' + df['Team'] + ' ' + df['Summary']
|
|
672
|
+
|
|
673
|
+
tfidf = TfidfVectorizer(stop_words='english')
|
|
674
|
+
tfidf_matrix = tfidf.fit_transform(df['combined'])
|
|
675
|
+
|
|
676
|
+
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
|
|
677
|
+
indices = pd.Series(df.index, index=df['Title']).drop_duplicates()
|
|
678
|
+
|
|
679
|
+
def get_recommendations(title, cosine_sim=cosine_sim):
|
|
680
|
+
idx = indices.get(title)
|
|
681
|
+
if idx is None:
|
|
682
|
+
return f"Game '{title}' not found in dataset."
|
|
683
|
+
|
|
684
|
+
if isinstance(idx, pd.Series):
|
|
685
|
+
idx = idx.iloc[0]
|
|
686
|
+
|
|
687
|
+
sim_scores = list(enumerate(cosine_sim[idx]))
|
|
688
|
+
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)[1:10]
|
|
689
|
+
|
|
690
|
+
game_indices = [i for i, _ in sim_scores]
|
|
691
|
+
return df.iloc[game_indices][['Title', 'Genres', 'Team', 'Rating']]
|
|
692
|
+
|
|
693
|
+
print(get_recommendations("Need for Speed: Hot Pursuit"))
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
''')
|
|
697
|
+
|
|
698
|
+
def amt_7():
|
|
699
|
+
print('''
|
|
700
|
+
|
|
701
|
+
#Collborative Filtering
|
|
702
|
+
|
|
703
|
+
import pandas as pd
|
|
704
|
+
|
|
705
|
+
df = pd.read_csv('fashion_products.csv')
|
|
706
|
+
df.columns = df.columns.str.strip()
|
|
707
|
+
df['Product'] = df['Product Name'].str.strip() + ' - ' + df['Brand'].str.strip()
|
|
708
|
+
df_cleaned = df[['User ID', 'Product', 'Rating']]
|
|
709
|
+
|
|
710
|
+
utility_matrix = df_cleaned.pivot_table(index='User ID', columns='Product', values='Rating').fillna(0)
|
|
711
|
+
print(utility_matrix)
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
from sklearn.metrics.pairwise import cosine_similarity
|
|
715
|
+
import pandas as pd
|
|
716
|
+
|
|
717
|
+
product_similarity = cosine_similarity(utility_matrix)
|
|
718
|
+
product_similarity_df = pd.DataFrame(product_similarity, index=utility_matrix.index, columns=utility_matrix.index)
|
|
719
|
+
print(product_similarity_df.head())
|
|
720
|
+
|
|
721
|
+
def recommend_products_for_user(user_id, utility_matrix, similarity_matrix, top_n=5):
|
|
722
|
+
if user_id not in utility_matrix.index:
|
|
723
|
+
print(f"User {user_id} not found.")
|
|
724
|
+
return []
|
|
725
|
+
|
|
726
|
+
similar_users = similarity_matrix.loc[user_id].drop(user_id)
|
|
727
|
+
scores = pd.Series(0, index=utility_matrix.columns)
|
|
728
|
+
|
|
729
|
+
for other_user, similarity in similar_users.items():
|
|
730
|
+
scores += utility_matrix.loc[other_user] * similarity
|
|
731
|
+
|
|
732
|
+
total_similarity = similar_users.sum()
|
|
733
|
+
if total_similarity > 0:
|
|
734
|
+
scores /= total_similarity
|
|
735
|
+
|
|
736
|
+
rated = utility_matrix.loc[user_id]
|
|
737
|
+
scores[rated > 0] = 0
|
|
738
|
+
return scores.sort_values(ascending=False).head(top_n)
|
|
739
|
+
|
|
740
|
+
recommendations = recommend_products_for_user(1, utility_matrix, product_similarity_df, top_n=5)
|
|
741
|
+
print(recommendations)
|
|
742
|
+
|
|
743
|
+
''')
|
|
744
|
+
|
|
745
|
+
def amt_8():
|
|
746
|
+
print('''
|
|
747
|
+
|
|
748
|
+
#Apriori Association
|
|
749
|
+
|
|
750
|
+
import pandas as pd
|
|
751
|
+
import seaborn as sns
|
|
752
|
+
import matplotlib.pyplot as plt
|
|
753
|
+
|
|
754
|
+
from mlxtend.preprocessing import TransactionEncoder
|
|
755
|
+
from mlxtend.frequent_patterns import apriori, association_rules
|
|
756
|
+
from sklearn.impute import SimpleImputer
|
|
757
|
+
|
|
758
|
+
data = pd.read_csv("./groceries.csv")
|
|
759
|
+
print(data.head())
|
|
760
|
+
print(data.columns)
|
|
761
|
+
transactions = data.values.astype(str).tolist()
|
|
762
|
+
transactions = [[item for item in row if item != 'nan'] for row in transactions]
|
|
763
|
+
print(transactions[:10])
|
|
764
|
+
|
|
765
|
+
te = TransactionEncoder()
|
|
766
|
+
te_ary = te.fit(transactions).transform(transactions)
|
|
767
|
+
df = pd.DataFrame(te_ary, columns=te.columns_)
|
|
768
|
+
print(df.head(5))
|
|
769
|
+
print(df.shape)
|
|
770
|
+
frequent_itemsets = apriori(df, min_support=0.01, use_colnames=True)
|
|
771
|
+
frequent_itemsets.count()['itemsets']
|
|
772
|
+
|
|
773
|
+
plt.figure(figsize=(12,6))
|
|
774
|
+
plt.xticks(rotation=90)
|
|
775
|
+
sns.barplot(x='itemsets', y='support', data=frequent_itemsets.nlargest(n = 15, columns = 'support'))
|
|
776
|
+
plt.show()
|
|
777
|
+
|
|
778
|
+
rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1)
|
|
779
|
+
rules.sort_values(by=['support'], ascending=False)
|
|
780
|
+
print("RULES 1:\n",rules)
|
|
781
|
+
rules["antecedent_len"] = rules["antecedents"].apply(lambda x: len(x))
|
|
782
|
+
rules["consequent_len"] = rules["consequents"].apply(lambda x: len(x))
|
|
783
|
+
|
|
784
|
+
print("RULES 2:\n",rules)
|
|
785
|
+
filtered_rules = rules[rules['antecedent_len'] >= 2]
|
|
786
|
+
|
|
787
|
+
print("RULES 3:\n", filtered_rules)
|
|
788
|
+
rules[ (rules['antecedent_len'] >= 2) &
|
|
789
|
+
(rules['confidence'] > 0.3) &
|
|
790
|
+
(rules['lift'] > 1) ].sort_values(by=['lift', 'support'], ascending=False)
|
|
791
|
+
print("RULES 4:\n",rules)
|
|
792
|
+
rules[ (rules['consequent_len'] >= 2) &
|
|
793
|
+
(rules['lift'] > 1) ].sort_values(by=['lift', 'confidence'], ascending=False)
|
|
794
|
+
print("RULES 5:\n",rules)
|
|
795
|
+
|
|
796
|
+
rules['lift'] = rules['support'] / (rules['antecedent_len'] * rules['consequent_len'])
|
|
797
|
+
print(rules)
|
|
798
|
+
|
|
799
|
+
print("---------------------ACCURACY METRICS-------------------------------")
|
|
800
|
+
rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1)
|
|
801
|
+
print(rules)
|
|
802
|
+
rules = association_rules(frequent_itemsets,metric="confidence",min_threshold=1)
|
|
803
|
+
print(rules)
|
|
804
|
+
rules = association_rules(frequent_itemsets,metric="leverage",min_threshold=1)
|
|
805
|
+
print(rules)
|
|
806
|
+
rules = association_rules(frequent_itemsets,metric="conviction",min_threshold=1)
|
|
807
|
+
print(rules)
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
#Apriori Example 2
|
|
814
|
+
|
|
815
|
+
import pandas as pd
|
|
816
|
+
from mlxtend.preprocessing import TransactionEncoder
|
|
817
|
+
from mlxtend.frequent_patterns import apriori, association_rules
|
|
818
|
+
|
|
819
|
+
# Load dataset
|
|
820
|
+
retail_df = pd.read_csv("genshin_transactions.csv")
|
|
821
|
+
|
|
822
|
+
# Group transactions
|
|
823
|
+
transactions = retail_df.groupby('Transaction_ID')['Item'].apply(list).tolist()
|
|
824
|
+
|
|
825
|
+
# Display sample transactions (optional)
|
|
826
|
+
grouped = retail_df.groupby('Transaction_ID')['Item'].apply(list).reset_index()
|
|
827
|
+
for _, row in grouped.head(5).iterrows():
|
|
828
|
+
print(f"{row['Transaction_ID']} : {', '.join(row['Item'])}")
|
|
829
|
+
|
|
830
|
+
# One-hot encode transactions
|
|
831
|
+
te = TransactionEncoder()
|
|
832
|
+
te_ary = te.fit(transactions).transform(transactions)
|
|
833
|
+
encoded_df = pd.DataFrame(te_ary, columns=te.columns_)
|
|
834
|
+
|
|
835
|
+
print("\nOne-Hot Encoded DataFrame:")
|
|
836
|
+
print(encoded_df.head())
|
|
837
|
+
|
|
838
|
+
# Apriori to find frequent itemsets
|
|
839
|
+
min_support = 0.1
|
|
840
|
+
frequent_itemsets = apriori(encoded_df, min_support=min_support, use_colnames=True, max_len=3)
|
|
841
|
+
print("\nFrequent Itemsets:")
|
|
842
|
+
print(frequent_itemsets.head(10))
|
|
843
|
+
|
|
844
|
+
# Generate association rules by confidence
|
|
845
|
+
min_confidence = 0.7
|
|
846
|
+
rules_conf = association_rules(frequent_itemsets, metric="confidence", min_threshold=min_confidence)
|
|
847
|
+
|
|
848
|
+
print(f"\nAssociation Rules (min confidence={min_confidence}):")
|
|
849
|
+
if rules_conf.empty:
|
|
850
|
+
print("No rules found with specified thresholds.")
|
|
851
|
+
else:
|
|
852
|
+
for idx, row in rules_conf.reset_index(drop=True).iterrows():
|
|
853
|
+
antecedents = list(row['antecedents'])
|
|
854
|
+
consequents = list(row['consequents'])
|
|
855
|
+
combined_items = antecedents + consequents
|
|
856
|
+
# Counts: numerator = count(A and B), denominator = count(A)
|
|
857
|
+
num_count = int(encoded_df[combined_items].all(axis=1).sum())
|
|
858
|
+
den_count = int(encoded_df[antecedents].all(axis=1).sum())
|
|
859
|
+
conf = (num_count / den_count) if den_count > 0 else 0.0
|
|
860
|
+
|
|
861
|
+
ant_str = ", ".join(antecedents)
|
|
862
|
+
cons_str = ", ".join(consequents)
|
|
863
|
+
print(f"Rule {idx+1}: {ant_str} → {cons_str} = {num_count}/{den_count} = {conf:.2f}")
|
|
864
|
+
|
|
865
|
+
# Generate association rules by lift
|
|
866
|
+
min_lift = 1.5
|
|
867
|
+
rules_lift = association_rules(frequent_itemsets, metric="lift", min_threshold=min_lift)
|
|
868
|
+
|
|
869
|
+
print(f"\nAssociation Rules (min lift={min_lift}):")
|
|
870
|
+
if rules_lift.empty:
|
|
871
|
+
print("No rules found with specified lift threshold.")
|
|
872
|
+
else:
|
|
873
|
+
for idx, row in rules_lift.reset_index(drop=True).iterrows():
|
|
874
|
+
antecedents = list(row['antecedents'])
|
|
875
|
+
consequents = list(row['consequents'])
|
|
876
|
+
combined_items = antecedents + consequents
|
|
877
|
+
num_count = int(encoded_df[combined_items].all(axis=1).sum())
|
|
878
|
+
den_count = int(encoded_df[antecedents].all(axis=1).sum())
|
|
879
|
+
conf = (num_count / den_count) if den_count > 0 else 0.0
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
ant_str = ", ".join(antecedents)
|
|
883
|
+
cons_str = ", ".join(consequents)
|
|
884
|
+
lift = row['lift']
|
|
885
|
+
print(f"Rule {idx+1}: {ant_str} → {cons_str} | support: {row['support']:.3f} | confidence: {conf:.2f} | lift: {lift:.2f}")
|
|
886
|
+
|
|
887
|
+
''')
|
|
888
|
+
|
|
889
|
+
def amt_9():
|
|
890
|
+
print('''
|
|
891
|
+
|
|
892
|
+
#Page Rank Algorithm
|
|
893
|
+
|
|
894
|
+
def pagerank(graph, iterations, damping=0.85, tol=1e-6):
|
|
895
|
+
N = len(graph)
|
|
896
|
+
ranks = {node: 1.0 for node in graph}
|
|
897
|
+
|
|
898
|
+
for iteration in range(iterations):
|
|
899
|
+
print(f"Iteration {iteration + 1}:")
|
|
900
|
+
for node, rank in ranks.items():
|
|
901
|
+
print(f" {node}: {rank:.6f}")
|
|
902
|
+
|
|
903
|
+
new_ranks = {}
|
|
904
|
+
for node in graph:
|
|
905
|
+
sum_rank = 0.0
|
|
906
|
+
for src in graph:
|
|
907
|
+
if node in graph[src]:
|
|
908
|
+
sum_rank += ranks[src] / len(graph[src])
|
|
909
|
+
new_ranks[node] = (1 - damping) / N + damping * sum_rank
|
|
910
|
+
|
|
911
|
+
diff = sum(abs(new_ranks[node] - ranks[node]) for node in graph)
|
|
912
|
+
ranks = new_ranks
|
|
913
|
+
|
|
914
|
+
if diff < tol:
|
|
915
|
+
print(f"Converged after {iteration + 1} iterations")
|
|
916
|
+
break
|
|
917
|
+
|
|
918
|
+
print("Final stable PageRank values:")
|
|
919
|
+
for node, rank in ranks.items():
|
|
920
|
+
print(f" {node}: {rank:.6f}")
|
|
921
|
+
return ranks
|
|
922
|
+
|
|
923
|
+
def input_graph():
|
|
924
|
+
graph = {}
|
|
925
|
+
n = int(input("Enter the number of pages: "))
|
|
926
|
+
for _ in range(n):
|
|
927
|
+
page = input("Enter page name: ")
|
|
928
|
+
out_links = input("Enter outbound links from this page, separated by spaces: ").split()
|
|
929
|
+
graph[page] = out_links
|
|
930
|
+
return graph
|
|
931
|
+
|
|
932
|
+
graph = input_graph()
|
|
933
|
+
iterations = int(input("Enter number of iterations for PageRank calculation: "))
|
|
934
|
+
|
|
935
|
+
result = pagerank(graph, iterations)
|
|
936
|
+
|
|
937
|
+
''')
|
|
938
|
+
|
|
939
|
+
def amt_10():
|
|
940
|
+
print('''
|
|
941
|
+
|
|
942
|
+
#Minhashing - R Implementation
|
|
943
|
+
|
|
944
|
+
library(textreuse)
|
|
945
|
+
minhash <- minhash_generator(n=240, seed=3552)
|
|
946
|
+
head(minhash(c("turn tokens into", "tokens into hashes", "into hashes fast")))
|
|
947
|
+
|
|
948
|
+
dir <- system.file("extdata/ats", package="textreuse")
|
|
949
|
+
corpus <- TextReuseCorpus(dir= dir, tokenizer=tokenize_ngrams, n =5, minhash_func = minhash, keep_tokens=TRUE, progress=FALSE)
|
|
950
|
+
head(minhashes(corpus[[1]]))
|
|
951
|
+
|
|
952
|
+
length(minhashes(corpus[[1]]))
|
|
953
|
+
lsh_threshold(h = 200, b = 50)
|
|
954
|
+
lsh_threshold(h = 240, b = 80)
|
|
955
|
+
lsh_probability(h = 240, b = 80, s = 0.25)
|
|
956
|
+
lsh_probability(h = 240, b = 80, s = 0.75)
|
|
957
|
+
|
|
958
|
+
buckets <- lsh(corpus, bands = 80, progress = FALSE)
|
|
959
|
+
buckets
|
|
960
|
+
|
|
961
|
+
baxter_matches <- lsh_query(buckets, "calltounconv00baxt")
|
|
962
|
+
baxter_matches
|
|
963
|
+
|
|
964
|
+
candidates <- lsh_candidates(buckets)
|
|
965
|
+
candidates
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
#Minhashing - Python Implementation
|
|
971
|
+
|
|
972
|
+
import os
|
|
973
|
+
import re
|
|
974
|
+
from datasketch import MinHash, MinHashLSH
|
|
975
|
+
|
|
976
|
+
folder = 'british-fiction-corpus'
|
|
977
|
+
|
|
978
|
+
def get_shingles(text, k=5):
|
|
979
|
+
text = re.sub(r'\s+', ' ', text.lower())
|
|
980
|
+
return [text[i:i+k].encode('utf-8') for i in range(len(text) - k + 1)]
|
|
981
|
+
|
|
982
|
+
lsh = MinHashLSH(threshold=0.1, num_perm=100)
|
|
983
|
+
signatures = {}
|
|
984
|
+
|
|
985
|
+
for filename in os.listdir(folder):
|
|
986
|
+
if filename.endswith('.txt'):
|
|
987
|
+
with open(os.path.join(folder, filename), 'r', encoding='utf-8') as f:
|
|
988
|
+
shingles = get_shingles(f.read())
|
|
989
|
+
|
|
990
|
+
minhash = MinHash(num_perm=100)
|
|
991
|
+
for shingle in shingles:
|
|
992
|
+
minhash.update(shingle)
|
|
993
|
+
signatures[filename] = minhash
|
|
994
|
+
lsh.insert(filename, minhash)
|
|
995
|
+
|
|
996
|
+
print(f"Loaded {len(signatures)} documents")
|
|
997
|
+
|
|
998
|
+
all_similarities = []
|
|
999
|
+
processed = set()
|
|
1000
|
+
|
|
1001
|
+
for doc_name in signatures:
|
|
1002
|
+
if doc_name in processed:
|
|
1003
|
+
continue
|
|
1004
|
+
|
|
1005
|
+
similar_docs = lsh.query(signatures[doc_name])
|
|
1006
|
+
for similar_doc in similar_docs:
|
|
1007
|
+
if similar_doc != doc_name and (doc_name, similar_doc) not in processed:
|
|
1008
|
+
sim = signatures[doc_name].jaccard(signatures[similar_doc])
|
|
1009
|
+
all_similarities.append((sim, doc_name, similar_doc))
|
|
1010
|
+
processed.add((doc_name, similar_doc))
|
|
1011
|
+
processed.add((similar_doc, doc_name))
|
|
1012
|
+
|
|
1013
|
+
top_5 = sorted(all_similarities, reverse=True)[:5]
|
|
1014
|
+
|
|
1015
|
+
print("\nTop 5 most similar document pairs:")
|
|
1016
|
+
for sim, d1, d2 in top_5:
|
|
1017
|
+
print(f"{d1} <-> {d2}: similarity = {sim:.3f}")
|
|
1018
|
+
|
|
1019
|
+
''')
|