diff --git a/Week 1/task2.ipynb b/Week 1/task2.ipynb new file mode 100644 index 0000000..c7114ca --- /dev/null +++ b/Week 1/task2.ipynb @@ -0,0 +1,881 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idtransaction_idtransaction_datetransaction_timestoreproduct_namequantityunit_pricetotal_pricetotal_amounttotal_items
0111403-01-0123:38:58Jewelry StoreJewelry Store Product 3811658456.891658456.891658456.891
1121403-01-0216:41:29Electronics StoreElectronics Store Product 8211462060.361462060.361462060.361
2131403-01-0307:45:32Cosmetics StoreCosmetics Store Product 261105516.10105516.10323033.432
3131403-01-0307:45:32Cosmetics StoreCosmetics Store Product 171217517.33217517.33323033.432
4141403-01-0415:22:12Hardware StoreHardware Store Product 4011949500.131949500.136191593.896
\n", + "
" + ], + "text/plain": [ + " user_id transaction_id transaction_date transaction_time \\\n", + "0 1 1 1403-01-01 23:38:58 \n", + "1 1 2 1403-01-02 16:41:29 \n", + "2 1 3 1403-01-03 07:45:32 \n", + "3 1 3 1403-01-03 07:45:32 \n", + "4 1 4 1403-01-04 15:22:12 \n", + "\n", + " store product_name quantity unit_price \\\n", + "0 Jewelry Store Jewelry Store Product 38 1 1658456.89 \n", + "1 Electronics Store Electronics Store Product 82 1 1462060.36 \n", + "2 Cosmetics Store Cosmetics Store Product 26 1 105516.10 \n", + "3 Cosmetics Store Cosmetics Store Product 17 1 217517.33 \n", + "4 Hardware Store Hardware Store Product 40 1 1949500.13 \n", + "\n", + " total_price total_amount total_items \n", + "0 1658456.89 1658456.89 1 \n", + "1 1462060.36 1462060.36 1 \n", + "2 105516.10 323033.43 2 \n", + "3 217517.33 323033.43 2 \n", + "4 1949500.13 6191593.89 6 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data = pd.read_csv(\"./Stores_Transactions.csv\")\n", + "data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from convertdate import persian\n", + "\n", + "def convert_to_gregorian(persian_date):\n", + " year, month, day = map(int, persian_date.split('-'))\n", + " # استفاده از تابع صحیح برای تبدیل تاریخ شمسی به میلادی\n", + " return persian.to_gregorian(year, month, day)\n", + "\n", + "# تبدیل تاریخ‌ها به میلادی\n", + "data['transaction_date'] = data['transaction_date'].apply(convert_to_gregorian)\n", + "\n", + "# تبدیل به فرمت مناسب pandas datetime\n", + "data['transaction_date'] = pd.to_datetime(data['transaction_date'].apply(lambda x: '-'.join(map(str, x))), format='%Y-%m-%d')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idtransaction_idtransaction_datetransaction_timestoreproduct_namequantityunit_pricetotal_pricetotal_amounttotal_items
0112024-03-2023:38:58Jewelry StoreJewelry Store Product 3811658456.891658456.891658456.891
1122024-03-2116:41:29Electronics StoreElectronics Store Product 8211462060.361462060.361462060.361
2132024-03-2207:45:32Cosmetics StoreCosmetics Store Product 261105516.10105516.10323033.432
3132024-03-2207:45:32Cosmetics StoreCosmetics Store Product 171217517.33217517.33323033.432
4142024-03-2315:22:12Hardware StoreHardware Store Product 4011949500.131949500.136191593.896
\n", + "
" + ], + "text/plain": [ + " user_id transaction_id transaction_date transaction_time \\\n", + "0 1 1 2024-03-20 23:38:58 \n", + "1 1 2 2024-03-21 16:41:29 \n", + "2 1 3 2024-03-22 07:45:32 \n", + "3 1 3 2024-03-22 07:45:32 \n", + "4 1 4 2024-03-23 15:22:12 \n", + "\n", + " store product_name quantity unit_price \\\n", + "0 Jewelry Store Jewelry Store Product 38 1 1658456.89 \n", + "1 Electronics Store Electronics Store Product 82 1 1462060.36 \n", + "2 Cosmetics Store Cosmetics Store Product 26 1 105516.10 \n", + "3 Cosmetics Store Cosmetics Store Product 17 1 217517.33 \n", + "4 Hardware Store Hardware Store Product 40 1 1949500.13 \n", + "\n", + " total_price total_amount total_items \n", + "0 1658456.89 1658456.89 1 \n", + "1 1462060.36 1462060.36 1 \n", + "2 105516.10 323033.43 2 \n", + "3 217517.33 323033.43 2 \n", + "4 1949500.13 6191593.89 6 " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "user_id 0\n", + "transaction_id 0\n", + "transaction_date 0\n", + "transaction_time 0\n", + "store 0\n", + "product_name 0\n", + "quantity 0\n", + "unit_price 0\n", + "total_price 0\n", + "total_amount 0\n", + "total_items 0\n", + "day_of_week 0\n", + "hour_of_day 0\n", + "transaction_datetime 0\n", + "dtype: int64\n" + ] + } + ], + "source": [ + "data['transaction_time'] = pd.to_datetime(data['transaction_time'], format='%H:%M:%S').dt.time\n", + "\n", + "print(data.isnull().sum())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "day_of_week\n", + "Friday 1148\n", + "Monday 1124\n", + "Saturday 1320\n", + "Sunday 1116\n", + "Thursday 1080\n", + "Tuesday 1164\n", + "Wednesday 1240\n", + "Name: transaction_id, dtype: int64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# استخراج روز هفته و ساعت از تاریخ و زمان\n", + "data['day_of_week'] = data['transaction_date'].dt.day_name()\n", + "\n", + "\n", + "# تعداد خریدها در روزهای مختلف هفته\n", + "day_of_week_sales = data.groupby('day_of_week')['transaction_id'].count()\n", + "\n", + "\n", + "day_of_week_sales\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "بیشترین تعداد خرید در روز Saturday با 1320 خرید انجام شده است.\n" + ] + } + ], + "source": [ + "# پیدا کردن روز هفته با بیشترین تعداد خرید\n", + "max_sales_day = day_of_week_sales.idxmax()\n", + "\n", + "# تعداد خریدها در آن روز\n", + "max_sales_count = day_of_week_sales.max()\n", + "\n", + "print(f\"بیشترین تعداد خرید در روز {max_sales_day} با {max_sales_count} خرید انجام شده است.\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hour_of_day\n", + "0 362\n", + "1 323\n", + "2 355\n", + "3 349\n", + "4 360\n", + "5 348\n", + "6 383\n", + "7 338\n", + "8 307\n", + "9 393\n", + "10 299\n", + "11 340\n", + "12 349\n", + "13 357\n", + "14 300\n", + "15 258\n", + "16 311\n", + "17 391\n", + "18 328\n", + "19 338\n", + "20 320\n", + "21 378\n", + "22 348\n", + "23 357\n", + "Name: transaction_id, dtype: int64" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data['hour_of_day'] = data['transaction_time'].apply(lambda x: x.hour)\n", + "# تعداد خریدها در ساعت‌های مختلف روز\n", + "hour_of_day_sales = data.groupby('hour_of_day')['transaction_id'].count()\n", + "hour_of_day_sales\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "بیشترین تعداد خرید در ساعت 9 با 393 خرید انجام شده است.\n" + ] + } + ], + "source": [ + "# پیدا کردن ساعت با بیشترین تعداد خرید\n", + "max_sales_hour = hour_of_day_sales.idxmax()\n", + "\n", + "# تعداد خریدها در آن ساعت\n", + "max_sales_count = hour_of_day_sales.max()\n", + "\n", + "print(f\"بیشترین تعداد خرید در ساعت {max_sales_hour} با {max_sales_count} خرید انجام شده است.\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "store\n", + "Bookstore 2.135477e+08\n", + "Chain Store 8.477238e+08\n", + "Clothing Store 1.476769e+09\n", + "Cosmetics Store 3.563268e+08\n", + "Electronics Store 3.855097e+09\n", + "Florist Store 1.181164e+08\n", + "Furniture Store 1.389610e+09\n", + "Hardware Store 9.986125e+08\n", + "Home Appliance Store 4.831257e+09\n", + "Jewelry Store 1.226038e+10\n", + "Music Store 9.247326e+07\n", + "Pet Store 2.898425e+08\n", + "Sporting Goods Store 5.665938e+08\n", + "Supermarket 3.942086e+08\n", + "Toy Store 3.754816e+08\n", + "Name: total_price, dtype: float64" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# مجموع فروش‌ها در هر فروشگاه\n", + "store_sales = data.groupby('store')['total_price'].sum()\n", + "\n", + "store_sales\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "store\n", + "Bookstore 394\n", + "Chain Store 776\n", + "Clothing Store 585\n", + "Cosmetics Store 556\n", + "Electronics Store 425\n", + "Florist Store 716\n", + "Furniture Store 377\n", + "Hardware Store 511\n", + "Home Appliance Store 335\n", + "Jewelry Store 365\n", + "Music Store 518\n", + "Pet Store 549\n", + "Sporting Goods Store 516\n", + "Supermarket 973\n", + "Toy Store 596\n", + "Name: transaction_id, dtype: int64" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# تعداد تراکنش‌ها در هر فروشگاه\n", + "store_transactions = data.groupby('store')['transaction_id'].count()\n", + "\n", + "store_transactions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "product_name\n", + "Jewelry Store Product 32 5.322176e+08\n", + "Jewelry Store Product 23 5.078559e+08\n", + "Jewelry Store Product 24 4.947495e+08\n", + "Jewelry Store Product 35 4.577688e+08\n", + "Jewelry Store Product 31 4.078780e+08\n", + "Name: total_price, dtype: float64\n" + ] + } + ], + "source": [ + "# مجموع فروش برای هر محصول\n", + "product_sales = data.groupby('product_name')['total_price'].sum()\n", + "\n", + "# نمایش پرفروش‌ترین محصولات\n", + "print(product_sales.sort_values(ascending=False).head())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " user_id total_price transaction_id cluster\n", + "0 1 2.251340e+09 661 0\n", + "1 2 2.795794e+09 673 3\n", + "2 3 2.713384e+09 708 3\n", + "3 4 1.687042e+09 717 2\n", + "4 5 2.273373e+09 624 4\n" + ] + } + ], + "source": [ + "from sklearn.cluster import KMeans\n", + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "# ویژگی‌های مشتریان برای خوشه‌بندی (برای مثال مجموع خرید و تعداد خریدها)\n", + "customer_features = data.groupby('user_id').agg({'total_price': 'sum', 'transaction_id': 'count'}).reset_index()\n", + "\n", + "# نرمال‌سازی ویژگی‌ها\n", + "scaler = StandardScaler()\n", + "customer_features_scaled = scaler.fit_transform(customer_features[['total_price', 'transaction_id']])\n", + "\n", + "# اعمال الگوریتم KMeans\n", + "kmeans = KMeans(n_clusters=5)\n", + "customer_features['cluster'] = kmeans.fit_predict(customer_features_scaled)\n", + "\n", + "# نمایش خوشه‌ها\n", + "print(customer_features.head())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "customer_features = data.groupby('user_id').agg({\n", + " 'total_price': 'sum', # مجموع مبلغ خرید\n", + " 'transaction_id': 'count' # تعداد تراکنش‌ها\n", + "}).reset_index()\n", + "\n", + "# تغییر نام ستون‌ها برای راحتی\n", + "customer_features.rename(columns={'transaction_id': 'transaction_count'}, inplace=True)\n", + "\n", + "# نرمال‌سازی داده‌ها\n", + "scaler = StandardScaler()\n", + "customer_features_scaled = scaler.fit_transform(customer_features[['total_price', 'transaction_count']])\n", + "\n", + "# اجرای K-Means با 3 خوشه (می‌توانید تعداد خوشه‌ها را تغییر دهید)\n", + "kmeans = KMeans(n_clusters=3, random_state=42)\n", + "customer_features['cluster'] = kmeans.fit_predict(customer_features_scaled)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idtotal_pricetransaction_countcluster
012.251340e+096610
122.795794e+096732
232.713384e+097081
341.687042e+097170
452.273373e+096240
\n", + "
" + ], + "text/plain": [ + " user_id total_price transaction_count cluster\n", + "0 1 2.251340e+09 661 0\n", + "1 2 2.795794e+09 673 2\n", + "2 3 2.713384e+09 708 1\n", + "3 4 1.687042e+09 717 0\n", + "4 5 2.273373e+09 624 0" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_features.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# پیدا کردن بهترین تعداد خوشه‌ها با استفاده از روش Elbow\n", + "inertia = []\n", + "for k in range(1, 11):\n", + " kmeans = KMeans(n_clusters=k, random_state=42)\n", + " kmeans.fit(customer_features_scaled)\n", + " inertia.append(kmeans.inertia_)\n", + "\n", + "# رسم نمودار Elbow\n", + "plt.plot(range(1, 11), inertia, marker='o')\n", + "plt.title('Elbow Method')\n", + "plt.xlabel('Number of clusters (K)')\n", + "plt.ylabel('Inertia')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " user_id total_price transaction_id product_name total_items \\\n", + "cluster \n", + "0 6.5 2.283527e+09 653.0 501.166667 5485.833333 \n", + "1 6.5 1.760903e+09 703.0 542.000000 6438.500000 \n", + "2 6.5 2.710768e+09 717.0 551.250000 6524.250000 \n", + "\n", + " average_purchase avg_time_between_purchases \n", + "cluster \n", + "0 3.497600e+06 28333.311441 \n", + "1 2.507927e+06 26190.019903 \n", + "2 3.789379e+06 25866.210750 \n" + ] + } + ], + "source": [ + "from sklearn.cluster import KMeans\n", + "from sklearn.preprocessing import StandardScaler\n", + "import pandas as pd\n", + "\n", + "# فرض می‌کنیم که داده‌ها در یک DataFrame به نام 'data' هستند\n", + "\n", + "# استخراج ویژگی‌های معنی‌دار برای تحلیل بیشتر\n", + "customer_features = data.groupby('user_id').agg({\n", + " 'total_price': 'sum', # مجموع مبلغ خرید\n", + " 'transaction_id': 'count', # تعداد تراکنش‌ها\n", + " 'product_name': 'nunique', # تعداد محصولات مختلفی که خریداری کرده‌اند\n", + " 'total_items': 'sum', # مجموع تعداد اقلام خریداری‌شده\n", + "}).reset_index()\n", + "\n", + "# محاسبه میانگین مبلغ خرید (total_price / تعداد تراکنش‌ها)\n", + "customer_features['average_purchase'] = customer_features['total_price'] / customer_features['transaction_id']\n", + "\n", + "# تبدیل ستون تاریخ و زمان به رشته و سپس ترکیب آن‌ها\n", + "data['transaction_datetime'] = pd.to_datetime(data['transaction_date'].astype(str) + ' ' + data['transaction_time'].astype(str))\n", + "\n", + "# مرتب کردن داده‌ها بر اساس user_id و transaction_datetime\n", + "data_sorted = data.sort_values(by=['user_id', 'transaction_datetime'])\n", + "\n", + "# محاسبه فاصله زمانی بین خریدها برای هر مشتری\n", + "data_sorted['time_diff'] = data_sorted.groupby('user_id')['transaction_datetime'].diff().fillna(pd.Timedelta(seconds=0))\n", + "\n", + "# محاسبه میانگین فاصله زمانی خریدها\n", + "purchase_frequency = data_sorted.groupby('user_id')['time_diff'].mean().reset_index()\n", + "purchase_frequency.rename(columns={'time_diff': 'avg_time_between_purchases'}, inplace=True)\n", + "\n", + "# تبدیل فاصله زمانی به ثانیه برای نرمال‌سازی\n", + "purchase_frequency['avg_time_between_purchases'] = purchase_frequency['avg_time_between_purchases'].dt.total_seconds()\n", + "\n", + "# ترکیب دو ویژگی جدید: میانگین فاصله زمانی و ویژگی‌های دیگر\n", + "customer_features = pd.merge(customer_features, purchase_frequency, on='user_id')\n", + "\n", + "# نرمال‌سازی داده‌ها\n", + "scaler = StandardScaler()\n", + "scaled_features = scaler.fit_transform(customer_features[['total_price', 'transaction_id', 'product_name', 'average_purchase', 'total_items', 'avg_time_between_purchases']])\n", + "\n", + "# اجرای K-Means با 3 خوشه\n", + "kmeans = KMeans(n_clusters=3, random_state=42)\n", + "customer_features['cluster'] = kmeans.fit_predict(scaled_features)\n", + "\n", + "# بررسی نتایج خوشه‌بندی\n", + "print(customer_features.groupby('cluster').mean()) # ویژگی‌های متوسط هر خوشه\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "myenv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Week 1/week1.pdf b/Week 1/week1.pdf new file mode 100644 index 0000000..f5d5520 Binary files /dev/null and b/Week 1/week1.pdf differ