<jupyter_start><jupyter_text>Классификация текста по канонам Соберём данные заново и помимо классификации сделаем визуализацию.Класса будет два: Алкомодель и РИА новости; разница будет существенная.Только на этот раз всё сделаем по гайду от sklearn:http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html<jupyter_code>from get_tweets import get_tweets
import csv
example_string = "@huabf Get Rid of those каРапузов !"
def purify(str):
    # delete all URLs
    str = re.sub(r'\w+:\/{2}[\d\w-]+(\.[\d\w-]+)*(?:(?:\/[^\s/]*))*', '', str, flags=re.MULTILINE)
    #delete all usernames
    str = re.sub(r'@\w+', '', str)
    return str.lower()
print(purify(example_string))
accounts = ["alcomodel", "rianru"]
def generate_data(accounts):
    train_data = []
    for account in accounts:
        with open("unsorted/{0}_tweets.csv".format(account)) as fp:
            raw_data = csv.reader(fp, delimiter = '|')
            for line in raw_data:
                if line[0:1] != "RT":       #ignore retweets
                    train_data.append([purify(line[3]), account])
    train_target = [train_data[i][1] for i in range(len(train_data))]
    train_data = [train_data[i][0] for i in range(len(train_data))]
    return train_data, train_target
train_data, train_target = generate_data(accounts)
print(len(train_data))
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(train_data)
X_train_counts.shape
from sklearn.feature_extraction.text import TfidfTransformer
tf_transformer = TfidfTransformer()
X_train_tf = tf_transformer.fit_transform(X_train_counts)
X_train_tf.shape
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB().fit(X_train_tf, train_target)<jupyter_output><empty_output><jupyter_text>Теперь можно заставить классификатор предсказывать<jupyter_code>def predict(str, clf):
    X_new_counts = count_vect.transform(str)
    X_new_tfidf = tf_transformer.transform(X_new_counts)
    
    predicted = clf.predict(X_new_tfidf)
    
    for doc, category in zip(str, predicted):   
        print("%r => %s" % (doc, category))
test_data = []
test_data.append("Ладно, допустим, лёд между нами уже растаял, А ЖИР-ТО МОЙ КОГДА НАЧНЁТ ТАЯТЬ???!!! Или это не так работает?")
test_data.append("Меня чуть не сбил велосипедист на пешеходном переходе. Ладно. Хорошо.")
test_data.append("Премьер Франции заявил, что Ферран останется в кабмине, несмотря на скандал")
print(predict(test_data, clf))<jupyter_output>'Ладно, допустим, лёд между нами уже растаял, А ЖИР-ТО МОЙ КОГДА НАЧНЁТ ТАЯТЬ???!!! Или это не так работает?' => alcomodel
'Меня чуть не сбил велосипедист на пешеходном переходе. Ладно. Хорошо.' => alcomodel
'Премьер Франции заявил, что Ферран останется в кабмине, несмотря на скандал' => rianru
None<jupyter_text>Попытка визуализации<jupyter_code>print(X_train_counts.toarray()[0:199].shape[0])
X1 = np.sum(X_train_tf.toarray()[0:199], axis=0)
X2 = np.sum(X_train_tf.toarray()[200:399], axis=0)
print(len(X1), len(X2))
plt.figure()
plt.scatter(range(len(X1)), X1, color = "blue")
plt.scatter(range(len(X2)), X2, color = "red")
plt.show()<jupyter_output><empty_output><jupyter_text>Обучение на всех имеющихся классах Для начала превратим все имеющиеся у нас данные в один документ с форматом ["класс", "твит"] Вариант для собранных данных. P.S. Вариант для сбора данных уже есть в collect data.ipynb<jupyter_code>import os
train_data = []
for cat in os.listdir("classes"):
    if cat[0] != '.':
        for account in os.listdir("classes/%s" % cat):
            with open("classes/%s/%s" % (cat, account)) as fp:
                raw_data = csv.reader(fp, delimiter = '|')
                for line in raw_data:
                    if line[0:1] != "RT":    # ignore retweets
                        train_data.append([str(purify(line[3])), cat])
