1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | # -*- coding: utf-8 -*- """Day 10_logistic_regression_Sentiment_Analysis.ipynb Automatically generated by Colaboratory. Original file is located at """ from google.colab import drive drive.mount('/gdrive') PATH = "/gdrive/My Drive/Colab Notebooks/resources/" # Standard includes # %matplotlib inline import numpy as np import string import matplotlib import matplotlib.pyplot as plt # Routines for linear regression from sklearn import linear_model from sklearn.metrics import mean_squared_error # Set label size for plots matplotlib.rc('xtick', labelsize=14) matplotlib.rc('ytick', labelsize=14) # installing packages for interactive graphs import ipywidgets as widgets from IPython.display import display from ipywidgets import interact, interactive, fixed, interact_manual, IntSlider ##데이터 로드 with open (PATH + "sentiment-logistic-regression/sentiment_labelled_sentences/"'full_set.txt') as f: content = f.readlines() content = [x.strip() for x in content ] ## 라벨과 문장으로 분리 sentences = [ x.split("\t")[0] for x in content ] labels = [ x.split("\t")[1] for x in content ] ## 타겟 클래스를 0, 1에서 -1과 1로 변경 y = np.array(labels, dtype='int8') y = 2*y - 1 ################################ ############ 전처리 ############# ############################### ## 지우고자 하는 문자 리스트를 받아서 x에서 지우는 함수. def full_remove(x, removal_list): for w in removal_list: x = x.replace(w, ' ') return x ## 숫자 제거 digits = [str(x) for x in range(10)] digit_less = [full_remove(x, digits) for x in sentences] ## 특수문자 제거 punc_less = [full_remove(x, list(string.punctuation)) for x in digit_less] ## 소문자로 변경 sents_lower = [x.lower() for x in punc_less] ## 불용어 정의 stop_set = set(['the', 'a', 'an', 'i', 'he', 'she', 'they', 'to', 'of', 'it', 'from']) ## 불용어 제거 ## 공백으로 분리 sents_split = [x.split() for x in sents_lower] ## 불용어에 없는 단어만 띄워쓰기로 재결합 sents_processed = [" ".join(list(filter(lambda a: a not in stop_set, x))) for x in sents_split] ## 불용어가 날아간 문장들 sents_processed[0:10] from sklearn.feature_extraction.text import CountVectorizer ## bag of words ( Term frequency ) 만들기 vectorizer = CountVectorizer(analyzer = "word", tokenizer = None, preprocessor = None, stop_words = None, max_features = 4500) data_features = vectorizer.fit_transform(sents_processed) ## 첫 250개 에는 y가 -1인값들의 인덱스가, 다음 250개에는 y가 1인 값들의 인덱스가 들어간다. test_inds = np.append(np.random.choice((np.where(y==-1))[0], 250, replace=False), np.random.choice((np.where(y==1))[0], 250, replace=False)) ## 처음 뽑은 500개를 제외한 나머지의 인덱스가 들어가게 된다. train_inds = list(set(range(len(labels))) - set(test_inds)) train_data = data_mat[train_inds,] train_labels = y[train_inds] test_data = data_mat[test_inds,] test_labels = y[test_inds] print("train data: ", train_data.shape) print("test data: ", test_data.shape) from sklearn.linear_model import SGDClassifier ## 모델 피팅. 손실함수에는 로그를 적용하고 regularizer를 사용하지 않는다. clf = SGDClassifier(loss="log", penalty="none", ) clf.fit(train_data, train_labels) ## Linear Function으로부터 피처들의 가중치 w와 bias를 추출한다. w = clf.coef_[0, :] b = clf.intercept_ ## 트레이닝셋과 테스트셋으로부터 예측결과를 받는다. preds_train = clf.predict(train_data) preds_test = clf.predict(test_data) ## 에러를 계산한다. errs_train = np.sum((preds_train > 0.0) != (train_labels > 0.0)) errs_test = np.sum((preds_test > 0.0) != (test_labels > 0.0)) print ("Training error: ", float(errs_train)/len(train_labels)) print ("Test error: ", float(errs_test)/len(test_labels)) ## 0.5로부터 감마만큼 떨어져 있는 포인트들만 다시 리턴한다. 즉 0.5 주변에 있는 확률이 애매한 포인트들은 제외하고 ## 확실히 분류될수 있는 포인트 들만 리턴한다. def margin_counts(clf, test_data, gamma): ## Compute probability on each test point preds = clf.predict_proba(test_data)[:,1] ## Find data points for which prediction is at least gamma away from 0.5 margin_inds = np.where((preds > (0.5+gamma)) | (preds < (0.5-gamma)))[0] return float(len(margin_inds)) ## 각 마진별 해당되는 요소의 갯수를 시각화 gammas = np.arange(0,0.5,0.01) f = np.vectorize(lambda g: margin_counts(clf, test_data, g)) plt.plot(gammas, f(gammas)/500.0, linewidth=2, color='green') plt.xlabel('Margin', fontsize=14) plt.ylabel('Fraction of points above margin', fontsize=14) plt.show() def margin_errors(clf, test_data, test_labels, gamma): ##각 테스트 포인트에서 1번으로 분류될 확률만 500행의 배열로 리턴한다. preds = clf.predict_proba(test_data)[:,1] ## 해당 조건을 만족하는 배열의 인덱스가 길이가 1인 튜플로 리턴된다. margin_inds = np.where((preds > (0.5+gamma)) | (preds < (0.5-gamma)))[0] ## 에러 검증. preds안에서 1로 분류된것들이 test_label에서 1로 분류가 안되었다면 에러로 취급한다 num_errors = np.sum((preds[margin_inds] > 0.5) != (test_labels[margin_inds] > 0.0)) return float(num_errors)/len(margin_inds) ## 마진 조정 범위 gammas = np.arange(0, 0.5, 0.01) ## g값에 따른 에러율 측정함수 f = np.vectorize(lambda g: margin_errors(clf, test_data, test_labels, g)) ## 시각화 plt.plot(gammas, f(gammas), linewidth=2) plt.ylabel('Error rate', fontsize=14) plt.xlabel('Margin', fontsize=14) plt.show() | cs |
출처 및 참고자료 : edx - Machine Learning Fundamentals_week_4 Programming Assignment.1
'Python Library > Machine Learning' 카테고리의 다른 글
Day 08. Perceptron_Classification_Algorithm (0) | 2019.07.18 |
---|---|
Day 07_ridge-regression_gradient_descent (0) | 2019.07.17 |
Day 05_Multivariate Gaussian_Winery_Classifier_MNIST (0) | 2019.07.13 |
Day 05_Multivariate Gaussian_Winery_Classifier (0) | 2019.07.13 |
Day 03.Probability and statistics Review (0) | 2019.07.08 |