diff --git a/DassomLee/20180629_statistics&constitution b/DassomLee/20180629_statistics&constitution index 88c3705..fa88ca5 100644 --- a/DassomLee/20180629_statistics&constitution +++ b/DassomLee/20180629_statistics&constitution @@ -1,9 +1,10 @@ • 차원이 늘어날 수록(=변수가 늘어날 수록) 각 변수에 대한 정보가 기하급수적으로 증가하게 됨 -• 반대로 전체의 관점에서 보면, 차원이 늘어날수록 20%에 해당하는 부분이(=전체 대표값이) 각 변수의 값을 포함하는 부분이 적어짐 which means 대표값이 각 값을 대변하지 못함 +• 반대로 전체의 관점에서 보면, 차원이 늘어날수록 20%에 해당하는 부분이(=전체 대표값이) 각 변수의 값을 포함하는 부분이 적어짐. 대표값이 각 값을 대변하지 못함 • 오버피팅; overfitting(너무 적을 때) & 언더피팅(너무 많을 때) --> 변수는 너무 많아도, 너무 적어도 안좋아. 적당히 있어야~적당히~ • SEMMA; Sample, Explore, Modify, Model, Assess. SAS에서 만든 방법론 --> 제일 중요한건 Explore • EDA; Exploratory Data Analysis. 탐색적 자료 분석. 데이터가 가진 정보를 데이터의 탐색만으로 얻는 방법. 다양한 시도를 해야함. 분석의 첫 단계.데이터의 패턴/규칙을 파악할 수 있음 + • 자료의 분류 • 수치형변수numerical variable ○ 연속형변수continous: 자세하게 하자면 계속 늘어날 수 있어 diff --git a/soryeongk/180727_Binary_classification.md b/soryeongk/180727_Binary_classification.md new file mode 100644 index 0000000..a3b0964 --- /dev/null +++ b/soryeongk/180727_Binary_classification.md @@ -0,0 +1,1358 @@ + +# 국민청원 데이터로 이진 분류하기 + +* 예제로 응답여부를 0과 1로 예측합니다. +* 응답여부 외에도 청원의 카테고리를 예측하는 분류를 해볼 수도 있을것 같아요. +* 이 예제를 참고하여 응답여부외에 청원내용으로 평균 이상의 투표를 받을 것인지 여부를 예측해 보면 좋겠습니다. + + +```python +import pandas as pd +import numpy as np +import re +print(pd.__version__) +print(np.__version__) +``` + + 0.23.0 + 1.14.3 + + +# 데이터 로드하기 + + +```python +# 크롤링해 온 국민청원 데이터를 판다스를 통해 읽어옵니다. +petitions = pd.read_csv('https://s3.ap-northeast-2.amazonaws.com/data10902/petition/petition.csv', + parse_dates=['start', 'end']) +# 데이터의 크기가 어느정도인지 봅니다. +petitions.shape +``` + + + + + (219855, 8) + + + + +```python +petitions.describe() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idansweredvotes
count219855.000000219855.000000219855.000000
mean132868.5946240.000123149.437711
std83296.5358700.0110814635.027514
min21.0000000.0000000.000000
25%57208.5000000.0000001.000000
50%131803.0000000.0000003.000000
75%204034.5000000.00000011.000000
max284841.0000001.000000714875.000000
+
+ + + + +```python +# 전체 데이터 중 투표가 1000건 이상인 데이터를 기준으로 가져옵니다. 아웃라이어 데이터 제거를 위해 10만건 이상 데이터도 제거합니다. +df = petitions.loc[(petitions['votes'] > 100) & (petitions['votes'] < 1000)] +# 500건 이상으로 바꾸어서 해보아도 좋음 +# 개수가 많으면 학습을 잘 하는 것은 맞지만, outline데이터가 많으면 의미없을 수도. +df.shape +``` + + + + + (7963, 8) + + + + +```python +df.describe() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idansweredvotes
count7963.0000007963.07963.000000
mean169588.0507350.0273.799950
std72330.8126030.0195.966223
min34.0000000.0101.000000
25%121414.0000000.0137.000000
50%184251.0000000.0196.000000
75%221999.0000000.0333.000000
max284841.0000000.0998.000000
+
+ + + + +```python +# 1000건 이상 투표를 받은 데이터의 평군은 7483 입니다. +df.loc[df['answered'] == 1].shape +``` + + + + + (0, 8) + + + + +```python +%matplotlib inline +df['votes'].plot.hist() +``` + + + + + + + + + +![png](output_9_1.png) + + + +```python +# 기본값을 0으로 세팅 +df['votes_pos_neg'] = 0 +``` + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + + + + +```python +# 투표수가 평균을 넘으면 1로 다시 세팅 +df['votes_pos_neg'] = (df['votes'] > 273) == 1 +``` + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + + + + +```python +# 타입을 boolean 에서 int로 변경해 줍니다. +df['votes_pos_neg'] = df['votes_pos_neg'].astype(int) +``` + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + + + + +```python +df.head() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idstartendansweredvotescategorytitlecontentvotes_pos_neg
13342017-08-192017-09-180679기타『국가유공자 등 예우 및 지원에 관한법률』상「6.25전몰군경 자녀수당」의 불합리한 ...(현황)\n우리들 아버지께서는 67여년전 북의 남침으로 조국이 위기에 처했을 때 젊...1
16372017-08-192017-09-180415기타황우석박사님 연구재개 허용 촉구합니다.국민의 70% 이상이 황우석박사님을 응원하고 지지하고 있습니다.\n*2007년 1월...1
18402017-08-192017-09-180218외교/통일/국방국가유공자등 예우및 지우너에 관한 법률 시행령 개정지금부터 67년전 1950년 6.25전쟁때 조국 대한민국이 위태로운 시점에 우리들 ...0
19412017-08-192017-09-180227외교/통일/국방국가유공자등 예우및 지우너에 관한 법률 시행령 개정지금부터 67년전 1950년 6.25전쟁때 조국 대한민국이 위태로운 시점에 우리들 ...0
20422017-08-192017-09-180173육아/교육기간제 교사의 정규직화를 반대합니다.대통령님, 안녕하세요. 저는 임용을 준비하고 수험생입니다. 처음 기간제 정규직화 된...0
+
+ + + +# 전처리 하기 + + +```python +def preprocessing(text): + # 개행문자 제거 + text = re.sub('\\\\n', ' ', text) + # 특수문자 제거 + # 특수문자나 이모티콘 등은 때로는 의미를 갖기도 하지만 여기에서는 제거했습니다. + # text = re.sub('[?.,;:|\)*~`’!^\-_+<>@\#$%&-=#}※]', '', text) + # 한글, 영문, 숫자만 남기고 모두 제거하도록 합니다. + # text = re.sub('[^가-힣ㄱ-ㅎㅏ-ㅣa-zA-Z0-9]', ' ', text) + # 한글, 영문만 남기고 모두 제거하도록 합니다. + text = re.sub('[^가-힣ㄱ-ㅎㅏ-ㅣa-zA-Z]', ' ', text) + return text +``` + + +```python +# 불용어 제거에 따라서 정확도가 달라질 수 있음 +def remove_stopwords(text): + tokens = text.split(' ') + stops = ['수', '현', '있는', '있습니다', '그', '년도', '합니다', '하는', '및', '제', '할', '하고', '더', '대한', '한', '그리고', '월', '저는', '없는', '입니다', '등', '일', '많은', '이런', '것은', '왜','같은', '같습니다', '없습니다', '위해', '한다'] + meaningful_words = [w for w in tokens if not w in stops] + return ' '.join(meaningful_words) +``` + + +```python +# 샘플데이터에 적용 +pre_sample_content = preprocessing(sample_content) +``` + + +```python +pre_sample_content = remove_stopwords(pre_sample_content) +``` + + +```python +%time df['content_preprocessing'] = df['content'].apply(preprocessing) +``` + + Wall time: 908 ms + + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + """Entry point for launching an IPython kernel. + + + +```python +%time df['content_preprocessing2'] = df['content_preprocessing'].apply(remove_stopwords) +``` + + Wall time: 1.23 s + + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + """Entry point for launching an IPython kernel. + + +# 학습세트와 테스트세트 만들기 +* 학습세트와 테스트세트를 7:3의 비율로 나눠 줍니다. + + +```python +df = df.reindex() # 인덱스를 새로 생성 +``` + + +```python +df.shape +``` + + + + + (2922, 11) + + + + +```python +split_count = int(df.shape[0] * 0.7) +split_count +``` + + + + + 2045 + + + + +```python +df_train = df[:split_count] +df_train.shape +# 70%의 데이터를 학습데이터로 담아둠 +# 70%의 데이터(학습데이터)로 30%의 데이터(실헙데이터)를 예측 +``` + + + + + (2045, 11) + + + + +```python +df_train.head() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idstartendansweredvotescategorytitlecontentvotes_pos_negcontent_preprocessingcontent_preprocessing2
7282017-08-192017-08-2602137경제민주화소액주주를 보호해주십시오** 존경하옵는 문재인대통령님께\n저는 중국원양자원이라는 KOSPI상장사의 소액 ...0존경하옵는 문재인대통령님께 저는 중국원양자원이라는 KOSPI상장사의 소액 주...존경하옵는 문재인대통령님께 중국원양자원이라는 KOSPI상장사의 소액 주주입니...
13342017-08-192017-09-180679기타『국가유공자 등 예우 및 지원에 관한법률』상「6.25전몰군경 자녀수당」의 불합리한 ...(현황)\n우리들 아버지께서는 67여년전 북의 남침으로 조국이 위기에 처했을 때 젊...0현황 우리들 아버지께서는 여년전 북의 남침으로 조국이 위기에 처했을 때 젊은...현황 우리들 아버지께서는 여년전 북의 남침으로 조국이 위기에 처했을 때 젊은...
21432017-08-192017-09-18011293육아/교육기간제 교사의 정규직화를 반대합니다.대통령님, 안녕하세요. 저는 임용을 준비하고 수험생입니다. 처음 기간제 정규직화 된...1대통령님 안녕하세요 저는 임용을 준비하고 수험생입니다 처음 기간제 정규직화 된...대통령님 안녕하세요 임용을 준비하고 수험생입니다 처음 기간제 정규직화 된다고 ...
24462017-08-192017-09-1801933육아/교육기간제교사의 정규직화를 반대합니다.대통령님, 안녕하세요. 저는 임용을 준비하고 수험생입니다. 처음 기간제 정규직화 된...0대통령님 안녕하세요 저는 임용을 준비하고 수험생입니다 처음 기간제 정규직화 된...대통령님 안녕하세요 임용을 준비하고 수험생입니다 처음 기간제 정규직화 된다고 ...
28502017-08-192017-10-1801251일자리치과위생사 국가고시 날짜 변경 억울합니다안녕하십니까? 대통령님 간단하게 제소개 부터 하겠습니다. 저는 치위생과 3학년 학생...0안녕하십니까 대통령님 간단하게 제소개 부터 하겠습니다 저는 치위생과 학년 학생...안녕하십니까 대통령님 간단하게 제소개 부터 하겠습니다 치위생과 학년 학생입니다...
+
+ + + + +```python +# 학습 세트에서 투표수가 평균보다 많은 건 +df_train.loc[df_train['votes_pos_neg'] == 1].shape +``` + + + + + (439, 11) + + + + +```python +df_test = df[split_count:] +df_test.shape +``` + + + + + (877, 11) + + + + +```python +df_test.head() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idstartendansweredvotescategorytitlecontentvotes_pos_negcontent_preprocessingcontent_preprocessing2
1677432078262018-04-212018-05-2101825인권/성평등경찰 성평등교육, 인성교육의무화뺑소니사고를 당해서 경찰에 신고를 했습니다.\n도착한 경위님과 대화중 계속 아가씨 ...0뺑소니사고를 당해서 경찰에 신고를 했습니다 도착한 경위님과 대화중 계속 아가씨 아...뺑소니사고를 당해서 경찰에 신고를 했습니다 도착한 경위님과 대화중 계속 아가씨 아...
1677662078522018-04-212018-05-210752인권/성평등법무부 검찰과장 권순정의 파면을 요구합니다.서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...0서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...
1677842078702018-04-212018-05-2101089행정강원도 고성군 거진앞바다 2.5마일 해역에 승조원 17명(경찰관 9명, 의무전투경찰...존경하는 국민여러분! 존경하는 대통령님!\n강원도 고성군 거진앞바다 2.5마일 해역...0존경하는 국민여러분 존경하는 대통령님 강원도 고성군 거진앞바다 마일 해역에...존경하는 국민여러분 존경하는 대통령님 강원도 고성군 거진앞바다 마일 해역에...
1678182079062018-04-212018-05-2101965기타[묻재] 황x미 경찰의 파면을 청원합니다밀양 집단 강간 사건을 기억하십니까?\n이때 평생 잊을 수 없는 상처를 받는 피해자...0밀양 집단 강간 사건을 기억하십니까 이때 평생 잊을 수 없는 상처를 받는 피해자를...밀양 집단 강간 사건을 기억하십니까 이때 평생 잊을 상처를 받는 피해자를 우롱하고...
1681412083162018-04-212018-05-210673외교/통일/국방일본 자위대 행사와 천황 생일기념식 한국행사 차단◼일본 자위대 행사와 천황 생일기념식 한국행사 차단\n군국주의로 물든 일본, 반성없...0일본 자위대 행사와 천황 생일기념식 한국행사 차단 군국주의로 물든 일본 반성없는...일본 자위대 행사와 천황 생일기념식 한국행사 차단 군국주의로 물든 일본 반성없는...
+
+ + + + +```python +# 테스트 세트에서 투표수가 평균보다 많은 건 +df_test.loc[df_test['votes_pos_neg'] == 1].shape +``` + + + + + (172, 11) + + + +# 단어 벡터화 하기 + + +```python +from sklearn.feature_extraction.text import CountVectorizer + +vectorizer = CountVectorizer(analyzer = 'word', # 캐릭터 단위로 벡터화 할 수도 있습니다. + tokenizer = None, # 토크나이저를 따로 지정해 줄 수도 있습니다. + preprocessor = None, # 전처리 도구 + stop_words = None, # 불용어 nltk등의 도구를 사용할 수도 있습니다. + min_df = 3, # 토큰이 나타날 최소 문서 개수로 오타나 자주 나오지 않는 특수한 전문용어 제거에 좋다. + ngram_range=(1, 5), # BOW의 단위를 1~3개로 지정합니다. + max_features = 3000 # 만들 피처의 수, 단어의 수가 된다. (많을수록 좋지만, 많다고 다 좋은건 ㄴㄴ) + # ngram과 max_features의 수 등에 따라서도 정확도가 달라짐 + ) +vectorizer +``` + + + + + CountVectorizer(analyzer='word', binary=False, decode_error='strict', + dtype=, encoding='utf-8', input='content', + lowercase=True, max_df=1.0, max_features=3000, min_df=3, + ngram_range=(1, 5), preprocessor=None, stop_words=None, + strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b', + tokenizer=None, vocabulary=None) + + + + +```python +%%time +train_feature_vector = vectorizer.fit_transform(df_train['content_preprocessing2']) +train_feature_vector.shape +``` + + Wall time: 15.9 s + + + +```python +%%time +test_feature_vector = vectorizer.fit_transform(df_test['content_preprocessing2']) +test_feature_vector.shape +``` + + Wall time: 7.66 s + + + +```python +vocab = vectorizer.get_feature_names() +print(len(vocab)) +vocab[:10] +# 왜 20개의 feature인가? 우리가 최대 feature를 지정해줬기 때문 +# 학습/테스트 데이터의 feature가 같아야 함. 일정 수로 맞춰주어야 함 +``` + + 3000 + + + + + + ['aid', + 'article', + 'articleview', + 'articleview html', + 'articleview html idxno', + 'a씨는', + 'bbk', + 'be', + 'blog', + 'blog naver'] + + + + +```python +dist = np.sum(train_feature_vector, axis=0) + +pd.DataFrame(dist, columns=vocab) +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aidarticlearticleviewarticleview htmlarticleview html idxnoa씨는bbkbeblogblog naver...휴게시간을희망을힘든힘들게힘들고힘들어힘듭니다힘없는힘을힘이
06296417054542321146140...512110662272833306750
+