train_target = [train_data[i][1] for i in range(len(train_data))]
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform([train_data[i][0] for i in range(len(train_data))])
X_train_counts.shape
from sklearn.feature_extraction.text import TfidfTransformer
tf_transformer = TfidfTransformer()
X_train_tf = tf_transformer.fit_transform(X_train_counts)
X_train_tf.shape
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB().fit(X_train_tf, train_target)
def predict(arr, clf):
    X_new_counts = count_vect.transform(arr)
    X_new_tfidf = tf_transformer.transform(X_new_counts)
    
    predicted = clf.predict(X_new_tfidf)
    
    for doc, category in zip(arr, predicted):   
        print("%r => %s" % (doc, category))
def test_perfomance(test_data, clf=clf):
    data = [test_data[i][0] for i in range(len(test_data))]
    target = [test_data[i][1] for i in range(len(test_data))]
    X_new_counts = count_vect.transform(data)
    X_new_tfidf = tf_transformer.transform(X_new_counts)

    predicted = clf.predict(X_new_tfidf)
    
    counter_total = 0
    counter_correct = 0
    for doc, category, tar in zip(data, predicted, target):
        counter_total += 1
        if category == tar:
            counter_correct += 1
    print("Всего: %s, Правильно: %s" % (counter_total, counter_correct))
    print("Вероятность правильного определения: %.2f%%" % (counter_correct/counter_total*100), )
test_perfomance(train_data, clf)<jupyter_output>Всего: 26993, Правильно: 22499
Вероятность правильного определения: 83.35%<jupyter_text>Построим Pipeline, таким образом объединим токенизацию, векторизацию и функцию весов в одну функцию. from sklearn.pipeline import Pipelinetext_clf = Pipeline([('vect', CountVectorizer()),                     ('tfidf', TfidfTransformer()),                     ('clf', MultinomialNB()),])data = [train_data[i][0] for i in range(len(train_data))]target = [train_data[i][1] for i in range(len(train_data))]text_clf.fit(data, target)<jupyter_code>from sklearn.linear_model import SGDClassifier
svm_clf = SGDClassifier(loss = 'perceptron', n_iter=10)
svm_clf.fit(X_train_tf, train_target)<jupyter_output><empty_output><jupyter_text>predicted = text_clf.predict(train_data)np.mean(predicted == train_arget)<jupyter_code>test_perfomance(train_data, svm_clf)<jupyter_output>Всего: 26993, Правильно: 26278
Вероятность правильного определения: 97.35%<jupyter_text>Опреление пола пользователя Имеется массив данных с бинарным разделением признаков: пользователь мужчина и пользователь женщина.Попробуем из этих данных узнать пол пользователя<jupyter_code>gender_data = []
for cat in os.listdir("gender"):
    if cat[0] != '.':
        for account in os.listdir("gender/%s" % cat):
            with open("gender/%s/%s" % (cat, account)) as fp:
                raw_data = csv.reader(fp, delimiter = '|')
                for line in raw_data:
                    if line[0:1] != "RT":    # ignore retweets
                        gender_data.append([purify(line[3]), cat])
gender_target = [gender_data[i][1] for i in range(len(gender_data))]
print(gender_data[4][0])
from sklearn.pipeline import Pipeline
gender_clf = Pipeline([('vect', CountVectorizer()),
                     ('tfidf', TfidfTransformer()),
                     ('clf', SGDClassifier(loss='perceptron', penalty='l2',
                                           alpha=1e-3, n_iter=5, random_state=42)),
])
text_gender = [str(gender_data[i][0]) for i in range(len(gender_data))]
print(str(text_gender[0]))
gender_clf = gender_clf.fit(text_gender, gender_target)
predicted = gender_clf.predict(text_gender)
np.mean(predicted == gender_target)<jupyter_output><empty_output><jupyter_text>Получение результатов<jupyter_code>from get_tweets import get_tweets<jupyter_output><empty_output><jupyter_text>Теперь необходимо сделать вывод полученной информации для выбранного пользователем акканута твиттер<jupyter_code>import matplotlib.pyplot as plt
from collections import Counter
import tweepy
import config

auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
auth.set_access_token(config.access_key, config.access_secret)

api = tweepy.API(auth)

