<jupyter_start><jupyter_text>[Toxic Comment Classification Challenge - Kaggle](https://www.kaggle.com/c/jigsaw-toxic-comment-classification-challenge) 악성 댓글을 식별하고 분류하기* 참고 : https://www.kaggle.com/jagangupta/stop-the-s-toxic-comments-eda<jupyter_code>import pandas as pd 
import numpy as np

# 시각화 
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec 
import seaborn as sns

import re
import string
color = sns.color_palette()
sns.set_style("dark")

%matplotlib inline
train = pd.read_csv("data/train.csv")
train.shape
test = pd.read_csv("data/test.csv")
test.shape
train.tail()
nrow_train = train.shape[0]
nrow_test = test.shape[0]
sum = nrow_train + nrow_test
print("* 전체 데이터에서 학습과 테스트셋의 비율로 학습셋이 약간 더 많다.")
print("       : train  : test")
print("행수    :", nrow_train, ":", nrow_test)
print("전체비율 :", round(nrow_train*100/sum), "    :", round(nrow_test*100/sum))
print("학습셋의 결측치")
null_check=train.isnull().sum()
print(null_check)
print("테스트셋의 결측치")
null_check=test.isnull().sum()
print(null_check)
print("\"unknown\"으로 되어 있는 NA데이터 채우기")
train["comment_text"].fillna("unknown", inplace=True)
test["comment_text"].fillna("unknown", inplace=True)
# 2번째 컬럼부터 데이터를 따로 담아본다.
train.iloc[:,2:].head()
x = train.iloc[:,2:].sum()
x
# row에 등장하는 숫자를 더한다.
rowsums = train.iloc[:,2:].sum(axis=1)
rowsums[:10]
# row의 각 컬럼을 더한수가 0인 데이터는 clean 컬럼을 만들어 담아준다.
train['clean'] = (rowsums==0)
# 악플이 아닌 데이터의 수
train['clean'].sum()

print("전체 코멘트 수 = ",len(train))
print("전체 클린 코멘트 수 = ", train['clean'].sum())
print("전체 태그 =",x.sum())
plt.figure(figsize=(8,4))
ax= sns.barplot(x.index, x.values, alpha=0.8)

plt.title("# per class")
plt.ylabel('# of Occurrences', fontsize=12)
plt.xlabel('Type ', fontsize=12)

# 레이블 추가
rects = ax.patches
labels = x.values
for rect, label in zip(rects, labels):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom')

plt.show()
# 6개 항목 모두를 만족하는 데이터는 31건이다.
x = rowsums.value_counts()
x
plt.figure(figsize = (8,4))
ax = sns.barplot(x.index, x.values, alpha = 0.8,color = color[2])
plt.title("Multiple tags per comment")
plt.ylabel('# of Occurrences', fontsize=12)
plt.xlabel('# of tags ', fontsize=12)

#adding the text labels
rects = ax.patches
labels = x.values
for rect, label in zip(rects, labels):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom')

plt.show()
temp_df = train.iloc[:,2:-1]
temp_df.head()
# 악성댓글의 각 항목이 얼마나 연관관계가 있는지
# obscene 와 threat 은 연관관계가 높다. 다음으로 obscene 와 toxic 도 연관관계가 높다
corr = temp_df.corr()
plt.figure(figsize = (10,8))
sns.heatmap(corr,
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values, annot=True)<jupyter_output><empty_output><jupyter_text>https://pandas.pydata.org/pandas-docs/stable/style.html<jupyter_code># https://pandas.pydata.org/pandas-docs/stable/style.html
def highlight_min(data, color='yellow'):
    '''
    highlight the maximum in a Series or DataFrame
    '''
    attr = 'background-color: {}'.format(color)
    if data.ndim == 1:  # Series from .apply(axis=0) or axis=1
        is_min = data == data.min()
        return [attr if v else '' for v in is_min]
    else:  # from .apply(axis=None)
        is_max = data == data.min().min()
        return pd.DataFrame(np.where(is_min, attr, ''),
                            index=data.index, columns=data.columns)
# Crosstab
# 6개 클래스를 크로스해서 보기는 어렵기 때문에 다른 태그와 함께 유해성을 본다.

main_col="toxic"
corr_mats=[]
for other_col in temp_df.columns[1:]:
    confusion_matrix = pd.crosstab(temp_df[main_col], temp_df[other_col])
    corr_mats.append(confusion_matrix)
out = pd.concat(corr_mats,axis=1,keys=temp_df.columns[1:])

# 체스판처럼 셀 배경색을 구분해 본다.
out = out.style.apply(highlight_min,axis=0)
out
merge = pd.concat([train.iloc[:,0:2],test.iloc[:,0:2]])
df = merge.reset_index(drop=True)
# 각 댓글의 문장 수
df['count_sent'] = df['comment_text'].apply(lambda x: len(re.findall("\n",str(x)))+1)
# 각 댓글의 단어 수
df['count_word'] = df['comment_text'].apply(lambda x: len(str(x).split()))
# 고유한 단어 수
df['count_unique_word'] = df['comment_text'].apply(lambda x: len(set(str(x).split())))
# 글자수
df['count_letters'] = df['comment_text'].apply(lambda x: len(str(x)))
# 구두점 수
df['count_punctuations'] = df['comment_text'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]))
# 대문자 수
df['count_words_upper'] = df['comment_text'].apply(lambda x: len([w for w in str(x).split() if w.isupper()]))
# 타이틀 단어 수
df['count_words_title'] = df['comment_text'].apply(lambda x: len([w for w in str(x).split() if w.istitle()]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17364106988783434, 'fraction_numerical': 0.01272648835202761, 'mean_word_length': 4.703567035670357, 'pattern_counts': {'":': 1, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '442288', 'license': 'MIT', 'n_tokens_mistral': 2148, 'n_tokens_neox': 2275, 'n_words': 403, 'path': 'jigsaw-toxic-comment-classification-challenge/eda.ipynb', 'repo_name': 'jgam/KaggleStruggle', 'size': '4636'}