1 rows × 3000 columns

+
+ + + + +```python +from sklearn.feature_extraction.text import TfidfTransformer +# 가중치를 적용; Tfidf는 문서에 아주 자주 등장하는 단어 중 큰 의미가 없는 단어 +# 전체 청원에서는 자주 등장하지 않지만, 특정 청원에서 아주 많이 등장하는 단어는 중요한 단어라고 여기는 방식 +transformer = TfidfTransformer(smooth_idf=False) +transformer +``` + + + + + TfidfTransformer(norm='l2', smooth_idf=False, sublinear_tf=False, + use_idf=True) + + + + +```python +%%time +train_feature_tfidf = transformer.fit_transform(train_feature_vector) +train_feature_tfidf.shape +``` + + Wall time: 16.5 ms + + + +```python +%%time +test_feature_tfidf = transformer.fit_transform(test_feature_vector) +test_feature_tfidf.shape +``` + + Wall time: 6.94 ms + + + +```python +test_feature_tfidf.shape +``` + + + + + (877, 3000) + + + +# 랜덤 포레스트로 학습시키기 +* 공식문서 : http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html + + +```python +from sklearn.ensemble import RandomForestClassifier + +# 랜덤포레스트 분류기를 사용 +forest = RandomForestClassifier( + n_estimators = 200, n_jobs = -1, random_state=2018) +forest +# max_leaf_nodes는 오버피팅을 방지할 때 사용함 +# n_jobs는 몇 개의 CPU 코어를 사용하는 것인지 이야기하는 것 (-1은 걔가 가진 최대의 코어를 사용하도록 함) +``` + + + + + RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', + max_depth=None, max_features='auto', max_leaf_nodes=None, + min_impurity_decrease=0.0, min_impurity_split=None, + min_samples_leaf=1, min_samples_split=2, + min_weight_fraction_leaf=0.0, n_estimators=100, n_jobs=-1, + oob_score=False, random_state=2018, verbose=0, + warm_start=False) + + + + +```python +# 학습에 사용할 y_label 을 넣어준다. +y_label = df_train['votes_pos_neg'] +%time forest = forest.fit(train_feature_tfidf, y_label) +``` + + Wall time: 1.74 s + + +# 평가하기 + + +```python +from sklearn.model_selection import KFold +from sklearn.model_selection import cross_val_score +k_fold = KFold(n_splits=10, shuffle=True, random_state=0) +# 학습 데이터를 'n_splits=10'은 10개로 쪼개어서 확인하라 +scoring = 'accuracy' +score = cross_val_score(forest, train_feature_tfidf, y_label, cv=k_fold, n_jobs=-1, scoring=scoring) +score +``` + + + + + array([0.82439024, 0.74634146, 0.77073171, 0.7902439 , 0.75609756, + 0.79901961, 0.83333333, 0.75490196, 0.76960784, 0.78431373]) + + + + +```python +round(np.mean(score)*100,2) +``` + + + + + 78.29 + + + +# 예측 + + +```python +# 테스트 데이터를 넣고 예측한다. +y_pred = forest.predict(test_feature_tfidf) +y_pred[:10] +``` + + + + + array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + + + + +```python +y_pred.shape +``` + + + + + (877,) + + + + +```python +# 예측 결과를 저장하기 위해 데이터프레임에 담아 준다. +output = pd.DataFrame(data={'votes_pos_neg_pred':y_pred}) +output.head() +``` + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
votes_pos_neg_pred
00
10
20
30
40
+
+ + + + +```python +# 0과 1이 어떻게 집계 되었는지 확인한다. +# 실제 데이터에는 답변 대상 건이 있는데 없는 것으로 예측되었다. +output['votes_pos_neg_pred'].value_counts() +``` + + + + + 0 866 + 1 11 + Name: votes_pos_neg_pred, dtype: int64 + + + + +```python +df_test['votes_pos_neg_pred'] = y_pred +``` + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + """Entry point for launching an IPython kernel. + + + +```python +df_test['pred_diff'] = df_test['votes_pos_neg'] - df_test['votes_pos_neg_pred'] +df_test.head() +# 실제 데이터에서 예측한 내용을 뺌 +``` + + C:\Users\rlath\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: + A value is trying to be set on a copy of a slice from a DataFrame. + Try using .loc[row_indexer,col_indexer] = value instead + + See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy + """Entry point for launching an IPython kernel. + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
article_idstartendansweredvotescategorytitlecontentvotes_pos_negcontent_preprocessingcontent_preprocessing2votes_pos_neg_predpred_diff
1677432078262018-04-212018-05-2101825인권/성평등경찰 성평등교육, 인성교육의무화뺑소니사고를 당해서 경찰에 신고를 했습니다.\n도착한 경위님과 대화중 계속 아가씨 ...0뺑소니사고를 당해서 경찰에 신고를 했습니다 도착한 경위님과 대화중 계속 아가씨 아...뺑소니사고를 당해서 경찰에 신고를 했습니다 도착한 경위님과 대화중 계속 아가씨 아...00
1677662078522018-04-212018-05-210752인권/성평등법무부 검찰과장 권순정의 파면을 요구합니다.서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...0서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...서지현 검사의 검찰과장과 면담내용이 법무부 발표와 전혀 다르다는것을 알게 되었습니다...00
1677842078702018-04-212018-05-2101089행정강원도 고성군 거진앞바다 2.5마일 해역에 승조원 17명(경찰관 9명, 의무전투경찰...존경하는 국민여러분! 존경하는 대통령님!\n강원도 고성군 거진앞바다 2.5마일 해역...0존경하는 국민여러분 존경하는 대통령님 강원도 고성군 거진앞바다 마일 해역에...존경하는 국민여러분 존경하는 대통령님 강원도 고성군 거진앞바다 마일 해역에...00
1678182079062018-04-212018-05-2101965기타[묻재] 황x미 경찰의 파면을 청원합니다밀양 집단 강간 사건을 기억하십니까?\n이때 평생 잊을 수 없는 상처를 받는 피해자...0밀양 집단 강간 사건을 기억하십니까 이때 평생 잊을 수 없는 상처를 받는 피해자를...밀양 집단 강간 사건을 기억하십니까 이때 평생 잊을 상처를 받는 피해자를 우롱하고...00
1681412083162018-04-212018-05-210673외교/통일/국방일본 자위대 행사와 천황 생일기념식 한국행사 차단◼일본 자위대 행사와 천황 생일기념식 한국행사 차단\n군국주의로 물든 일본, 반성없...0일본 자위대 행사와 천황 생일기념식 한국행사 차단 군국주의로 물든 일본 반성없는...일본 자위대 행사와 천황 생일기념식 한국행사 차단 군국주의로 물든 일본 반성없는...00
+
+ + + + +```python +pred_diff = df_test['pred_diff'].value_counts() +pred_diff +# 0이라는 것은 예측했다는 이야기 +``` + + + + + 0 700 + 1 169 + -1 8 + Name: pred_diff, dtype: int64 + + + + +```python +print('전체 {}건의 데이터 중 {}건 예측'.format(y_pred.shape[0], pred_diff[0])) +``` + + 전체 877건의 데이터 중 700건 예측 + + + +```python +acc = ( pred_diff[0] / y_pred.shape[0] ) *100 +print('예측 비율 {}'.format(acc)) +``` + + 예측 비율 79.81755986316989 + diff --git a/soryeongk/180727_Machine_Learning_Predict.md b/soryeongk/180727_Machine_Learning_Predict.md new file mode 100644 index 0000000..8b9a93e --- /dev/null +++ b/soryeongk/180727_Machine_Learning_Predict.md @@ -0,0 +1,23 @@ +# 기계 학습 + +1959년, 아서 사무엘은 기계 학습을 +``` +"기계가 일일이 코드로 명시하지 않은 동작을 데이터로부터 학습하여 실행할 수 있도록 하는 알고리즘을 개발하는 연구 분야" +``` +라고 정의하였다. + +## 일반화 +기계 학습에서의 일반화는 훈련 이후 새롭게 들어온 "데이터를 정확히 처리할 수 있는 능력"을 말한다. + +* 언더 피팅 : 학습이 제대로 안된 상태 +* 오버 피팅 : 특정 데이터에는 거의 정확한데, 다른 데이터에는 맞지 않는 경우 + ex. 상권 데이터에는 맞는데, 주거 데이터에는 맞지 않을 때, 주거 데이터에 오버 피팅되었다고 이야기 함. + +## 기계 학습과 데이터 마이닝 +기계 학습은 훈련 데이터(Training Data)를 통해 학습된 알려진 속성을 기반으로 예측에 초점을 두고 있다. +데이터 마이닝은 데이터의 미처 몰랐던 속성을 발견하는 것에 집중한다. 이는 데이터베이스의 지식 발견 부분의 분석 절차에 해당한다. + + + +# 실습 + diff --git a/soryeongk/180727_Statistics.md b/soryeongk/180727_Statistics.md new file mode 100644 index 0000000..16aafa3 --- /dev/null +++ b/soryeongk/180727_Statistics.md @@ -0,0 +1,266 @@ +# 통계학 + +## 회귀분석은 통계학의 꽃이다! + +``` +매출액 = 1.5*티비광고비 +3*유투브광고비 + 2*페북광고비 -0.5*월요일 + 2.5*일요일 +``` + +회귀분석을 하기 위해서는 몇 가지를 미리 알고 있어야 함 + +1. 정규분포(확률분포) +2. 통계적 추정 +3. 검정 + +## 확률분포 + +통계학과 확률 + +``` +통계는 표본을 바탕으로 모집단을 추론하는 것 +따라서, 확률이 없으면 의미가 없음 +``` + +* 확률 : 근원사건들이 일어날 가능성이 모두 같을 떄, 사건이 일어날 확률 +* 확률의 특징 + * 확률은 0~1의 값을 갖는다. + * 모든 사건에 대한 확률의 합은 1이다. + +이산확률변수 - 확률분포표 + +> 발생할 사건에 대해 확률을 나열한 것 + +연속확률변수 - 확률밀도함수 + +> 확률의 밀도가 어느 구간에 더 높고 어느 구간에 더 낮게 분포하는지를 나타냄 +> +> 영역으로 확률을 구함 + +## 정규분포 + +* 키, 몸무게, 강수량, 시험 점수 등 자연현상이나 사회현상과 관련된 연속확률변수의 확률밀도함수의 그래프는 정규분포와 비슷한 형태 +* 정규분포는 평균을 중심으로 좌우 대칭인 종 모양의 곡선을 띄고 있음 +* 평균과 분산만으로 특성을 모두 다 설명가능 +* 정규분포의 특징 + +``` +평균 = 최빈값 = 중앙값 +평균을 중심으로 자우대칭 +확률이 m을 중심으로 +-2s안에 거의 집중되어 있음(95.4%) + m : 분포의 중심을 나타내는 위치 모수 + s : 평균으로부터 퍼져있는 정도를 나타내는 모수 +``` + +> 이번 수학 시험점수의 평균은 60점 (총 100명) 표준편차 5점 +> +> 나는 75점 (평균보다는 높음) +> +> 학생 중 95명 정도는 50~70점을 맞았을 것. +> +> 75점은 상위 2.5% 왜? - 직접 해보기 + +**평균과 분산에 따라 정규분포 모양은 달라지므로 비교하기 곤란** + +## 표준정규분포 + +정규분포의 표준화 + +``` +정규분포에서는 평균과 표준편차에 따라서 특정 영역의 넓이가 다르므로 두 그룹의 비교를 위해선 하나의 기준으로 재배치 해야 함 +``` + +* NORMSDIST(Z)는 z값의 확률을 RETURN + * NORMSDIST(0) = 0.5 + * NORMSDIST(1) = 0.84 + * NORMSDIST(1.65) = 0.95 +* NORMSINV(X)는 확률이 x가 나오는 Z값을 RETURN + * NORMSINV(0.5) = 0 + * NORMSINV(0.84) = 1 + * NORMSINV(0.95) = 1.645 + +## 표집분포 + +통계적 추론 : 표본을 통해 모집단을 예측하려면 둘 사이의 연결고리가 필요 + +* 모집단(population) + * 모수(parameters) : 모집단으로부터 계산된 값. + * 전수조사를 하지 않는 한, 절대 알 수 없는 미지의 수 +* 표본(sample) + * 통계량(statistics) : 표본으로부터 계산된 모든 값 + * 일반적으로 통계량을 가지고 모수를 추정함 + +> 표본평균들의 평균은 모평균과 같음 +> +> 표본평균들의 분산은 (모분산/표본의크기)와 같음 + +## 중심극한의 정리 + +![중심극한의정리](./Photo/0727_01.png) + +**보통 100 이상이 되어야 n이 크다고 말함** + +## 실습 + +log(참여인원(votes))로 중심극한의 정리 확인 + +1. log(참여인원(votes))의 평균과 분산을 구하고 히스토그램 그리기 +2. log(참여인원(votes)) 중 랜덤하게 100개의 표본을 추출한 후 평균 구하기 + 1. rand()함수를 이용해 random number 생성 + 2. rank(값, 데이터, [오름차순])함수를 이용해 ranking 부여 + 3. query문을 이용해 100개 추출 = average(query(범위, “select votes where rank < 101")) +3. 값만 복사한 후, 2번 과정을 50번 재시도(복사하면, 값이 바뀌어 있음) +4. 표본평균들의 평균과 분산 히스토그램 그리기 +5. 모수와 통계량을 비교하고, 중심극한의 정리를 따르는지 확인 + +## 통계적 추론 + +``` +표본이 갖고 있는 정보를 이용하여 모수에 관한 결론을 유도하고 모수에 대한 가설의 옳고 그름을 판단하는 것 + +조사자의 관심에 따라 + +1. 모수의 추정 +2. 모수에 대한 가설검정 + +이라는 두 가지 문제로 나눌 수 있음 +``` + +> 1. 점추정 : 전체 고등학생의 평균키를 하나의 값으로 추정 +> 2. 구간추정 : 전체 고등학생의 평균키를 포함할 만한 적당한 구간을 정함 +> 3. 가설검정 : 전체 고등학생의 평균키가 5년 전의 평균값인 155cm와 다른지를 판단 + +![모평균에대한점추정](./Photo/0727_02.png) + +* 표준편차(standard deviation) : 데이터의 흩어진 정도를 평가하는 도구로써, 평균으로부터 표본들의 흩어져 있는 산포도를 나타냄 +* 표준오차 (standard error) : 모평균을 추정했을 시, 그 추정량은 표본으로부터 모집단을 추론한 것이기 때문에 완전하다고 할 수 없다. 따라서, 그 불완전성에 대한 오차를 의미함 +* 신뢰구간 = (표본의 평균 - 2\*표준오차, 표본의 평균 + 2\*표준오차) + +> 점추정 +> +> * 모평균 추정 <- 표본의 평균 +> * 표준오차 <- 표본의 표준편차/(표본의 개수) + +## 가설검정 + +``` +스타벅스의 자바 칩 프라푸치노는 Tall/355ml(12floz)에 340kcal라고 알려져 있다. 하지만,절대미각인 내가 마셔본 결과 340kcal보다 높은 것 같다. 따라서, 전국 스타벅스 매장에서 +랜덤으로 50개의 매장에서 파는 자바 칩 프라푸치노의 칼로리를 측정했다. +``` + +``` +✓ 모집단 : 스타벅스의 자바 칩 프라푸치노 +✓ 표본집단 : 무작위로 선택된 50개의 매장의 프라푸치노 +✓ 모수 : 340kcal +✓ 통계량 : 50개 자바 칩 프라푸치노의 평균 칼로리 +``` + +``` +검정하고 싶은 가설 : 스타벅스의 자바 칩 프라푸치노는 340kcal보다 높다. +``` + +> 1. 50개의 프라푸치노의 평균 = 350 +> 2. 50개의 프라푸치노의 표준편차 = 10 +> +> => 프라푸치노의 칼로리는 340일까? + +따라서 + +1. 자바 칩 프라푸치노의 칼로리가 340kcal가 아니라고 주장하기 위해선, 자바칩 프라푸치노의 칼로리가 340kcal라고 하기엔 나오기 힘들 정도로 큰 값이 나오면 된다. +2. 즉, 충분히 큰 값인 c에 대해 Xത ≥ c 의 형태를 가질 때, 자바 칩 프라푸치노의 칼로리가 340kcal보다 높다고 할 수 있다. + +충분히 큰 c의 기준은? + +- c는 μ(푸라푸치노 칼로리)= 340이라면 거의 나오지 않을 정도의 값을 가져야 함 + +- 5%의 확률이 거의 나오지 않을 정도의 확률이라고 했을 때, 아래의 식에서 c보다 큰 경우를 ‘충분히’ 큰 경우라고 함 + + ​ P[Xത ≥ c] = 0.05 + +- Xത가 c보다 큰 경우에 이를 ‘충분히’ 큰 값이라 보고 μ(푸라푸치노의 칼로리)가 340보다 크다고 주장할 수 있음 + +## 가설검정 + +> 가설검정 단계 +> +> 1. 가설을 수립 +> +> 2. 유의수준을 결정(내가 정하는 것) : 모수의 추정이 맞지 않을 확률을 결정 +> +> 일반적으로 유의수준은 5%로 설정 +> +> 3. 기각역 설정 : 가설의 기각여부를 결정하는 범위계산 +> +> 유의수준이 결정되면 자동적으로 계산됨 +> +> 4. 통계량의 계산 : 표본의 통계량을 이용해 가설검정 +> +> 5. 의사결정 : 기각을 할지, 못 할지 결정 + +가설의 정의 + +``` +주어진 사실 혹은 조사하고자 하는 사실이 어떠하다는 주장이나 추측 +``` + +* 귀무가설(Null Hypothesis, H0) + * 연구자가 증명하고자 하는 실험가설과 반대되는 입자, 증명되기 전까지는 효과도 없고 차이도 없다는 영가설 + * 효과/차이가 없다. + * 깔라만시가 다이어트에 효과가 없다. +* 대립가설(Alternative Hypothesis, H1) + * 귀무가설의 반대로 연구자가 실험을 통해 규명하고자 하는 가설 + * 효과/차이가 있다/크다/작다. + * 깔라만시가 다이어트에 효과가 있다. + +### 양측검정 & 단측검정 + +``` +양측검정(two-side test) : 대립가설이 어떤 특정 모수랑 같지 않음을 검정 +``` + +> ex) 대립가설 : 스타벅스 자바 칩 프라푸치노의 칼로리는 340kcal가 아니다. + +``` +단측검정(one-side test) : 대립가설이 어떤 특정 모수 이상이거나 이하를 검정 +``` + +> ex1) 대립가설 : 스타벅스 자바 칩 프라푸치노의 칼로리는 340kcal보다 크다. +> +> ex2) 대립가설 : 스타벅스 자바 칩 프라푸치노의 칼로리는 340kcal보다 작다. + +### 유의수준 & 기각역 + +- 유의수준(α) : 귀무가설이 실제로 참일 때, 귀무가설에 대한 판단의 오류 수준데이터로부터 얻어지는 값이 아니라, 가설검정을 하기전에 미리 정해야 하는 값 + - 일반적으로 5%로 설정 +- 기각역∶ 귀무가설을 기각하게 되는 영역 + +> 기각역에 **검정통계량**이 포함되는 경우 : 귀무가설 기각, 대립가설 채택 +> +> 채택역에 **검정통계량**이 포함되는 경우 : 귀무가설 채택, 대립가설 기각 + +### 모평균에 대한 검정 + +``` +표본의 크기가 클 때 모평균 μ에 대한 가설 H0 ∶ μ = μ0를 검정하기 위한 검정통계량은 다음과 같음 +``` + +> Z = (Xത − μ0) / (s/ n) + +``` +검정통계량의 분포는 H0가 하에서 N(0, 1)을 따른다. 각 대립가설에 대하여 유의수준 α를 갖는 기각역은 다음과 같다. +``` + +![모평균에대한검정예시](./Photo/0727_03.png) + +### 검정통계량 & 유의확률 + +* 검정통계량 : 가설검정을 위해 사용되는 주요 표본 통계량 +* 유의확률(p-value) : 귀무가설(null hypothesis, H0)이 맞다는 전제 하에, 통계값(statistics)이 실제로 관측된 값 이상일 확률 + +``` +왜 유의수준은 10%, 20%가 아니라, 5%로 결정하는 것일까? +``` + +![유의수준에대한설명](./Photo/0727_03.png) + +![1종오류가중요한이유](./Photo/0727_05.png) + diff --git a/soryeongk/180802_Special_Lecture.md b/soryeongk/180802_Special_Lecture.md new file mode 100644 index 0000000..0d96471 --- /dev/null +++ b/soryeongk/180802_Special_Lecture.md @@ -0,0 +1,93 @@ +# 지그재그 데이터 분석가 박인성님 특강 + +## 1. 지그재그 & 데이터 팀 소개 + +**지그재그 : 여성쇼핑몰 모음, 쇼핑몰 순위** + +* 여성의류 쇼핑몰 메타 서비스 +* 쇼핑몰 즐겨찾기, 상품 검색, 배송 추적 기능 +* 사용자 패턴 분석을 통한 쇼핑몰 및 상품 추천 + +> 다운로드 수 1000만 돌파, MAU(월간 이용자수) 200만 돌파 + +**크로키 닷컴 데이터 팀** + +* Raw 데이터를 다양한 분석 니즈에 맞게 추출/변환/적재 +* **사내 다양한 팀과 협업하여 각 팀의 주요 의사결정 지원** +* 서비스 관련 지표 모니터링 및 대시보드 제작/운영 +* 머신/딥러닝 알고리즘 리서치 및 적용 테스트 + + + +## 2. 데이터 팀 프로젝트 진행 과정 + +1. 문제 정의 +* 분석 과제 수행이 필요한 주제 선정(추상적 주제) - 사람들이 잘 쓰고 있나요? +* **주제를 구체화하여 데이터로 정의** +2. 데이터 수집 및 전처리 +* 데이터 스토리지에 접속해 이용자 로그 수집 +* 앞서 정의했던 구조에 맞게 데이터 전처리**(시간 효율성 고려)** +3. 데이터 탐색 및 분석 +* 데이터 탐색을 통해 정의한 문제 분석 +* **분석결과 시각화 (중요 포인트 위주)** - 직관적으로 이해하기 쉽게 +4. 분석 결과 공유 +* 관련 팀원에게 **분석 데이터 공유 및 결과 브리핑** - 이해하기 쉽도록 하는 것이 중요 +* 분석 결과 피드백 수집 및 후속 분석 기획 + + + +## 3. 데이터 팀 업무 인프라(feat. 마케팅 팀) + +1. 마케팅팀이 하는 일 + +* 마케팅 채널을 통한 광고 집행 +* 마케팅 성과 측정 솔루션 + +2. 데이터팀이 하는 일 + + (1) 데이터 처리, 분석 시스템 + + (2) 서비스 이용자 로그 데이터 + +(2)를 통해 로그데이터를 추출, (1)을 통해 로그데이터 변환후 JOIN, 업로드 + + + +## 4. 지그재그 리뉴얼 프로젝트 + +> 작년 10월까지 지그재그는 수익모델이 없음 +> +> 수익모델이 앱에 반영될 방식을 고민한 결과. 앱 첫 번째 영역에 광고 영역을 새롭게 추가하기로 결정 +> +> 기존 '쇼핑몰 랭킹'에서 앱 첫 번째 영역에 광고 영역을 새롭게 추가 + +새롭게 개발하는 광고 영역에 적용할 상품 노출 방법 2가지 (이미지 위주, 가격도 보여주기) + +> 예상할 수 있는 각타입의 장단점이 존재하고, 이를 확인하기 위해서 A/B 테스트를 진행 + +1. 앱 전체 영영 관점 + * 이용자의 이탈이 존재? + * 주요 액션에 변화? + * 기존 영역 중 영향을 받는 곳의 유무? +2. 광고 영역 관점 + * 상품이 많이 노출되는 타입은 무엇 + * 많이 클릭되는 타입은 무엇 + * 내 상품 추가를 많이하는 타입 + * 이탈률이 낮은 타입은 무엇 + +``` +전체 앱 이용자 중 5%를 랜덤 추출하여 리뉴얼 버전 앱 업데이트 배포 +배포 후 이용자 데이터 모니터링 +``` + + + +## 5. 데이터 팀에게 중요한 점 + +1. 보통 추상적인 분석 과제가 들어옵니다. **과제를 구체화하는 능력**이 중요합니다. +2. 데이터 용량 이슈보다 **데이터 처리 시간 이슈**가 더 중요합니다. +3. 탐색하면서 **빈도표, 히스토그램, 박스플롯**을 정말 많이 씁니다. +4. 보고서에 **선형/막대 그래프**를 많이 쓰고, 대부분 편하게 볼 수 있습니다. +5. 다른 팀에게 분석 결과를 공유할 떄, **최대한 쉽게 전달하는 것이 중요**합니다. +6. 대부분 **서버 안에서 작업**이 이뤄집니다. 엔지니어 파트를 간과하면 안됩니다. + diff --git a/soryeongk/Photo/0727_01.png b/soryeongk/Photo/0727_01.png new file mode 100644 index 0000000..c455f71 Binary files /dev/null and b/soryeongk/Photo/0727_01.png differ diff --git a/soryeongk/Photo/0727_02.png b/soryeongk/Photo/0727_02.png new file mode 100644 index 0000000..cf67e88 Binary files /dev/null and b/soryeongk/Photo/0727_02.png differ diff --git a/soryeongk/Photo/0727_03.png b/soryeongk/Photo/0727_03.png new file mode 100644 index 0000000..14f6598 Binary files /dev/null and b/soryeongk/Photo/0727_03.png differ diff --git a/soryeongk/Photo/0727_04.png b/soryeongk/Photo/0727_04.png new file mode 100644 index 0000000..66b7b65 Binary files /dev/null and b/soryeongk/Photo/0727_04.png differ