def classify(username):
    get_tweets(username, folder = "unsorted")
    tweets = []
    with open("unsorted/{0}_tweets.csv".format(username)) as fp:
        raw_data = csv.reader(fp, delimiter = '|')
        for line in raw_data:
            if line[0:1] != "RT":       #ignore retweets
                tweets.append(purify(line[3]))
    #tweets are ready
    X_new_counts = count_vect.transform(tweets)
    X_new_tfidf = tf_transformer.transform(X_new_counts)
    
    predicted = clf.predict(X_new_tfidf)
    result = []
    for doc, category in zip(tweets, predicted):
        result.append(category)
    z = Counter(result)
    
    print("\n")
    user = api.get_user(username)

    print(user.name, ", ", user.followers_count, "подписчиков.")
    print("Интересы: ")
    
    labels = list(z)
    values = list(z.values())
    explode = [np.log(x)/50 for x in values]
    
    plt.pie(values, labels = labels, explode = explode,
        autopct='%1.1f%%', shadow=True, startangle=140)
 
    plt.axis('equal')
    plt.show()
    
    for value, label in zip(values, labels):
        print(label, " : %1.1f%%" % (value/len(tweets)*100))
        
    gender_predict = gender_clf.predict(tweets)
    gender_result=[]
    for doc, category in zip(tweets, gender_predict):
        gender_result.append(category)
    print("Gender: ", Counter(gender_result).most_common()[0][0])
classify("brupsen")
classify("medvedevrussia")
classify("kinamanka")
!python3 classify.py
from sklearn.externals import joblib
import matplotlib.pyplot as plt
from collections import Counter
import tweepy
import config
import csv
import sys
from get_tweets import get_tweets
from learn import purify
import numpy as np

auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
auth.set_access_token(config.access_key, config.access_secret)
api = tweepy.API(auth)

def classify(username):
    if len(sys.argv) == 2:
        username = sys.argv[1]
    try:
        text_clf = joblib.load("models/text_model.pkl")
        gender_clf = joblib.load("models/gender_model.pkl")
    except FileNotFoundError:
        sys.exit("Не найден файл модели")
    get_tweets(username, folder="unsorted")
    tweets = []
    with open("unsorted/{0}_tweets.csv".format(username)) as fp:
        raw_data = csv.reader(fp, delimiter='|')
        for line in raw_data:
            if line[0:1] != "RT":  # ignore retweets
                tweets.append(purify(line[3]))

    predicted = text_clf.predict(tweets)
    result = []
    for doc, category in zip(tweets, predicted):
        result.append(category)
    z = Counter(result)
    user = api.get_user(username)
    labels = list(z)
    values = list(z.values())
    explode = [np.log(x) / 50 for x in values]

    plt.pie(values, labels=labels, explode=explode,
            autopct='%1.1f%%', shadow=True, startangle=140)
    plt.axis('equal')

    print("\n")
    print(user.name, ", ", user.followers_count, "подписчиков.")
    print("Интересы: ")

    for value, label in zip(values, labels):
        print(label, " : %1.1f%%" % (value / len(tweets) * 100))

    gender_predict = gender_clf.predict(tweets)
    gender_result = []
    for doc, category in zip(tweets, gender_predict):
        gender_result.append(category)
    print("Пол: ", Counter(gender_result).most_common()[0][0])
    plt.show()
classify("medvedevrussia")
classify("Stalingulag")
classify("mudakoff")
classify("navalny")
classify("meduzaproject")
classify("rianru")
classify("whysodisgusting")
classify("alcomodel")
classify("Narisovana_ka")<jupyter_output>writing to unsorted/Narisovana_ka_tweets.csv


<NAME> ,  242 подписчиков.
Интересы:
{'fraction_non_alphanumeric': 0.12567004169148302, 'fraction_numerical': 0.011656598315323747, 'mean_word_length': 4.212416851441242, 'pattern_counts': {'":': 5, '<': 34, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '582205', 'license': 'MIT', 'n_tokens_mistral': 4419, 'n_tokens_neox': 4479, 'n_words': 856, 'path': 'Canonical.ipynb', 'repo_name': 'shigabeev/Tweet-Classifier', 'size': '11760'}