دسته بندی داده ها با پایتون — راهنمای کاربردی
در این مطلب، چندین الگوریتم «یادگیری ماشین» (Machine Learning) در «زبان برنامهنویسی پایتون» (Python Programming Language) با استفاده از کتابخانه «سایکیتلِرن» (Scikit-Learn) که یکی از محبوبترین کتابخانههای یادگیری ماشین است، پیادهسازی شدهاند. این الگوریتمها، برای «دستهبندی» (Classification) یک مجموعه داده برچسبدار از میوهها، مورد استفاده قرار گرفتهاند. در واقع، از یک مجموعه داده ساده، برای آموزش دادن «دستهبند» (Classifier) و تمایز ایجاد کردن بین انواع میوهها، استفاده شده است. هدف از این مطلب، شناسایی الگوریتم یادگیری ماشینی است که برای چنین مسالهای بالاترین صحت را ارائه میکند. بنابراین، الگوریتمهای گوناگون در ادامه با یکدیگر مقایسه میشوند و الگوریتمی با بهترین عملکرد، انتخاب میشود. با مطالعه این مطلب، میتوان با روشهای گوناگون دسته بندی داده ها با پایتون آشنا شد.
داده
مجموعه داده میوهها، توسط دکتر «لاین مورای» (Iain Murray) از «دانشگاه اِدینبرا» (University of Edinburgh) ساخته شده است. وی، مقادیر زیادی پرتقال، لیمو و سیب از گونههای گوناگون را تهیه و اندازههای آنها را در یک جدول ثبت کرده است.
سپس، اساتید دانشگاهی در «میشیگان» (Michigan)، دادههای میوهها را به تدریج قالببندی کردهاند. مجموعه داده نهایی حاصل شده از این فرایند را میتوان از اینجا [+] دانلود کرد. در ادامه، نگاهی به سطرهای اول این مجموعه داده انداخته میشود.
1%matplotlib inline
2import pandas as pd
3import matplotlib.pyplot as plt
4fruits = pd.read_table('fruit_data_with_colors.txt')
5fruits.head()
هر سطر از مجموعه داده، نشانگر یک میوه به همراه «ویژگیهای» (Features) آن است. ۵۹ عدد نمونه (اطلاعات مربوط به ۵۹ میوه)، همراه با هفت ویژگی پیرامون آنها، در این مجموعه داده آورده شده است.
ورودی:
1print(fruits.shape)
خروجی:
(59, 7)
چهار نوع میوه، در مجموعه داده وجود دارد (در واقع، با توجه به برچسبدار بودن مجموعه داده، چهار برچسب وجود دارد).
ورودی:
1print(fruits['fruit_name'].unique())
خروجی:
[‘apple’ ‘mandarin’ ‘orange’ ‘lemon’]
دادهها به جز در مورد «پرتقال ماندارین» (Mandarin)، متوازن هستند (که البته میتوان با این مساله کنار آمد).
ورودی:
1print(fruits.groupby('fruit_name').size())
خروجی:
ورودی:
1import seaborn as sns
2sns.countplot(fruits['fruit_name'],label="Count")
3plt.show()
خروجی:
بصریسازی
نمودار جعبهای، برای هر متغیر عددی، ایدهای کلی از شیوه توزیع متغیرهای ورودی به دست میدهد.
ورودی:
1fruits.drop('fruit_label', axis=1).plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False, figsize=(9,9),
2 title='Box Plot for each input variable')
3plt.savefig('fruits_box')
4plt.show()
خروجی:
به نظر میرسد که امتیاز رنگ، دارای توزیعی نزدیک به «توزیع گاوسی» (Gaussian Distribution) است.
ورودی:
1import pylab as pl
2fruits.drop('fruit_label' ,axis=1).hist(bins=30, figsize=(9,9))
3pl.suptitle("Histogram for each numeric input variable")
4plt.savefig('fruits_hist')
5plt.show()
خروجی:
برخی از جفت ویژگیها، همبسته هستند (جرم و عرض). این امر موجب همبستگی بالا و رابطه قابل پیشبینی میشود.
ورودی:
1from pandas.tools.plotting import scatter_matrix
2from matplotlib import cm
3feature_names = ['mass', 'width', 'height', 'color_score']
4X = fruits[feature_names]
5y = fruits['fruit_label']
6cmap = cm.get_cmap('gnuplot')
7scatter = pd.scatter_matrix(X, c = y, marker = 'o', s=40, hist_kwds={'bins':15}, figsize=(9,9), cmap = cmap)
8plt.suptitle('Scatter-matrix for each input variable')
9plt.savefig('fruits_scatter_matrix')
خروجی:
خلاصه آماری
میتوان مشاهده کرد که مقادیر عددی، دارای مقیاس یکسانی نیستند. بنابراین، نیاز به اعمال استانداردسازی مجموعه داده تست است؛ در اینجا باید همان روش استانداردسازی که برای مجموعه داده آموزش مورد استفاده قرار گرفته، روی مجموعه داده تست اعمال شود .
ساخت مجموعههای آموزش، تست و اعمال استانداردسازی
1from sklearn.model_selection import train_test_split
2X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
3from sklearn.preprocessing import MinMaxScaler
4scaler = MinMaxScaler()
5X_train = scaler.fit_transform(X_train)
6X_test = scaler.transform(X_test)
دسته بندی داده ها با پایتون
همانطور که پیشتر بیان شد، چندین مدل گوناگون روی مجموعه داده اعمال میشوند تا کارایی آنها سنجیده و صحت خروجی حاصل از هر یک از آنها، با دیگر الگوریتمها مقایسه شود. در نهایت، مدل با بهترین خروجی، انتخاب خواهد شد.
رگرسیون لجستیک
برای مطالعه بیشتر پیرامون الگوریتم «رگرسیون لجستیک» (Logistic Regression)، مطالعه مطلب «رگرسیون لجستیک در پایتون — راهنمای گام به گام»، توصیه میشود. در زیر، پیادهسازی این الگوریتم با استفاده از کتابخانه Scikit-Learn انجام شده است.
1from sklearn.linear_model import LogisticRegression
2logreg = LogisticRegression()
3logreg.fit(X_train, y_train)
4print('Accuracy of Logistic regression classifier on training set: {:.2f}'
5 .format(logreg.score(X_train, y_train)))
6print('Accuracy of Logistic regression classifier on test set: {:.2f}'
7 .format(logreg.score(X_test, y_test)))
- صحت دستهبند رگرسیون لجستیک روی مجموعه داده آموزش: ۰.۷۰
- صحت دستهبند رگرسیون لجستیک روی مجموعه داده تست: ۰.۴۰
درخت تصمیم
برای مطالعه بیشتر پیرامون الگوریتم «درخت تصمیم» (Decision Tree)، مطالعه مطلب «درخت تصمیم با پایتون — راهنمای کاربردی» پیشنهاد میشود. در زیر، قطعه کد مربوط به اعمال این الگوریتم روی مجموعه داده میوهها، ارائه شده است.
1from sklearn.tree import DecisionTreeClassifier
2clf = DecisionTreeClassifier().fit(X_train, y_train)
3print('Accuracy of Decision Tree classifier on training set: {:.2f}'
4 .format(clf.score(X_train, y_train)))
5print('Accuracy of Decision Tree classifier on test set: {:.2f}'
6 .format(clf.score(X_test, y_test)))
- صحت دستهبند درخت تصمیم روی مجموعه داده آموزش: 1.00
- صحت دستهبند درخت تصمیم، روی مجموعه داده تست: ۰.۷۳
K-نزدیکترین همسایگی
برای مطالعه بیشتر پیرامون الگوریتم «K-نزدیکترین همسایگی» (k-Nearest Neighbors | KNN)، مطالعه مطلب «الگوریتم K-نزدیکترین همسایگی به همراه کد پایتون» توصیه میشود. در ادامه، قطعه کد مربوط به اعمال الگوریتم KNN روی مجموعه داده میوهها، ارائه شده است.
1from sklearn.neighbors import KNeighborsClassifier
2knn = KNeighborsClassifier()
3knn.fit(X_train, y_train)
4print('Accuracy of K-NN classifier on training set: {:.2f}'
5 .format(knn.score(X_train, y_train)))
6print('Accuracy of K-NN classifier on test set: {:.2f}'
7 .format(knn.score(X_test, y_test)))
- صحت دستهبندی KNN روی مجموعه داده آموزش: ۰.۹۵
- صحت دستهبندی KNN روی مجموعه تست: ۱.۰
آنالیز تشخیصی خطی
برای مطالعه بیشتر پیرامون الگوریتم «آنالیز تشخیصی خطی» (Linear Discriminant Analysis | LDA)، مطالعه مطلب «آنالیز تشخیصی خطی (LDA) در پایتون — راهنمای کاربردی» توصیه میشود.
در ادامه، الگوریتم LDA روی مجموعه داده میوه اعمال شده است.
1from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
2lda = LinearDiscriminantAnalysis()
3lda.fit(X_train, y_train)
4print('Accuracy of LDA classifier on training set: {:.2f}'
5 .format(lda.score(X_train, y_train)))
6print('Accuracy of LDA classifier on test set: {:.2f}'
7 .format(lda.score(X_test, y_test)))
- صحت دستهبندی LDA روی مجموعه داده آموزش: ۰.۸۶
- صحت دستهبندی LDA روی مجموعه داده تست: ۰.۶۷
نایو بیز گاوسی
برای آشنایی بیشتر با الگوریتم «دستهبند بیز ساده» (Naive Bayes Classifiers)، مطالعه مطلب «دسته بند بیز ساده (Naive Bayes Classifiers) — مفاهیم اولیه و کاربردها» توصیه میشود. در ادامه، قطعه کد مربوط به اعمال الگوریتم نایو بیز گاوسی روی مجموعه داده میوهها ارائه شده است.
1from sklearn.naive_bayes import GaussianNB
2gnb = GaussianNB()
3gnb.fit(X_train, y_train)
4print('Accuracy of GNB classifier on training set: {:.2f}'
5 .format(gnb.score(X_train, y_train)))
6print('Accuracy of GNB classifier on test set: {:.2f}'
7 .format(gnb.score(X_test, y_test)))
- صحت دستهبند نایو بیز گاوسی روی مجموعه آموزش: ۰.۸۶
- صحت دستهبند نایو بیز گاوسی روی مجموعه تست: ۰.۶۷
ماشین بردار پشتیبان
برای مطالعه بیشتر پیرامون الگوریتم «ماشین بردار پشتیبان» (Support Vector Machine | SVM)، مطالعه مطلب «ماشین بردار پشتیبان — به همراه کدنویسی پایتون و R» توصیه میشود.
در ادامه، پیادهسازی SVM با استفاده از کتابخانه سایکیتلرن انجام شده است.
1from sklearn.svm import SVC
2svm = SVC()
3svm.fit(X_train, y_train)
4print('Accuracy of SVM classifier on training set: {:.2f}'
5 .format(svm.score(X_train, y_train)))
6print('Accuracy of SVM classifier on test set: {:.2f}'
7 .format(svm.score(X_test, y_test)))
- صحت دستهبند ماشین بردار پشتیبانی روی مجموعه آموزش: ۰.۶۱
- صحت دستهبند ماشین بردار پشتیبان روی مجموعه تست: ۰.۳۳
نتیجهگیری
همانطور که از صحتهای حاصل شده مشهود است، مدل KNN بالاترین خروجی را داشته است. «ماتریس درهم ریختگی» (Confusion Matrix) حاکی از عدم وجود هرگونه خطا در خروجی الگوریتم K-نزدیکترین همسایگی برای مجموعه داده تست است. اگرچه، مجموعه داده تست استفاده شده، خیلی کوچک محسوب میشود.
1from sklearn.metrics import classification_report
2from sklearn.metrics import confusion_matrix
3pred = knn.predict(X_test)
4print(confusion_matrix(y_test, pred))
5print(classification_report(y_test, pred))
ترسیم مرزهای دستهبندی برای دستهبند K-نزدیکترین همسایگی
1import matplotlib.cm as cm
2from matplotlib.colors import ListedColormap, BoundaryNorm
3import matplotlib.patches as mpatches
4import matplotlib.patches as mpatches
5X = fruits[['mass', 'width', 'height', 'color_score']]
6y = fruits['fruit_label']
7X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
8def plot_fruit_knn(X, y, n_neighbors, weights):
9 X_mat = X[['height', 'width']].as_matrix()
10 y_mat = y.as_matrix()
11# Create color maps
12 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF','#AFAFAF'])
13 cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF','#AFAFAF'])
14clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)
15 clf.fit(X_mat, y_mat)
16# Plot the decision boundary by assigning a color in the color map
17 # to each mesh point.
18
19 mesh_step_size = .01 # step size in the mesh
20 plot_symbol_size = 50
21
22 x_min, x_max = X_mat[:, 0].min() - 1, X_mat[:, 0].max() + 1
23 y_min, y_max = X_mat[:, 1].min() - 1, X_mat[:, 1].max() + 1
24 xx, yy = np.meshgrid(np.arange(x_min, x_max, mesh_step_size),
25 np.arange(y_min, y_max, mesh_step_size))
26 Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
27# Put the result into a color plot
28 Z = Z.reshape(xx.shape)
29 plt.figure()
30 plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
31# Plot training points
32 plt.scatter(X_mat[:, 0], X_mat[:, 1], s=plot_symbol_size, c=y, cmap=cmap_bold, edgecolor = 'black')
33 plt.xlim(xx.min(), xx.max())
34 plt.ylim(yy.min(), yy.max())
35patch0 = mpatches.Patch(color='#FF0000', label='apple')
36 patch1 = mpatches.Patch(color='#00FF00', label='mandarin')
37 patch2 = mpatches.Patch(color='#0000FF', label='orange')
38 patch3 = mpatches.Patch(color='#AFAFAF', label='lemon')
39 plt.legend(handles=[patch0, patch1, patch2, patch3])
40plt.xlabel('height (cm)')
41plt.ylabel('width (cm)')
42plt.title("4-Class classification (k = %i, weights = '%s')"
43 % (n_neighbors, weights))
44plt.show()
45plot_fruit_knn(X_train, y_train, 5, 'uniform')
1k_range = range(1, 20)
2scores = []
3for k in k_range:
4 knn = KNeighborsClassifier(n_neighbors = k)
5 knn.fit(X_train, y_train)
6 scores.append(knn.score(X_test, y_test))
7plt.figure()
8plt.xlabel('k')
9plt.ylabel('accuracy')
10plt.scatter(k_range, scores)
11plt.xticks([0,5,10,15,20])
برای این مجموعه داده، بالاترین صحت هنگامی حاصل میشود که مقدار K در الگوریتم KNN برابر با پنج (k=5) تعیین شده است.
خلاصه
در این مطلب، الگوریتمهای دستهبندی گوناگون با استفاده از کتابخانه سایکیتلرن پیادهسازی و روی یک مجموعه داده برچسبدار (مجموعه داده میوهها) اعمال شدند. سپس، صحت نتایج حاصل از هر یک از الگوریتمها با دیگر موارد مقایسه شد. در واقع، در این بررسی موردی روی صحت پیشبینیها تمرکز شده و هدف، یافتن مدلی بود که صحت خوبی داشته باشد. چنین مدلی، صحت پیشبینی را بیشینه میسازد. در نهایت، الگوریتم یادگیری ماشینی که بهترین خروجی را برای مساله بیان شده داشت (دستهبندی انواع میوهها)، یعنی KNN، شناسایی شد. کدهای استفاده شده برای این پروژه، در گیتهاب [+] موجود هستند.
اگر مطلب بالا برای شما مفید بوده، آموزشهای زیر نیز به شما پیشنهاد میشود:
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- مجموعه آموزشهای دادهکاوی یا Data Mining در متلب
- مجموعه آموزشهای هوش مصنوعی
- زبان برنامهنویسی پایتون (Python) — از صفر تا صد
- یادگیری ماشین با پایتون — به زبان ساده
- آموزش یادگیری ماشین با مثالهای کاربردی — مجموعه مقالات جامع وبلاگ فرادرس
- چگونه یک دانشمند داده شوید؟ — راهنمای گامبهگام به همراه معرفی منابع
^^
خیلی ب دردم خورد دمتون گرم