TowardsDataScience 博客中文翻译 2020(七百一十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

预测员工评论的情绪

原文:https://towardsdatascience.com/predicting-sentiment-of-employee-reviews-ec0c0c837328?source=collection_archive---------33-----------------------

对来自 Indeed.com 的员工评论的正面和负面情绪进行分类

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

奥利维尔·科莱在 Unsplash 上拍摄的照片

在我之前的文章中,我们学习了如何从 Indeed.com 的收集流程分析员工评价。请随意查看并提供反馈。我很想听听你会如何改进代码。特别是,如何动态地克服网站的 HTML 的变化。

在这篇文章中,我想把我们的数据集进一步解决情感分类问题。具体来说,我们将为每个评论分配情感目标,然后使用二元分类算法来预测这些目标。

我们将导入从 Indeed.com 收集的原始员工评论。我建议你回顾一下我以前的文章来了解我们是如何获得这个数据集的。

首先,让我们导入数据集并进行处理。对于此分析,我们只需要“评级”和“评级 _ 描述”列。关于文本预处理更详细的解释,请阅读我的 nlp 预处理文章

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
import seaborn as sns
import contractions
import random
import fasttext
from autocorrect import spell
from nltk.probability import FreqDist
from nltk.tokenize import word_tokenize
import nltk
from nltk.corpus import stopwords, wordnet
from sklearn.feature_extraction.stop_words import ENGLISH_STOP_WORDS
from nltk.stem import WordNetLemmatizer
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold
from imblearn.pipeline import make_pipelinefrom sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import roc_auc_score
from sklearn.metrics import auc
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCVfrom warnings import simplefilter
simplefilter(action='ignore', category=FutureWarning)
pd.set_option('display.max_colwidth', 200)with open('apple_scrape.csv') as f:
    df = pd.read_csv(f)
f.close()print(df.head())df = df[['rating', 'rating_description']]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

消除收缩

df['no_contract'] = df['rating_description'].apply(lambda x: [contractions.fix(word) for word in x.split()])

将单词列表转换为字符串

应用“fix”函数的结果是一个单词列表,我们需要将该列表转换回字符串。

df['rating_desc_str'] = [' '.join(map(str, l)) for l in df['no_contract']]

删除非英语评论

首先,我们将使用“快速文本”库来识别每个评论的语言。使用此链接下载预训练模型。一旦每个评论被标记,我们只需过滤数据框,只包括英文评论。

pretrained_model = "lid.176.bin" 
model = fasttext.load_model(pretrained_model)langs = []
for sent in df['rating_desc_str']:
    lang = model.predict(sent)[0]
    langs.append(str(lang)[11:13])df['langs'] = langsdf.head()df = df[df['langs'] == 'en']

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

符号化

df['tokenized'] = df['rating_desc_str'].apply(word_tokenize)

删除标点符号和特殊字符

df['no_punc'] = df['tokenized'].apply(lambda x: [word for word in x if word.isalnum()])

转换成小写

df['lower'] = df['no_punc'].apply(lambda x: [word.lower() for word in x])

拼写

df['spell'] = df['lower'].apply(lambda x: [spell(word) for word in x])

移除任何数字字符(即整数、浮点数)

df['no_num'] = df['spell'].apply(lambda x: [word for word in x if word.isalpha()])

词汇化

为了将词汇化应用于我们的记号,我们首先需要识别每个单词的词性。接下来,我们需要将从 nltk 获得的标签转换为 wordnet 标签,因为这些是我们的 lemmatizer (WordNetLemmatizer())唯一接受的标签。

df['pos_tags'] = df['no_num'].apply(nltk.tag.pos_tag)def get_wordnet_pos(tag):
    if tag.startswith('J'):
        return wordnet.ADJ
    elif tag.startswith('V'):
        return wordnet.VERB
    elif tag.startswith('N'):
        return wordnet.NOUN
    elif tag.startswith('R'):
        return wordnet.ADV
    else:
        return wordnet.NOUNdf['wordnet_pos'] = df['pos_tags'].apply(lambda x: [(word, get_wordnet_pos(pos_tag)) for (word, pos_tag) in x])wnl = WordNetLemmatizer()
df['lemma'] = df['wordnet_pos'].apply(lambda x: [wnl.lemmatize(word, tag) for (word, tag) in x])

删除停用词

stop_words = set(stopwords.words('english'))
df['stop_removed'] = df['lemma'].apply(lambda x: [word for word in x if word not in stop_words])

删除长度少于 3 个字符的单词

def short_words(words):
    return [word for word in words if len(word) > 2]df['length'] = df['stop_removed'].apply(short_words)

我们剩下的是一个大的 dataframe,它包含我们执行的每个预处理步骤的一列。我更喜欢以这种方式工作,因为我们可以很容易地看到每一步前后的变化。如果你问我的话,会使数据验证更容易。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

决定情绪

我们可以利用像“TextBlob”这样的库。情绪”来计算每个评论的情绪,但由于我们有实际的员工评级,我们可以使用此列来代替。

该员工用 5 分制的李克特量表给公司评分,超过 75%的评分是正面的(即 5 或 4)。此外,5 分制的评分为 3 分(中性),可以是正面的,也可以是负面的。为简单起见,我们将删除中性评级。介于 1 和 2 之间的评分为负,介于 4 和 5 之间的评分为正。

最后,我们将筛选数据帧,使其只包含训练模型所需的列。

def sent(df):
    if df['rating'] <= 2:
        val = 1.0
    elif df['rating'] >= 4:
        val = 0.0
    else:
        val = -1.0
    return valdf['sentiment'] = df.apply(sent, axis=1)df = df.loc[(df['sentiment']==1) | (df['sentiment']==0)]df = df[['rating', 'length', 'sentiment']]
df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将数据可视化

让我们花一点时间,根据每个单词的积极或消极程度(即感悟)。为了完成这项任务,我们需要计算每个独特的单词在积极情感评论和消极情感评论中出现的频率。 最终结果将类似于下面的列表,其中“工作”一词在负面评价中出现了 425 次,在正面评价中出现了 4674 次。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是代码将产生的结果

为了计算上面的列表,我们首先按照情绪降序排列评论,并重置索引。接下来,我们可以看到,我们有 3570 个正面和 1039 个负面的情感评论。现在,我们将数据集分为正面和负面评论,然后创建一个由 3570 个 1 和 1039 个 0 组成的数组。

df.sort_values(by='sentiment', ascending=False, inplace=True)
df.reset_index(inplace=True, drop=True)df_pos = df[df['sentiment'] == 0.0]
df_neg = df[df['sentiment'] == 1.0]targets = np.append(np.ones(len(df_neg)), np.zeros(len(df_pos)))df['sentiment'].value_counts()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来,我们创建一个名为“frequencies”的空字典来存放输出。现在我们迭代 zipped(即。元组)评论和目标数组(3,570 个零和 404 个一)。当我们迭代每个评论中的每个单词时,我们以由单词及其情感组成的元组的形式创建一个对(即。1 或 0)。我们知道有 3,570 个正面评价,因此,只有前 3,570 个评价中的单词将被分配为正面的。剩余的 404 个评论中的所有单词将被指定为负面的。最终结果是单词和情感的元组键的字典,以及作为值的正面和负面词频。

例如,“工作”这个词在所有正面评价中出现了 425 次。

frequencies = {}
for y, words in zip(targets, df['length']):
    for word in words:
        pair = (word, y)
        if pair in frequencies:
            frequencies[pair] += 1
        else:
            frequencies[pair] = 1

print(frequencies)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们需要做的最后一件事是对“频率”字典中的每个单词的正计数和负计数求和。

首先,我们在频率字典键中索引这个单词,创建一个所有单词的列表(存储在“words”中)。接下来,我们初始化 pos_count 和 neg_count 的计数变量。如果元组关键字“单词 1.0”出现在频率字典中(即 work ',1.0)然后我们索引该关键字的值,“neg_count”变量成为该词在负面评论中出现的次数。出现在正面评论中的单词也是如此。最后,我们将单词、pos_count 和 neg_count 添加到“数据”列表中。

words = [word[0] for word in frequencies]
data = []for word in words:
    pos_count = 0
    neg_count = 0

    if (word, 1) in frequencies:
        neg_count = frequencies[(word,1)]
    if (word, 0) in frequencies:
        pos_count = frequencies[(word, 0)]

    data.append([word, neg_count, pos_count])print(data)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如你所看到的,如果我们把所有的单词都画出来,情节会变得有点乱,因此,让我们随机选择几个单词。因为有更多积极的评论,所以情节偏向积极的一面。

fig, ax = plt.subplots(figsize=(20, 15))x = np.log([x[1] + 1 for x in data])
y = np.log([x[2] + 1 for x in data])ax.scatter(x, y)plt.xlabel('Negative Count')
plt.ylabel('Positive Count')for i in range(0, len(data)): 
    ax.annotate(data[i][0], (x[i], y[i]), fontsize=15)    
ax.plot([0,7], [0,7], color='red')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

fig, ax = plt.subplots(figsize=(20, 15))data_rand = random.sample(data, 50)x = np.log([x[1] + 1 for x in data_rand])
y = np.log([x[2] + 1 for x in data_rand])ax.scatter(x, y)plt.xlabel('Negative Count')
plt.ylabel('Positive Count')for i in range(0, len(data_rand)): 
    ax.annotate(data_rand[i][0], (x[i], y[i]), fontsize=15)    
ax.plot([0,7], [0,7], color='red')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特征抽出

我们将创建一个只有两个特征的矢量化特征集,而不是走一步到位的编码或计数矢量化路线,这将创建一个巨大的稀疏矩阵,(想要可视化一个稀疏矩阵看看这个)。 第一个特征将是来自“频率”字典的所有负频率的总和,用于评论中的每个唯一单词。第二个特征将是来自“频率”字典的所有频率的总和,用于评论中的每个独特的正面词。

比如看第一个特征(即。负数总计),让我们假设我们有一个包含以下单词的评论[‘工作’,‘苹果’,‘承包商’]。查看之前计算的“频率”字典,该评论的特征 1 值将是 739 或(425+279+35=739)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先,我们创建一个备用的 1x2 numpy 阵列。在评论中循环每个单词,如果(word,1)(即。work ',1)作为一个关键字出现在频率字典中,我们将对其值进行索引。该值被赋给“x”数组中的第一列。如果这个单词不存在,那么“x”数组中的第一列将被赋一个零。然后 for 循环查看是否相同的单词但是具有积极的情绪(即 apple ',0)出现在频率字典中。如果是这样,索引值被分配给“x”数组中的第二列。当 for 循环完成其第一次迭代时,它将 x[0,0]和 x[0,1]值赋给“X”数组中相应列的第一行。

我们可以在下面的结果数据框中看到,第一篇评论中的负面词汇总数为 6790 个,正面词汇总数为 54693 个。

def features(review, frequencies):
    x = np.zeros((1,2))

    for word in review:
        if (word, 1) in frequencies:
            x[0,0] += frequencies.get((word, 1.0),0)
        if (word, 0) in frequencies:
            x[0,1] += frequencies.get((word, 0.0),0)
    assert(x.shape == (1, 2))
    return xX = np.zeros((len(df), 2))for i in range(len(df['length'])):
    X[i, :] = features(df['length'][i], frequencies)X_df = pd.DataFrame(X, columns=['neg_count', 'pos_count'])
reviews_df = pd.concat([X_df, df['sentiment']], axis=1)print(reviews_df.head())

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

列车测试分离

X_train, X_test, y_train, y_test = train_test_split(
    reviews_df.drop('sentiment', axis=1),
    reviews_df['sentiment'], 
    test_size=0.25)

分类器评估

我们将评估六种分类器,逻辑回归、随机森林、KNN、朴素贝叶斯、支持向量分类器和梯度推进分类器。我们肯定希望我们的模型有利于对负面评论(真正的正面评论)的准确预测,因为这些评论给了我们对组织问题的洞察力。也就是说,我们不想要一个过于“挑剔”的模型,它只会预测一个负面评论是负面的,如果它是绝对确定的。我们最终想要一个更平衡的模型,它有利于准确的负面评论预测(真正的正面),但也能很好地正确分类正面评论。因此,从度量的角度来看,我们需要高召回率来正确预测尽可能多的真实负面评论,但也需要良好的精确度来最小化错误的负面评论。此外,高 AUC 分数将指示该模型具有正确分类正面和负面评论的高概率。

为了获得更准确的模型评估并避免过度拟合,我们将使用分层 K-Fold 交叉验证。这样,每个模型将在来自我们原始训练数据的训练和测试数据的不同分割上被评估 k 次。将在每个折叠处计算指标,并对所有折叠进行总体平均。我们将比较每一层的平均训练和测试指标,以确定哪个分类器可能过拟合。此外,由于训练数据中存在少数类的类不平衡,我们将在每个折叠处使用 SMOTE 技术来过采样和平衡目标。让我们看看我们的分类器表现如何。

不幸的是,兰登森林和 KNN 严重过度拟合数据。朴素贝叶斯和 SVC 具有很高的测试召回率,但模型的精度很低,导致了很高的假阴性率。最后,逻辑回归和梯度推进分类器具有非常相似的分数,但是后者具有稍高的精度和 AUC。这似乎是一个稍微平衡的模型。

models = []
models.append(('log_reg', LogisticRegression(max_iter=10000, random_state=42)))
models.append(('rf_classifer', RandomForestClassifier(random_state=42)))
models.append(('knn', KNeighborsClassifier()))
models.append(('bayes', GaussianNB()))
models.append(('svc', SVC()))
models.append(('gbc', GradientBoostingClassifier()))scoring = {'accuracy': 'accuracy',
           'precision': 'precision',
           'recall': 'recall',
           'f1_score' : 'f1',
            'auc': 'roc_auc'}sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
skf = StratifiedKFold(n_splits=10)for name, classifier in models:
    pipeline = make_pipeline(sm, classifier)
    scores = cross_validate(pipeline, X_train, y_train, cv=skf, scoring=scoring, return_train_score=True)    
    for score in list(scores)[2:]:
        print('{} Avg CV Recall {} is {} | std is (+/- {})'.format(name, score[:-6], 
            np.mean(scores[score]).round(3), 
            np.std(scores[score]).round(3)))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

超参数调谐

梯度推进分类器有很大范围的超参数,我们可以调整。通常,n _ 估计量(即树的数量)、最大深度和学习速率被认为是最重要的参数。我们将检查学习率、n 估计量、最大深度、最小样本分裂和最小样本叶。

请记住,这些超参数范围是多次迭代的结果。我们将从大范围开始(即范围(10,1000,100)并缩小到更具体的范围(即。800,1000,1)基于获得的分数。它似乎是 0.01 的学习率和 n _ 估计量(即 959 的树数)是最好的。

learning_rate = [0.3,0.2,0.15,0.1,0.05,0.01]
n_estimators = range(20,1000,1)param_grid = dict(gradientboostingclassifier__learning_rate=learning_rate,
                 gradientboostingclassifier__n_estimators=n_estimators)gbc = GradientBoostingClassifier(random_state=42)
skf = StratifiedKFold(n_splits=10)
sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
pipeline = make_pipeline(sm, gbc)grid = GridSearchCV(pipeline, 
                    param_grid=param_grid, 
                    scoring='roc_auc', 
                    verbose=1, 
                    n_jobs=-1, 
                    cv=skf,
                    return_train_score=True
                   )
grid_results = grid.fit(X_train, y_train)print('Best Score: ', grid_results.best_score_)
print('Best Params: ', grid_results.best_params_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

scores = grid_results.cv_results_['mean_test_score'].reshape(len(learning_rate),len(n_estimators))plt.figure(figsize=(30, 15))
plt.pcolor(scores, cmap='coolwarm', alpha=0.7)
plt.xlabel('n_estimators')
plt.ylabel('learning_rate')
plt.colorbar()
plt.xticks(np.arange(len(n_estimators)), n_estimators)
plt.yticks(np.arange(len(learning_rate)), learning_rate)
plt.title('GridSearchCV Test AUC Score')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们转向 max_depth,即每个决策树可以构建的深度。增加深度使模型能够捕捉更多的信息(增加复杂性),但是有一个收益递减的水平,因为太多的级别模型将开始过度拟合。

似乎 max_depth 为 2 是最佳的,增加深度我们可以看到模型很快开始过度拟合。

max_depth = [2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20]param_grid = dict(gradientboostingclassifier__max_depth=max_depth)gbc = GradientBoostingClassifier(random_state=42,
                                 learning_rate = 0.01,
                                 n_estimators = 959)
skf = StratifiedKFold(n_splits=10)
sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
pipeline = make_pipeline(sm, gbc)grid = GridSearchCV(pipeline, 
                    param_grid=param_grid,
                    scoring='roc_auc', 
                    verbose=1, 
                    n_jobs=-1, 
                    cv=skf,
                    return_train_score=True)
grid_results = grid.fit(X_train, y_train)print('Best Score: ', grid_results.best_score_)
print('Best Params: ', grid_results.best_params_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

cv_results_df = pd.DataFrame(grid_results.cv_results_)
cv_results_df.rename(columns={'param_gradientboostingclassifier__max_depth': 'max_depth'}, inplace=True)
train_scores_mean = cv_results_df["mean_train_score"]
test_scores_mean = cv_results_df["mean_test_score"]
max_depths = cv_results_df['max_depth']plt.figure(figsize=(10,5))
plt.plot(max_depths, train_scores_mean, label='Avg Training AUC Scores')
plt.plot(max_depths, test_scores_mean, label='Avg Test AUC Scores')
plt.xlabel('max_depths')
plt.ylabel('Avg AUC Score')
plt.legend()
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Min_samples_split 或拆分内部节点所需的最小样本数。换句话说,如果我们将该参数设置为 2,那么该节点将需要至少两个记录/审查,以便拆分成两个节点。较高的值有助于过度拟合,因为它迫使决策树在拆分之前需要更多的记录。更多的分割=更多的深度=增加的复杂性=过度拟合。

min_samples_split = [2,3,4,5]param_grid = dict(gradientboostingclassifier__min_samples_split = min_samples_split)gbc = GradientBoostingClassifier(random_state=42,
                                 learning_rate=0.01,
                                 n_estimators=959,
                                 max_depth=2)
skf = StratifiedKFold(n_splits=10)
sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
pipeline = make_pipeline(sm, gbc)grid = GridSearchCV(pipeline, 
                    param_grid=param_grid,
                    scoring='roc_auc', 
                    verbose=1, 
                    n_jobs=-1, 
                    cv=skf,
                    return_train_score=True)
grid_results = grid.fit(X_train, y_train)print('Best Score: ', grid_results.best_score_)
print('Best Params: ', grid_results.best_params_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

cv_results_df = pd.DataFrame(grid_results.cv_results_)
cv_results_df.rename(columns={'param_gradientboostingclassifier__min_samples_split': 'min_samples_split'}, inplace=True)
train_scores_mean = cv_results_df["mean_train_score"]
test_scores_mean = cv_results_df["mean_test_score"]
min_samples_splits = cv_results_df['min_samples_split']plt.figure(figsize=(10,5))
plt.plot(min_samples_splits, train_scores_mean, label='Avg Training AUC Scores')
plt.plot(min_samples_splits, test_scores_mean, label='Avg Test AUC Scores')
plt.xlabel('min_samples_splits')
plt.ylabel('Avg AUC Score')
plt.legend()
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Min_samples_leaf 是形成叶节点所需的最小样本数。换句话说,每个叶子必须至少有 min_samples_leaf 评论,它将其分类为正面或负面。看来 26 条评论是最佳数字。

min_samples_leaf = range(10,30,1)param_grid = dict(gradientboostingclassifier__min_samples_leaf = min_samples_leaf)gbc = GradientBoostingClassifier(random_state=42,
                                 learning_rate=0.01,
                                 n_estimators=959,
                                 max_depth=2,
                                 min_samples_split=2
                                )
skf = StratifiedKFold(n_splits=10)
sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
pipeline = make_pipeline(sm, gbc)grid = GridSearchCV(pipeline, 
                    param_grid=param_grid,
                    scoring='roc_auc', 
                    verbose=1, 
                    n_jobs=-1, 
                    cv=skf,
                    return_train_score=True)
grid_results = grid.fit(X_train, y_train)print('Best Score: ', grid_results.best_score_)
print('Best Params: ', grid_results.best_params_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

cv_results_df = pd.DataFrame(grid_results.cv_results_)
cv_results_df.rename(columns={'param_gradientboostingclassifier__min_samples_leaf': 'min_samples_leaf'}, inplace=True)
train_scores_mean = cv_results_df["mean_train_score"]
test_scores_mean = cv_results_df["mean_test_score"]
min_samples_leafs = cv_results_df['min_samples_leaf']plt.figure(figsize=(10,5))
plt.plot(min_samples_leafs, train_scores_mean, label='Avg Training AUC Scores')
plt.plot(min_samples_leafs, test_scores_mean, label='Avg Test AUC Scores')
plt.xlabel('min_samples_leafs')
plt.ylabel('Avg AUC Score')
plt.legend()
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型评估

将我们的优化模型应用到我们坚持的测试数据中,我们可以看到边际改进。总体而言,AUC 略有上升(0.728 至 0.734),同时积极评价类别的召回率也有所上升(74%至 76%)。我们能够通过 11 个评论增加我们的真实正面计数。我们的模型仍然将大量正面评论错误分类为负面评论(217 个误报)。也就是说,总的来说,它在正确分类真实的正面评价(76%)和真实的负面评价(71%)方面做得相当不错。

model_one = GradientBoostingClassifier(random_state=42,
                                       learning_rate=0.01,
                                       n_estimators=959,
                                       max_depth=2,
                                       min_samples_split=2,
                                       min_samples_leaf=26)sm = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
X_train_sm, y_train_sm = sm.fit_sample(X_train, y_train)model_one.fit(X_train_sm, y_train_sm)
train_auc = cross_val_score(model_one, X_train_smote, y_train_smote, cv=10, scoring='roc_auc')
y_pred = model_one.predict(X_test)
cnf_matrix = confusion_matrix(y_test, y_pred)
roc_auc = roc_auc_score(y_test, y_pred).round(3)print(classification_report(y_test, y_pred))
print(cnf_matrix)
print('Training CV AUC:', train_auc)
print('Training Avg AUC:', train_auc.mean().round(3))
print('Test Auc:', roc_auc)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

优化模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基础模型

我希望这篇文章对您的数据科学事业有所帮助和启发。一如既往,我欢迎任何和所有的反馈。

用 Python 中的量化金融和机器学习预测短期股票走势

原文:https://towardsdatascience.com/predicting-short-term-stock-movements-with-quantitative-finance-and-machine-learning-in-python-e6e04e3e0337?source=collection_archive---------10-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QuoteInspector 拍摄的照片

探索机器学习和标准交叉,以 68%的准确率预测未来的短期股票趋势

你有没有听人说过,他们多么希望能回到过去,投资苹果或亚马逊?嗯,他们不能,而且无论他们在 r/WallStreetBets 上花多少时间,他们都不会预测下一个快速致富的投资。事实上,如果你真的听了 r/WallStreetBets,你很可能会在一周内破产,这是我在这篇文章中做出的唯一保证。

然而,让我们看看我们是否可以利用简单的量化金融机器学习概念,看看我们是否能够以一定的准确度预测股票走势。在本教程中,我们将看看我们是否能够准确预测特定股票的短期走势。

什么是量化金融?

量化金融是利用大型数据集和数学模型来分析金融市场。所以,想象一下,我们有一堆公式,以某种方式让我们更好地理解特定的股票,我们用它来猜测预测的趋势,这就是量化金融。现在,如果我发现了任何突破性的指标、公式或模型,那我就是在撒谎,但是让我们看看我们是否能制造出自己的指标、公式或模型,并且有可能在未来从中赚钱。最终,我们也许能把乔丹·贝尔福特从华尔街之狼变成一种算法。

交易 101

我将使用一些投资和交易领域特有的术语,所以如果你有任何不确定性,请不要犹豫去查找术语。我不是金融专家,所以我会谨慎使用它们。
这里有一些你应该知道的术语:
指标——一种表示股票价格趋势的统计数据
S&P 500——500 家最大上市公司的加权指数
短期运动——股票的 30 天趋势
移动平均线——一段时间内收盘股票价格的平均值

收集数据

所有好的数据科学项目都依赖于输入数据的质量。谢天谢地,由于股票交易的性质,我们可以使用 pandas-datareader (一个内置网页抓取功能的 pandas 扩展)和令人惊讶的不朽工具 Yahoo!金融

import pandas_datareader as pdr
import datetime
# We can choose any date up to that stock’s IPO
start = datetime.datetime(2014, 1, 1)
# Up to most recent data
end = datetime.date.today()
# We’ll look at F which is Ford
stock = ‘F’
pdr.DataReader(stock, ‘yahoo’, start, end)
# This returns a data frame of scraped stock data from yahoo

完成了!任何数据科学应用程序中最简单也是最重要的部分,只用几行简单的代码就完成了。我们可以进一步扩展到这一点,只使用股票代码从任何股票中收集数据。例如,在我们的应用程序中,我们收集了所有标准普尔股票的数据。

简单分析

在定量金融中,最简单的趋势指标是一个交叉点。交叉是指短均线和长均线交叉。在此分析中,我们将利用简单移动平均线(所有收盘价的权重相等)和指数移动平均线(较新的价格权重较大)。然后,当我们的脚本检测到交叉时,我们将执行交易。

当短均线从长均线上方转到下方时,这是一个交叉,表示卖出(或做空)的机会,反之则表示买入(或做多)的机会。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

移动平均线交叉的图形解释

当我们的脚本检测到有利于股票上涨的交叉时,就会触发买入,反之则触发卖出。然后,使用回溯测试分析,我们可以用历史数据测试我们的策略,甚至绘制出我们的算法所做的交易。

我们先算一下所有的均线。对于我们的例子,我们将使用 50 和 200 天窗口的指数移动平均线。

import pandas as pd
# List where we will keep track of long and short average points
indicators = pd.DataFrame(index=data.index)
# 50 day
short_window = 50
# 200 day
long_window = 200
# Exponential moving averages using the closing data
indicators[‘short_avg’] = data[‘Close’].ewm(span=50, adjust=False).mean()
indicators[‘long_avg’] = data[‘Close’].ewm(span=200, adjust=False).mean()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个所有交叉和指示福特股票方向的图

正如你所看到的,通过这种简单而有效的分析,我们的算法通常可以准确地预测趋势。一种算法可以通过利用期权交易而不是典型的摇摆交易来进一步利用这些摇摆,在典型的摇摆交易中,唯一的机会是买入和卖出。交叉是交易者最简单也是最常用的技术指标之一,现在在算法交易的帮助下,你也可以。

要了解更多信息,请查看 QuantStart ,他们有一些关于 Python 的好的免费文章。

机器学习

如果我们想利用我们的数据做出更好的预测呢?好吧,通过机器学习的魅力,我们可以创建一个模型,给我们一个短期价格预测,希望它有点准确。

我们将像以前一样开始收集数据,但是,这一次我们将需要更多的数据。对于我们的模型,我们使用与之前相同的 API 从所有标准普尔 500 股票中收集了超过 30 年的股票数据,但是我们需要做更多的数据处理。

首先,我们需要一个目标变量,它可以是分类的,也可以是数字的。该项目利用了与总体标准普尔 500 相比的相对百分比变化。这很重要,因为如果标准普尔 500 指数也上涨了 10%,一只股票在 30 天内上涨 10%并不重要。例如,如果苹果股价上涨 8%,S & P 500 下跌 2%,则short_result(我们的目标变量)将为 10%,稍后归类为强烈买入

# Getting the S&P 500 relative price difference.
SP = pdr.DataReader(‘SPY’, ‘yahoo’, start_time, end_time)
SP[‘sp_percent_change’] = SP[‘Adj Close’].pct_change(periods=1).astype(float)
data = data.merge(SP[‘sp_percent_change’], left_index=True, right_index=True)
data[‘percent_change’] = data[‘Adj Close’].pct_change(periods=1).astype(float)
# Daily percent change as compared to the S&P 500
data[‘relative_change’] = data[‘percent_change’] — data[‘sp_percent_change’]

现在我们有了一个包含所有训练数据的基本数据框架,我们可能需要添加更多的指标。这是因为我们的 API,以及我们的目标变量,为我们的模型提供了每个实体只有有限数量的特征,因此对于预测趋势是无效的。像这样的机器学习模型需要一段时间的数据。因此,我们将不得不利用这些趋势和一些其他定量财务指标来添加更多的功能。

谢天谢地,像往常一样,有一个库为我们做这些。我们利用了 FinTA(金融技术分析),它能够利用我们已经拥有的所有数据计算出 76 个交易指标。理解每个模型的细节并不是完全必要的,但是可以帮助最大化模型的准确性。在我们的模型中,我们使用了几种不同的移动平均线和力量指数**,因为这些指标是专家们最常用来衡量市场的短期波动。**

为了实现,我们简单地使用 python 的 eval 函数,因为它最容易快速实现所有选择的指示器方法,并将它们作为特性添加到我们的数据集。

from finta import TA
# Here are all indicators we are using
indicators = [‘SMA’, ‘SMM’, ‘SSMA’, ‘EMA’, ‘DEMA’, ‘TEMA’, ‘TRIMA’, ‘TRIX’, ‘VAMA’, ‘ER’, ‘KAMA’, ‘ZLEMA’, ‘WMA’, ‘HMA’, ‘EVWMA’, ‘VWAP’, ‘SMMA’, ‘MACD’, ‘PPO’, ‘VW_MACD’, ‘EV_MACD’, ‘MOM’, ‘ROC’, ‘RSI’, ‘IFT_RSI’]
df = None
# Using python’s eval function to create a method from a string instead of having every method defined
df = eval(‘TA.’ + indicator + ‘(data)’)
# Some method return series, so we can check to convert here
if not isinstance(df, pd.DataFrame):
df = df.to_frame()
# Appropriate labels on each column
df = df.add_prefix(indicator + ‘_’)
# Mege data frames based on the date
data = data.merge(df, left_index=True, right_index=True)

你可能会问自己“这些特性不会产生不必要的噪音吗”,你可能是对的;然而,我们可以用几种方法来解决这个问题。我们可以收集更多的数据,我们已经这样做了,和/或我们可以利用交叉验证,它利用我们数据的重采样来更好地概括我们模型的预测。

制作模型

现在这里是我们想要如何完成预测的岔路口。我们可以手工制作模型的其余部分;优化我们自己的超参数(这只是控制学习过程的参数)标准化特征,并利用不同的 ML 技术,或者我们可以为我们处理这些。然而,如果你是 ML 的新手,我强烈建议遵循我们的 代码 并学习不同的技术,但是如果你对更大的自动化优化感兴趣,你绝对应该查看一下 亚马逊 Web 服务 SageMaker ,尤其是如果你有一些 AWS 学分的话。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建 SageMaker 实验、模型和笔记本的过程

SageMaker 为您完成了构建、培训和部署 ML 模型的所有繁重工作,并且非常易于使用。他们有一些很棒的教程,设置自动驾驶实验只需简单的点击几下。一旦完成,您就可以选择最佳模型并部署它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

借助 AWS 部署 SageMaker 模型流程

不管你是使用基于回归的模型还是分类模型,买卖股票的核心问题是分类问题。然而,从回归模型开始并为是否买入或卖出设置上限/下限是有效的。在我们的模型中,我们使用标签强烈买入强烈卖出与我们的目标变量≥10 和≤-10 的预测评级相关联。买入卖出分类分别与一个评级[5,10]和[-5,-10]相关联,持有被赋值为(-5,5)。值得注意的是,所有股票的表现要么比标准普尔 500 指数好,要么比标准普尔 500 指数差。预测评级的幅度越大,我们对股票走向的信心就越大。例如,两只股票可能被列为强烈买入,但我们可以对评级更高的那只更有信心。

分析

为了分析我们模型的有效性,我们可以用未经测试的数据来验证我们的模型。我们可以创建的一个指标是预测区间(类似于置信区间),它将告诉我们预测的真实范围,并具有一定的可信度。我们可以使用均方根误差,它对我们来说是 8.91,因此 80%的预测区间将是等于predicted rating ± 11.40predicted rating ± 8.91*1.28。这意味着我们有 80%的信心认为股票的实际相对表现将在我们预测的 11.40 以内。

需要注意的是,我们的区间利用了均方差,该均方差没有考虑超出上限或下限区间的预期。例如,预测值为 10,实际值为 30 的short_result与-10 的short_result相同,即使第二个结果没有那么幸运,误差的平方也是相同的。然而,如果我们独立地分析每个标签,我们可以创建更具体的预测区间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显示由我们的模型预测的每个标签的预测间隔的图表

我们还可以创建混淆矩阵,使我们能够可视化每个结果的预测模型的统计成功。通过分解预测买入或卖出的可能结果(我们忽略了持有预测,因为它的高度不确定性),我们可以明确地可视化我们的正确率。例如,在“预测卖出”和“实际卖出”单元格中具有最高值的混淆矩阵意味着模型预测建议的卖出结果比买入结果更准确。

以下是用每只标准普尔 500 股票代表的未经测试的数据验证我们的模型的结果:

  • 使用强烈买入/卖出分类预测正确趋势的准确率为 67.6%
  • 使用任何买入/卖出分类预测正确趋势的准确率为 55.8%

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

强买/强卖混淆矩阵

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

购买/销售混淆矩阵

最后的想法

机器学习是一种非常强大的技术,可以利用历史数据进行预测,股票市场就是这种技术的一个很好的应用。然而,需要注意的是,股票市场通常是非常不可预测的,技术分析应该总是在基本面分析之后,我有义务说,这些都不应该作为财务建议。

恭喜你。如果你跟着做,你的模型现在可以和其他先前发表的模型相媲美,它们也预测短期股票方向。我们取得了类似的成功,因为我们利用了大量的可用数据和几种类型的指标。这正好说明,在数据科学领域,数量绝对驱动质量

点击这里查看完整的项目回购和我个人网站上该模型预测的每日反馈:

[## 马修·斯坦宁格

软件工程师-学生

mathewsteininger.com](https://mathewsteininger.com)

使用宏观社会文化变量预测新加坡自杀率

原文:https://towardsdatascience.com/predicting-singapore-suicide-rates-using-macro-sociocultural-variables-13f9e63ece86?source=collection_archive---------54-----------------------

Movember 已经到来,带来了…嗯,只是你典型的潮湿和湿润的新加坡天气(不是人们在北半球所期望的美丽的秋叶)。由于我是一名亚洲男性,因此没有机会留胡子,我决定以自己的方式做出贡献,调查自杀率(包括男性和女性),并试图找出是否有任何方法可以通过观察宏观社会因素来预测自杀率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如图: 非我 在 Movemeber(图片来自 Unsplash)

关于这一点已经有了很多预先存在的研究(例如,参见此处的和此处的),得出的主要结论之一是宏观经济不稳定与“精神疾病和自杀的加剧”之间的关系。然而,我想超越经济指标,看看随机的、可能不相关的变量,看看是否有任何“盒子外”的因素,我们可以用来预测自杀率(并据此采取行动)。

TL;博士;医生

  1. **糟糕的模型:**我尝试对数据应用随机森林,然后应用线性回归模型。然而,两者都被证明具有极低的 R 值,表明预测能力差(当在验证集上测试时)。
  2. 经验教训:
    答:数据为王
    :无论您使用哪种模型,您使用的数据都是关键。俗话说,垃圾进,垃圾出。尽管我不愿意承认,但我确实没有足够的数据。我从 SingStat 下载的大部分数据集只能追溯到 1990 年。数据太少,无法对其进行任何有意义的工作。b .因变量的性质:自杀作为心理健康的一个功能,传统上很难管理,更不用说预测了。认为我可以使用宏观变量以某种方式预测自杀率是一个好主意,但可能是天真的想法。
  3. 提高意识是关键:归根结底,也许我们对付这种致命的社会趋势的最好工具就是意识和同情。消除自杀意念的污名,给人们提供接受帮助的空间,是解决这一问题的关键。作为个人,我们可以用正确的知识和技能来武装自己,为可能遭受精神痛苦的朋友和家人提供帮助。这是一个很好的网站,上面有关于我们如何发挥作用的关键信息。

收集数据

想要做一个新加坡特有的探索,我求助于两个新加坡统计资料库: SingStat 和【Data.gov】T2。这些网站上的数据集真的非常广泛,涵盖了各种各样的统计数据。我从这些网站下载了一大堆随机统计数据,把它们编译成一个主 csv 文件。

虽然自杀率的统计一直追溯到 1968 年,但大多数其他关键统计数据只追溯到 1990 年。我很失望地发现这一点,因为我一直认为新加坡,在所有国家中,将有良好的,可靠的历史统计数据(考虑到我们作为一个国家相对年轻)。尽管如此,我还是利用我所拥有的资料,将我的数据集限制在 1990 年至 2019 年。这后来证明对我不利。

从网上大量可用的数据集中,我选择了一些随机的、不相关的数据集。我想包括更多的变量(随机的东西,比如公共游泳池的游客数量),但是大多数只有 2005 年的数据(有些只有 2010 年的数据!).我还想包括一些重要的消费者消费变量。在其他研究中,酒精使用(通过消费和与酒精相关的犯罪来衡量)是重要因素。然而,犯罪统计从 2011 年才开始,消费统计每 5 年才进行一次。不是特别有用。

然而,我研究了我能找到的数据,最终得到了 14 个不同的变量:失业率、雨天、日照时间、结婚率、视觉艺术展览数量、手机订阅数量、离婚率、图书馆图书借阅数量、理工学生支出、大学生支出、车辆总数、报纸订阅数量、交通事故数量和电力消耗率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要是我有更多的变量就好了…唉(图片来自 Unsplash)

我认为这是一个相当广泛的列表,并很兴奋地在模型中运行它,看看我们能找到什么。谢天谢地,下载的数据非常干净,在 Excel 中做了一点“预处理”,我们就可以开始了。

数据窥视

清理完数据后,我将它导入 Python,绘制出这些年的自杀率以及相关图,只是为了快速了解数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看看自杀率的图表,老实说,看起来并不乐观。这些年似乎没有真正的趋势(上升或下降),虽然在关键时刻(如 2007 年至 2008 年金融危机)似乎有峰值,但也不是特别突出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看着热图,老实说,它看起来并不乐观。从最后一行来看,没有一个变量与自杀率有特别强的相关性(正或负)。即使对于失业率(在其他论文中显示有显著的正相关性),似乎也没有特别强的相关性。

随机森林回归量

数据的概述并没有吓住我(或者我本应该被吓住),我继续实现了一个随机森林模型,试图理解这些数据。使用sklearn,我将数据分成训练集和测试集,然后实例化 RFG。

(注:我知道关于为 RFs 分割数据集有不同的思想流派。有些人认为,由于装袋,没有必要为射频验证设置。然而,也有其他人认为,这可以与 OOB 分数进行比较,以获得更好的评估。后来,我还需要为我的多元线性回归模型建立一个测试和训练集,因此需要拆分)

拟合训练数据集,然后我比较了模型的 R 分数。R 的重要性已经在前面讨论过了,但本质上它代表了自变量解释的因变量方差的比例。或者用外行人的话来说,它代表了多少结果可以用自变量来解释。

最终产品是一场灾难。虽然训练 R 是相当可观的 0.80 (80%的自杀率可以通过输入来解释),但公开得分是,测试集得分 0.36 与 OOB 得分相差甚远。

射频模型通常有很高的 R 值,所以 0.80 的分数不值得一提。虽然我最初打算使用sklearn RandomizedSearchCV对模型执行超参数调整,但模型的初始评估已经很差,我认为任何调整都没有意义。 N (数据点数)简直太低了。正如 Will Koehrsen 在他关于改进 RF 模型的文章中所写的,第一步是收集更多的数据(在这种情况下,我很遗憾不能)。

出于好奇,我想看看特征的重要性(例如,哪些特征对预测目标最有用)。我使用了 Eryk Lewinson 的代码来创建特性重要性图,并对其进行了调整以适应数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了证明这个模型有多不准确,政府在理工学院的支出是最重要的特征。其次是每年视觉艺术展览的数量。虽然第二个因素排在第二位,但很难看出理工学院的支出是预测自杀率的最重要变量。失业率(通常是一个很强的预测指标)是第七个最重要的因素。这种模式显然是相当破碎的。

多元线性回归

此时,我已经意识到我缺乏数据是一个巨大的问题。然而,由于我已经在使用 Python 了,所以我决定还是结束探索并加入 LR 模型吧。

从结果中可以看出,调整后的 R 平方是负的(也就是说,这个模型不能预测自杀率的任何变化)。因此,这是一个基本上无用的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我感觉像这个气球(图片来自 Unsplash)

结论

  1. 数据为王:无论你使用什么模型,你使用的数据都是关键。俗话说,垃圾进,垃圾出。尽管我不愿意承认,但我确实没有足够的数据。我从 SingStat 下载的大部分数据集只能追溯到 1990 年。数据集太小,无法对其执行任何有意义的工作。这篇文章是一个关于改进 ML 模型的资源。它建议的第一件事是获取更多的数据来训练你的模型。在这种情况下,由于我在寻找新加坡相关统计数据方面的限制,不可能获得更多的数据。
  2. **因变量的性质:**自杀作为心理健康的一个功能,传统上很难管理,更不用说预测了。认为我可以使用宏观变量以某种方式预测自杀率是一个好主意,但可能是天真的想法。也有其他研究试图使用微观变量(例如观察 twits 来检测自杀意念)。虽然他们确实发现了“算法 SI 分数与全县自杀死亡率的显著关联”,但这是否有助于预测自杀倾向还有待观察。
  3. 提高意识是关键:归根结底,也许我们对付这种致命的社会趋势的最好工具就是意识和同情。消除自杀意念的污名,给人们提供接受帮助的空间,是解决这一问题的关键。作为个人,我们可以用正确的知识和技能来武装自己,为可能遭受精神痛苦的朋友和家人提供帮助。这个是一个很好的网站,上面有关于我们如何发挥作用的关键信息。

原载于https://Zach lim 98 . github . io/me/2020-11/自杀率预测

预测垃圾邮件

原文:https://towardsdatascience.com/predicting-spam-messages-17b3ca6699f0?source=collection_archive---------42-----------------------

使用机器学习算法预测垃圾邮件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Jason Leung 在 Unsplash 上拍摄的照片

在本文中,我尝试预测垃圾邮件。你可以在文末提供的我的 Github 账号上找到所有的 python 代码。

如今,当我们听到“垃圾邮件”这个词时,首先想到的是垃圾邮件。然而,八十年前并非如此。spam 一词是由一个叫 Ken Daigneau 的人在 1937 年创造的,用来命名 Hormel Foods 的新肉制品。肯为新项目命名赢得了 100 美元的奖金。有些人认为 spam 代表五香火腿,还有许多人认为它代表“特别加工的美国肉类”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

垃圾品牌。汉尼斯·约翰逊在 Unsplash 上拍摄的照片

“垃圾邮件”这个词在 20 世纪 70 年代开始被认为是“令人讨厌”的东西,在巨蟒剧团的飞行马戏表演之后,当在一个“”场景中,维京人开始唱“垃圾邮件之歌”,并一直重复“垃圾邮件”这个词。后来,在 20 世纪 80 年代和 90 年代,人们使用“垃圾邮件”这个词的重复,有时甚至是《维京人之歌》的整首歌来发送垃圾邮件聊天。因此,人们开始将“垃圾邮件”这个词与令人讨厌的垃圾信息联系起来。

本文的目标是使用不同的机器学习技术来预测邮件是否是垃圾邮件。我使用了加州大学欧文分校提供的 数据集 ,其中包含大约 5500 条短信。下面是文章的结构:

  1. 探索性数据分析
  2. 文本预处理和特征工程
  3. 建模
  4. 结论

探索性数据分析

首先,我们来做一些探索性的数据分析。通过检查数据集的形状,我们可以看到它有 5572 个观察值和两列。然而,在 5,572 个观察值中,只有 5,169 个唯一值,这意味着大约有 450 个重复行。我还检查了缺失值,但是发现没有一列有任何缺失值。下面是前五行和数据集的形状:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始数据集

删除重复项后,数据集有 5,169 个观察值,其中 4,516 个是垃圾邮件,653 个是垃圾邮件。相对大量的 ham 消息意味着如果我把所有的消息都当作 ham,我会得到 87%左右的准确率。有些人以朴素贝叶斯(一个非常简单的模型)的精度为基准,但我会以整体精度为基准,并会尝试以更高的精度做出能更好预测的模型。如果你想了解更多关于朴素贝叶斯的知识,可以看看这个 视频

文本预处理和特征工程

在开始建模部分之前,我需要处理数据,并使其适合建模。在这一部分,我需要将电子邮件、网址、货币符号、电话号码和数字转换成特定的单词,并删除所有的标点符号。更准确地说,想象一条垃圾消息,它具有下面的消息“使用 www.wearespam.com 的链接获得 100 万美元”,以及另一条包含“使用 www.wearealsosmap.com链接获得 50 万美元”表述的垃圾消息。在这种情况下,我们不希望算法考虑两个不同的链接或奖金数额,而是用特定的词来定义它们。转换文本后,这两个句子看起来像“使用 webaddr 链接获取货币号码”除了改变文本中的一些单词,我还对词典进行了规范化,并从文本中删除了所有的停用词。为了更加精确,我现在将提供每个部分的更多细节。

删除“不必要的”单词——正如我已经解释过的,我们不需要在文本中有不同的唯一数字。尽管如此,我们需要知道特定的消息是否包含电子邮件地址、电话号码等。您可以使用 Python 的正则表达式包来识别文本中的电子邮件和电话号码。在下面的 网站 找到更多关于正则表达式的信息。

规范词汇——我执行了词汇规范化的词汇化技术。在这个过程中,我们把这个词带到它的“基础”层面。例如,单词“go”、“goes”和“going”有相同的基础,但用法不同。词汇规范化的另一种方法是词干化,但是词汇化比词干化有一些优势。例如,词汇化通过使用词汇将单词转换为其基础,而词干化对单词起作用,而不考虑其内容。因此,词汇化可以导致单词的更好的转换,而不改变意思。要了解更多关于词汇化和词干化的信息,请点击这里的。**

清洗完文字,我需要看到最常见的字。下图显示了文本中最常见的单词是“数字”那是因为我把所有的数字都转换成了一个单词,我们的文本包含了太多不同的数字。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

词的出现

最后,在删除了停用词、不必要的词和规范化了词典之后,是时候对文本进行标记了。标记化是将每个单词或一系列单词视为特定单位的过程。例如,在对“我喜欢苹果”句子进行单字标记化之后,我们得到三个单独的标记:[我]、[喜欢]和[苹果]。我使用了 unigram 和 bigram 标记化,因为包含两个单词的表达式也是分析所必需的。例如,在短语“早上好”中,这两个词放在一起,而不是分开,对于捕捉表达的确切含义是必不可少的。我没有用三个或更多的单词来标记,不是为了增加变量的数量和最小化计算能力的使用。在对文本进行标记后,我制作了一个单词包来开始处理数据。通过制作单词包,我们为单词提供了数值。单词包计算每个单词在句子中的出现次数。这是一个简单的技术,易于使用。然而,只用弓也有它的缺点。例如,BoW 衡量文本中每个词的出现次数,出现频率越高的词可以获得更高的重要性。例如,让我们来看下面两个句子:“轰炸、弹幕、幕火、地雷、毒气、坦克、机枪、手榴弹——单词、单词、单词,但它们包含了世界的恐怖”(埃里希·玛利亚·雷马克“西线一切平静”)和“这是一张桌子。”在制作了单词包之后,我们看到单词“words”比“table”更常见,这意味着“words”将变得更加重要。为了解决这个问题,我使用了 TF-IDF(术语频率-逆文档频率)权重。权重提供了每个标记的重要性,但是它也考虑了标记在语料库中的频率。想了解更多关于 BoW 和 TF-IDF 的信息,可以查看 这里

在对数据进行标记化并计算 TF-IDF 权重之后,我得到了最终的数据集,它由 5169 行和 37891 列组成。太多了!!!

造型

因为我已经准备好了数据,现在是制作模型的时候了。在我的分析中,我使用了四种不同的模型:SVM、随机森林、逻辑回归和 XGBoost。我将数据集分成两部分,用一部分训练模型,另一部分测试它们的性能。为了提高每个模型的性能,我尝试了不同的参数,并使用贝叶斯优化进行超参数调整。我采用了不同范围的参数,并对训练数据集进行交叉验证,以找到参数的最佳组合。后来,我在测试数据集上测试了这些模型,并使用准确性和 AUC 分数来比较它们的性能。尽管我使用贝叶斯优化进行超参数调优,但我想快速浏览一下广泛使用的替代方法。贝叶斯优化的可能替代品是网格搜索和随机搜索,但我使用贝叶斯优化,因为其他两个有一些缺点。我将简要解释每种方法的工作原理以及它们可能的缺点。

  • 网格搜索方法-测量所有可能的参数组合的结果。例如,如果我们想在 0.01 或 0.1 的学习率和 4 或 5 的最大深度之间做出决定,那么网格搜索将建立四个不同的模型(尝试所有可能的组合),并采用模型表现最佳的参数。网格搜索方法的缺点是,在许多参数的情况下,比较所有可能的组合将花费太多的计算能力。
  • 随机搜索方法-在提供的参数中,该方法采用参数的随机组合,并用它们来建立模型。对于这种方法,我们需要指定要进行多少种组合。随机搜索方法的主要缺点是它随机选择参数,并且人们永远不能确定该方法将采用参数的最佳组合。
  • 贝叶斯优化方法—使用贝叶斯定理指导参数搜索。因此,它走向目标函数增加/减少的方向(取决于目标)。

下面是 XGBoost 的超参数调整代码:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

XGBoost 的超参数调整

通过了解所有模型的最佳参数并制作模型,我发现支持向量机(SVM)的预测效果最好。它具有 98%的准确性和 0.92 的 AUC 分数。XGBoost 和 Random Forest 的性能没有显著差异,但这些模型的准确性和 AUC 较低。一个相对简单的模型,逻辑回归,并不能很好地进行预测,并且准确性和 AUC 评分最低。另外,通过查看混淆矩阵,我们可以看到,当算法预测该消息是垃圾邮件时,大多数错误都与误报有关,但实际上,它是 ham。以下是 SVM 的结果汇总:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SVM 绩效总结

最后我对所有模型做了 ROC 曲线,直观的看哪一个表现最好。下面你可以找到 ROC 图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

受试者工作特征曲线

您可以再次看到 SVM(红线)的表现最好,因为它的 ROC 得分最高。

总的来说,在本文中,我试图了解哪种模型有助于更好地预测垃圾邮件。首先,我清理了数据,对文本进行了必要的转换,并将 word 转换为数值,以便能够制作模型。我使用了四个模型,并为 SVM 获得了最高的准确性和 AUC 分数。该模型的使用可以帮助许多企业更好地了解哪些消息是垃圾邮件。然而,我相信可以通过使用更复杂的模型如神经网络来进一步改进预测。

你可以在我的 github 账号上找到本文使用的 Python 代码。

预测 Spotify 曲目跳过

原文:https://towardsdatascience.com/predicting-spotify-track-skips-49cf4a48b2a5?source=collection_archive---------23-----------------------

致力于 Spotify 顺序跳过预测挑战

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(截图由 Spotify 提供)

介绍

作为 Metis 数据科学训练营的第三个项目,我做了一个稍微简化的版本的 Spotify 顺序跳过预测挑战【1】。

我相信你知道,Spotify 是一家流媒体服务公司,其商业模式的核心是向用户提供歌曲推荐,以保持他们使用他们的应用程序。

Spotify 拥有超过1.9 亿活跃用户,与超过4000 万首歌曲互动。

挑战的目标是预测用户在收听过程中跳过任何一首歌曲的可能性

方法学

数据

Spotify 为比赛提供了两套主要信息。一个表有关于用户收听会话的信息。例如:

  • 会话 ID
  • 在会话中的位置
  • 轨道 ID
  • 如果轨道被跳过或没有被跳过
  • 其他会话元数据

请注意,用户会话的长度都在 10 到 20 首曲目之间,并且不包括任何关于用户的可识别信息。

第二个表包含关于磁道的元数据(对应于会话表中的track_id功能),例如:

  • 轨道持续时间
  • 追踪在美国的受欢迎程度
  • 发布年份

以及一些额外的功能,由 Spotify 生成,用于描述歌曲,例如:

  • 声音度
  • 跳动力量力量
  • 弹性
  • 可跳舞性

该数据集还包括每首曲目的一组 8 个“声音矢量”,它们是 Spotify 为每首曲目生成的潜在编码。

出于许可的原因,Spotify 将曲目信息匿名化,因此没有任何关于曲目名称、艺术家、专辑或流派的数据。

所提供的数据集中的目标(无论是否跳过了音轨)与大约 51.7%被跳过的音轨保持平衡。所以没有必要为了训练而调整班级平衡。

有多余的数据,所以我使用了会话表中大约 100k 行的子集和跟踪表中相应的行,我将它们加载到托管在 AWS EC2 实例上的 Postgres 数据库中。数据库模式如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Spotify 跳过数据的模式

为了了解单个会话可能是什么样子,下图显示了单个用户会话的曲线图,因为它与其中一个功能相关,即“音轨响度”,Spotify 对歌曲特征的描述,而不是传统意义上的“音量”,其中颜色指示跳过和未跳过的音轨。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单个会话的音轨跳过与音轨响度

虽然它本身没有意义,但它说明了如何根据歌曲属性绘制每个会话。在这个例子中,随着响度值降低,用户只听了前 11 个音轨中的两个,然后听了所有剩余的 9 个音轨。

此外,为了更好地了解整体发行曲目属性,我绘制了一小部分功能的分布,并突出显示了三首不同歌曲在分布中的位置(使用来自 Spotify API 的数据)。这三首来自三个不同流派的歌曲是:

  • 威利·尼尔森的拦路强盗(国家)
  • 武堂帮的护丫脖子(嘻哈/R & B)
  • 约翰·科尔特兰的《蓝色世界》(爵士乐)

以下是属性“能量”、“响度”、“跳舞度”和“声音度”的属性分布图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标绘 3 首歌曲作为参考的音轨特征子集的分布

特征工程

这些数据本质上是有序的。该模型对任何给定歌曲的跳过预测将基于在用户收听会话中较早跳过的歌曲。因此,为了让我的模型考虑到这一点,我添加了一组特征来表示以前音轨的音频特征以及这些音轨是否被跳过。

旁注:我还尝试了一种替代方法,在这种方法中,我添加了两组特征,分别对应于被跳过的先前轨道和未被跳过的轨道的平均轨道特征信息,但是发现计算时间更长,添加了两倍的特征,并且没有提高模型性能。

型号选择

根据竞赛指南,目标衡量标准是准确性。

我开始用逻辑回归模型作为基线,但是发现它的准确性很差。因此,从那以后,我转向了基于树的模型,这种模型不太容易解释,但能够自动处理复杂的功能交互。

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比较逻辑回归和 LightGBM 模型性能的 ROC 曲线

我最好的模型的最终测试精度是 0.73 ,使用的是 LightGBM 的LGBMClassifier模型,考虑到问题,这已经相当不错了,但还有改进的空间。

在训练模型之后,我分析了误差,寻找改进模型的地方,但是在残差中没有发现任何明确的趋势。

结论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终 LightGBM 模型的相对特征重要性排序

该图显示了最终模型的前 10 个功能的相对重要性排名。该模型将曲目流行度列为最重要的特征,其次是曲目持续时间,然后是上一首曲目的流行度。这个排名似乎总的来说是有意义的,并没有发现什么太令人惊讶的事情,除了可能的事实是曲目流行度的排名远远高于下一个最重要的功能。然而,有趣的是,这个图(以及在下面的附录中可以看到的完整排名的图)显示,在少数情况下,该模型似乎正在比较当前曲目和先前曲目的特征。一些例子包括流行度持续时间响度

同样,该模型的性能是合理的,与精确度为 0.51 的完全天真的模型(总是预测音轨将被跳过)相比,精确度为 0.73,但仍有很大的改进空间。

未来的工作

展望未来,需要继续努力的几个领域包括:

  • 添加无监督学习,根据曲目特征对歌曲进行聚类,并可能生成“伪流派”
  • 使用递归神经网络进行预测,这可以更自然地处理序列轨迹信息
  • 用来自 Spotify API 的更多数据补充数据集(如流派信息)
  • 创建一个 Flask 应用程序,它使用 D3 来可视化模型预测,并允许用户交互式地探索数据集

感谢阅读,我很想听听你的想法!

附录

特征子集描述

  • 声音度:音轨有声音的可能性
  • 可跳舞性:描述一个曲目适合跳舞的程度
  • 能量:轨迹强度的量度
  • :音轨所传达的“积极”程度
  • 语音识别:检测口语单词的存在

全模型特征重要性等级

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

轨迹"*声矢量"*相关矩阵

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

引文

这里有一个挑战网站的链接(这里有更多关于数据集和挑战规则的信息)。

[1] B. Brost,R. Mehrotra 和 T. Jehan,音乐流会话数据集 (2019),2019 年网络会议论文集

使用逻辑回归预测启动性能

原文:https://towardsdatascience.com/predicting-startup-performance-using-logistic-regression-582a1e80b2eb?source=collection_archive---------23-----------------------

通过简单的数据科学分析创业公司的寿命

我第一次接触创业领域是在大学一年级的夏天,直到现在,我也是其中的一员。不幸的是,我遇到的大多数都因为各种原因而关闭了。所以我对创业公司的生存方式产生了兴趣。我能判断一家初创公司是会生存还是会失败吗?尽管创业公司的本质在某种程度上意味着不可预测,但我想看看我能从一些数据中挖掘出什么见解。

摘要

这篇文章的特色是从初创企业数据库angelist.co收集的数据,将 ML 框架化为一个分类问题,即初创企业是否可以提高某个阈值来预测业绩。比较 P 值,卡方,F 值,互信息作为变量选择方法提出和评估。最后,选择的模型找到了最重要的预测因素:规模、成立年份、旧金山、奥斯汀、西雅图和手机游戏。大多数这些都是直观的,因为它们都证实了地理优势和市场竞争力对创业公司的影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

流程图

以下是我的 jupyter 笔记本从刮痧到建模如果你感兴趣的话:)

1.数据采集

在研究了几个不同的创业数据库后,我选择了 angelist.co 的 T4,因为它的数据相当详细,而且可以免费访问。下面是网站的外观,让你对我们正在处理的数据有一个大致的了解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

天使公司页面

上面的页面显示了大量的初创公司,对于每个初创公司,都会显示以下数据:

  • 加入时间(启动加入天使数据库的月份和年份)
  • 启动位置
  • 创业公司所处的市场(电子商务、医疗保健、B2B、SaaS 等)
  • 员工规模(1-10 人、11-50 人、51-200 人等等)
  • 当前启动阶段(种子期、首轮融资、…、首次公开募股、已收购)
  • 筹集的资金总额

我编写了一个 web scraper 来获取上述数据,从 Angelist 中随机抽取了 4260 个独特的初创公司。下面是我搜集的数据片段。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 1:抓取的数据

评估指标

我不知道该把这个问题框定为一个回归问题来预测一些美元价值,还是作为“好”和“不好”创业公司之间的分类。如果这是一个分类问题,那么我们需要一些好与不好的衡量标准。TechCrunch 的一项关于一轮融资对下一轮融资影响的研究给了我灵感。

我们在下图中看到,当公司在首轮融资前融资 200 万至 250 万美元时,融资 A 轮的概率最高。因此,融资 2M 美元的种子期公司应该比融资 2M 美元以下的公司有更高的生存机会。因此,我们的种子阶段模型将使用 2M 美元作为阈值来评估哪些公司好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:杰森·罗利,经由 crunchbase

在 0 美元到 200 万到 250 万美元之间,每筹集 50 万美元的首轮融资前融资都会略微增加 A 轮融资的可能性,至少对那些在 2003 年至 2012 年期间筹集了首轮融资前资金的公司来说是如此。在 250 万美元之后,从种子、天使和其他首轮前投资者那里筹集更多资金没有边际效益,至少就公司筹集 B 轮资金的机会而言。

在不同的 A 轮融资中,B 轮融资的概率要低得多。筹资金额对进入下一阶段的影响较小。然而,我们仍然看到接近 1200 万美元的峰值,因此我们将遵循之前相同的逻辑,使用 1200 万美元作为评估初创公司好坏的门槛。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:杰森·罗利,via crunchbase

我们发现 B 轮融资的成功率保持相对平稳,与平均水平只有微小的差异。这表明,出于这样或那样的原因,在 B 轮融资之前筹集的资金数量在大多数情况下不会对公司筹集 B 轮融资的能力产生重大影响。

数据后处理

在更正数据类型并清除重复的行/特殊字符后,应用以下处理逻辑来创建一个准备用于训练的表。

  • 原始数据列“位置”和“市场”是用于机器学习的一次性编码。
  • 创建“年”来表示自时间加入 angelist 以来的年数。
  • 创建“size_numeric”是为了将序数数据转换为数字数据(通过选择大小范围的中点)。
  • “raised_2mil”和“raised_12mil”是我们试图分别为种子和 A 轮创业公司预测的二元结果变量。
  • 通过“种子”和“系列 A”筛选阶段,并为建模准备好两个数据集。

下面是种子期公司数据框架的截图。除了 size_numeric 和 years 之外的所有变量都是二进制 1/0,以表示该创业公司是否符合位置/市场标准。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 2:生成的数据帧:种子 x

2.初步数据可视化

我们的数据集包含了来自所有不同阶段的总共 4260 家公司。这里有两个有趣的图表,显示了融资最多(最著名)的初创公司以及阶段的分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,具体来说种子期和首轮融资。让我们看看种子期公司和首轮融资公司在员工规模、地点和市场分布方面有何不同。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

公司规模分布

种子期公司的员工往往集中在 1-10 岁和 11-50 岁。A 系列公司的员工往往在 11-50 到 51-200 之间。这是非常直观的,因为当从一个阶段进入另一个阶段时,初创公司的规模通常会变得更大。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创业市场分布

种子和 a 轮之间最热门的市场似乎是一致的。移动商务,b2b 和 Saas 是排行榜的榜首。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

启动位置的分布

seed 和 a 系列的地点也有重叠。旧金山、纽约、伦敦、洛杉矶和奥斯汀是这两个阶段的热门地点。

关于影响创业公司生存的因素,这些分布并没有产生太多的洞察力。在下一节中,机器学习被应用于分析上述市场、位置及其对创业公司的影响。

3.建模

如果我们考察输入特征的性质,我们会发现大多数输入特征都是由一键编码生成的二进制特征。我们的输入数据具有很高的维数(大多数是二进制的),因此不太适合基于树的模型。鉴于数据的稀疏分布和低复杂度,我选择使用 logistic 回归 进行建模。

**要建模的两个数据集: seed 和 s*series A,*具有不同的“y”(“raised _ 2 mil”和“raised_12mil”)。这将为我们提供比较的洞察力。

特征选择

二进制特征可能非常偏向 0。(例如,一家公司的位置为“伊萨卡”,那么一个名为“伊萨卡”的列中正好有一行的值为 1,而其余的都是 0。)所以某些变量会比其他变量重要得多。在此步骤中,特征选择将用于仅选择重要的特征。

我决定尝试一些不同的特征选择方法,看看它们如何影响结果。也就是说,我将使用 卡方、互信息、ANOVA f 值和 p 值

对于 p 值选择,我使用 0.05 的 alpha 执行了一个向后消除,其余的使用来自[sklearn.feature_selection](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_selection)的内置函数。

简写如下。对训练数据运行逻辑拟合,如果具有最大 p 值的特征超过我期望的显著性水平(意味着 coef 不显著),则我移除该特征并重复该过程,直到剩下的所有特征都具有低于阈值的 p 值。

import statsmodels.api as smdef logiVarSelect(x, y, sig_lvl, columns):
    while True:
        logi = sm.Logit(y, x).fit(method='bfgs',maxiter=400)
        maxP = max(logi.pvalues)
        if maxP > sig_lvl:
            loc = list(logi.pvalues).index(maxP)
            x = np.delete(x, loc, 1)
            columns = np.delete(columns, loc)
        else: 
            return columns

p 值向后消除返回不固定数量的变量,在本例中,Seed 为 9,SeriesA 为 6。sci-kit 学习选择使用 SelectKBest 实现,其中 K 设置为 10。通过找到最佳验证集 AUC 性能来挑选该数字。(在下一部分解释)。卡方检验和 F 值检验对种子和系列产生了完全相同的变量,因此它们被合并为一个变量。以下是使用不同流程选择的变量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个有趣的观察是,对于 p 值选择方法,种子变量由大小、年份、位置和市场组成。而 A 系列变量不包括市场。对此的一种解释可能是,早期创业公司更依赖市场,随着它们的成长/进入,它们受市场表现/竞争力的影响较小。

模特表演

对于每种特征选择方法,在该组特征上训练逻辑回归,并使用验证组绘制 ROC 曲线。每条 ROC 曲线都有一个指标 AUC(曲线下面积)。该值越倾向于 1,模型对结果的预测就越准确…

在这个步骤中使用交叉验证来产生平滑和圆形的“平均”ROC 曲线。4x 网格中的每条模糊曲线是来自训练/验证集的单个 ROC,粗体曲线代表平均 ROC,灰色阴影区域代表一个标准差。左手边的大图是简单地绘制在一起的平均 ROC。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

验证集上种子公司的平均 ROC 曲线

对于种子公司,卡方/F 值选择方法在验证集上表现最佳,AUC 为 0.761。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

验证集上系列公司的平均 ROC 曲线

对于 SeriesA 公司,卡方/F 值选择方法在验证集上表现最佳,AUC 为 0.717。

从变量选择的比较来看,卡方/F 值在两个阶段都具有最高的 AUC,现在让我们看看在测试集上的表现。

4.模型评估和讨论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

种子阶段模型在测试集上的性能

种子期

对于种子阶段,Chi2/F 选择确实给了我们最好的测试精度 0.764。这意味着我们可以在 76.4%的时间里正确预测提高 2M 的能力。TPR 和 TNR 也是合理的。虽然提高 2M 并不意味着一定成功,但它最有可能提高下一轮。所以它绝对可以帮助我们识别“强大”的创业公司。

让我们再次访问 Chi2/F 选择确定的变量及其相应的系数和 p 值。这将为我们提供关于哪些因素是创业公司生存的强大影响因素的见解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将讨论 p 值小于 0.05 的变量,因为它们在区分好的和坏的创业公司方面具有统计学意义。size_numeric,years,Austin,San Francisco,Seattle,以及 Mobile Games 将在下面详细讨论。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显著预测值及其系数

种子阶段的发现

  • size_numeric ”有一个 0.0048 的小正系数(正意味着更有可能筹集到 200 万)。简单来说,大公司往往生存得更好。这是有道理的,因为较大的创业公司有更多的脑力,因此具有优势。
  • ”的系数为负,为-0.297,这意味着创业公司成立的时间越长,筹集 200 万美元的可能性就越小。非常直观,如果一个 3 岁的初创公司仍然处于种子阶段,那么这可能意味着它不是一个好公司,很快就会死去。
  • 奥斯汀”、“旧金山”、“西雅图”都有 1 左右的正 coeds,西雅图略微领先。这反映了创业公司的“热门”地点,这也是非常直观的。旧金山的硅谷,西雅图的许多科技巨头总部,以及奥斯汀快速发展的科技产业,都使这些地方成为科技创业公司的发源地。
  • 手游”是个有意思的,系数-1.298。对于创业公司来说,这似乎是一个糟糕的市场。我和一个风投的朋友讨论过手机游戏市场,我们的解释是 手机游戏市场很难创新,竞争激烈,具体到 。手机游戏本身并不是技术创新。所谓的手机游戏创新是指游戏风格/媒介/角色的知识产权。与解决现实问题的简单粗暴的 Saas 方法相比,这种精品概念对天使投资者来说更难理解。同时,手机游戏是一个竞争非常激烈的市场。很多手机游戏公司被像网易游戏这样的大型国际公司收购。手机游戏的“商业策略”或“卖点”在不同的游戏中是重复的。这种创新的缺乏助长了强大的竞争力。此外,手机游戏是一个非常“特殊”的市场。像“Saas”、“电子商务”或“移动医疗保健”(仅举几个种子阶段的热门市场)这样的市场非常广阔,可以包括非常不同的子市场,但移动游戏真正专注于为 Android 或 IOS 开发游戏。它的特殊性使得它很容易与其他移动游戏创业公司进行隔离和比较,因此使它成为一个具有统计意义的属性。总的来说,这个模型确定的“移动游戏”市场实际上是一个应该避免的投资选择,在 Saas、医疗保健和 b2b 等技术自由的市场中,创新有更多的可能性和理由。

系列 A 阶段

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系列舞台模型在测试台上的表演

与种子阶段的模型不同,SeriesA 阶段的模型表现糟糕。TPR 非常低,这意味着它们在预测“好”创业公司方面非常糟糕。造成这种情况的原因可能是样本数据集太小。当种子公司有 1882 个观察值时,我们有 529 个观察值。潜在的下一步是对更多的数据重新运行模型。

最后的话

总的来说,数据的质量肯定是有限的,但我们的种子阶段模型表现良好,精确度为 0.764。成功创业的预测因素不仅仅是市场、位置、规模和成立时间。公司文化和创始人背景等因素在现实生活中可能更具决定性。

然而,我们从种子阶段模型中得到了非常适用于现实生活知识的重要见解。所以,作为一个建议,尽量不要投资手机游戏,把你的钱投在旧金山、西雅图或奥斯汀的创业公司吧!(可能吧!)

退一步说,这个项目基于 Crunchbase 文章的百分比来看一个非常简单的问题。从中得出的见解只是为了我们的单纯解读。在风险投资领域,有太多的神秘、科学和技术是无法通过逻辑回归学习的。

感谢您的阅读!

如果您有任何问题或意见,请随时发起讨论/联系我们!

LinkedIn|xm53@cornell.edu|Github

预测大学教室和足球场的成功

原文:https://towardsdatascience.com/predicting-success-for-college-classrooms-and-football-fields-5f45e20153bf?source=collection_archive---------64-----------------------

每个学生在高等教育机构的旅程都会产生大量数据。使用它来构建支持机构和学生成功的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 MD 杜兰

帽子、礼服、文凭……还有数据!

每个学生在高等教育机构的旅程都会产生大量数据。招聘、咨询、留人、资助、行政 流程考核措施,课程工作、体育活动、校友活动均可详细跟踪。

这些数据可以在预测模型中发挥作用,推进机构目标并帮助学生取得成功。除了上面链接的有效用例,这里还有两种更具创新性的方法,研究人员使用机器学习在高等教育的世界中进行预测。当然,尽管存在挑战,但预测分析可以提供对各种高等教育数据的洞察。

KISS:对学生(…和模特)保持简单

随着许多学院和大学现在主要在线教学,学生们正面临着不同寻常的学习挑战。在线学习管理系统(LMS)提供了大量关于学生如何参与课程活动、在线资源和相互交流的数据。但是,哪些数据最能预测哪些学生可能会挣扎,哪些模型提供了最大的效用?

一组研究人员从 Moodle,一个流行的 LMS,收集了四个学期的在线计算机编程入门课程的数据。这些数据包括学生与课程内容的“认知互动”,他们彼此之间的“社会互动”,以及他们与教师的“教学互动”;研究人员认为这些类别可能有不同的预测能力。他们还收集了更多的数据,如学生在 LMS 上的总互动量,并向学生发放了一份关于动机和人口统计的问卷。最后,他们建立了新的功能,包括一个“承诺因子”,一个学生每周总互动量与班上所有学生平均互动量的比率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 虹膜王

有了这些有趣的数据,研究人员测试了 13 种不同的数据组合和 6 种不同的预测算法,以了解哪种算法能够最好地识别出有辍学或在第八周失败风险的学生。

令人惊讶的是,他们发现——尽管试图开发新的方法来检查学生的数据——“简单的交互计数可以用来生成预测模型,”尽管其他研究表明这可能还不够复杂。他们预测高风险学生的最佳模型是根据所有学生互动的总计数训练的 AdaBoost 分类器,第二好的模型也使用 AdaBoost,具有相同的计数和“承诺因子”功能。除了这些简单的数据点,即使是学生问卷也不能增强模型。

“我们可以得出这样的结论,一门包含几十种材料的更有条理的课程最适合学生的需求,因为他们可以与课程进行良好的互动,从而取得成功。研究人员写道:“学生互动似乎意味着参与,更多的参与会让学生取得成功。”。

虽然这似乎是显而易见的——建立一个强大的在线课程,学生更有可能成功!—这些结果对那些想自己尝试学习分析和预测的人很有帮助。你不一定要建立一个超级复杂的模型来识别和接触有风险的学生。一种更简单的方法来跟踪学生的在线参与度,并识别那些参与度较低的学生,仍然有助于学生的成功。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 安德鲁·麦克罗伊

大学体育中的预测分析:成功的推特

机器学习不仅仅是为了大学的学术和行政需要。另一个研究项目“从标签到海斯曼:大学足球招生中的社交媒体和网络”,展示了如何将逻辑回归用于足球学生运动员的推特帖子,以 87%的准确率预测他们是否会在这些推特帖子发布后的一个月内获得奖学金。

在正确预测报价方面,逻辑回归优于其他算法,包括随机森林SVM 。研究人员手工标注了 7000 多条推文,但自动自然语言处理,如情感分析,也可能是有用的。

虽然为一个团队选择一名运动员似乎是一个复杂的决定,有许多无形的因素,但有趣的是,Twitter 内容本身被证明是有预测性的。重要的变量包括运动员是否发布了“自我推销”的推文,“迎合”的推文称赞特定的教练和团队,以及他们参加的营地或拜访过他们的教练等信息。Bigsby 还创建了另一个逻辑回归模型,可以预测运动员是否会加入或“退出”某些团队。

除了体育和高等教育,这项研究还为如何将这种预测方法创造性地用于各种工作的招聘提供了思路。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 罗马法师

潜在问题

虽然这些例子使用的数据很容易从 LMSes 或公共社交媒体获得,但高等教育数据在实践中可能很难收集和分析。机构孤岛、分散的数据以及对学生隐私和偏见的担忧都带来了挑战。

来自 Hechinger 报告的这篇最近的文章特别涵盖了使用预测分析法对学生成绩的一些潜在的意想不到的后果。一个模型(和一个解释它的导师)可以引导一个学生远离一个被预测对那个学生来说过于雄心勃勃的首选专业……但是那个学生也许能够迎接挑战。模型和导师的指导是否符合学生的最大利益?这不是一个容易回答的问题。关于隐私和系统偏见的问题也发挥了作用。

诚然,这里存在复杂的问题。不过,只要小心,预测分析有很多方法可以用来帮助学生和其他人打造高质量的高等教育体验。

有关如何使用预测分析的更多灵感,请观看下面来自 Educause 的视频,其中一些机构领导人解释了预测分析在其机构中的作用。你也可以看看这本免费的电子书,它展示了七所不同的学校在各自机构的不同领域对分析方法的使用。

原载于 Alteryx 社区 并精选于 Alteryx 数据科学门户

预测泰坦尼克号的幸存者

原文:https://towardsdatascience.com/predicting-survivors-of-titanic-e7280822b00b?source=collection_archive---------35-----------------------

谁会在海难中幸存?我们可以用机器学习来回答这样的问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

斯图亚特(1843-1923)/公共领域

1912 年 4 月 15 日凌晨,由白星航运公司运营的英国客轮泰坦尼克号在从南安普敦到纽约的处女航中撞上冰山后沉没在北大西洋。据估计,船上 2224 名乘客和船员中,超过 1500 人死亡,这使得沉船成为现代史上最致命的和平时期商业海上灾难之一。

我们现在想要的是创建一个机器学习模型,能够预测谁将在泰坦尼克号的沉船中幸存。为此,我们将使用这个来自 Kaggle 的数据集——这个任务也有一个 Kaggle 竞赛,这是一个开始 Kaggle 竞赛的好地方。该数据集包含关于乘客的以下信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

探索性分析

现在,在对这个数据集进行任何机器学习之前,做一些探索性分析并看看我们的数据看起来如何是一个好的做法。我们也想一路准备/打扫。

import numpy as np
import pandas as pddf = pd.read_csv('train.csv')
df

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

df.describe()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们在数据中看到了什么?我们看到 PassengerId 列有一个与每个乘客相关联的唯一编号。机器学习算法可以很容易地使用这个字段来记住每个乘客的结果,而没有概括的能力。此外,还有一个名字变量,我个人认为它不能以任何方式决定一个人是否幸存。所以,我们将删除这两个变量。

del df['PassengerId']
del df['Name']

现在,让我们看看我们是否有丢失的值,以及它们有多少。

df.isnull().sum()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 891 个样本中,687 个样本的座舱变量为空值。此变量缺少太多值,无法使用它。我们会删除它。

del df['Cabin']

我们不想删除其他两列,因为它们很少缺少值,我们将增加它们。
对于装载的变量,由于它是一个分类变量,我们将查看每个类别的计数,并用拥有最多项目的类别替换 2 个空值。

df['Embarked'].value_counts()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

oaked 最常见的值是“S ”,因此我们将使用它来替换空值。

df['Embarked'].loc[pd.isnull(df['Embarked'])] = 'S'

对于年龄,我们将用平均年龄替换缺失值。

mean_age_train = np.mean(df['Age'].loc[pd.isnull(df['Age']) == False].values)
df['Age'].loc[pd.isnull(df['Age'])] = mean_age_train

请注意,我们应该存储我们从训练数据中了解到的一切,例如开始上课的频率或年龄的平均值,因为我们将在进行预测时使用这些信息,以防测试数据中也有缺失值。我们还将计算并存储费用平均值,以备测试数据需要。

mean_fare_train = np.mean(df['Fare'].loc[pd.isnull(df['Fare']) == False].values)

我们去掉了空值,现在让我们看看接下来会发生什么。

顺序编码

机器学习算法对文本不起作用(至少不能直接起作用),我们需要用数字转换所有字符串。我们将使用序数编码进行这种转换。序号编码是一种通过给每个类别分配一个数字来将分类变量转换为数字的方法。我们将使用 Scikit-Learn 的OrdinalEncoder对变量性别上船进行这种转换。
在此之前,我们将备份当前的数据格式以备将来使用。

df_bkp = df.copy()
from sklearn.preprocessing import OrdinalEncoderdf['Sex'] = OrdinalEncoder().fit_transform(df['Sex'].values.reshape((-1, 1)))
df['Ticket'] = OrdinalEncoder().fit_transform(df['Ticket'].values.reshape((-1, 1)))
df['Embarked'] = OrdinalEncoder().fit_transform(df['Embarked'].values.reshape((-1, 1)))

形象化

现在,我们将可视化我们的数据,看看我们的变量在存活和未存活类中的分布如何变化。
下面是我们数据集中每个变量的直方图(以及生成它的代码),左边是幸存人员的子集,右边是未幸存人员的子集。

import matplotlib.pyplot as plt
from IPython.display import display, Markdowndef show(txt):
    # this function is for printing markdown in jupyter notebook
    display(Markdown(txt))for i in range(1, 9):
    show(f'### {df.columns[i]}')
    f, (survived, not_survived) = plt.subplots(1, 2, sharey=True, figsize=(18, 8))
    survived.hist(df.iloc[np.where(df['Survived'] == 1)[0], i])
    survived.set_title('Survived')not_survived.hist(df.iloc[np.where(df['Survived'] == 0)[0], i])
    not_survived.set_title('Not Survived')
    plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对这种数据格式运行机器学习

现在,我们将在数据集上尝试几种机器学习方法,看看我们会得到什么结果。我们将使用的机器学习方法有:

  • 逻辑回归
  • 支持向量机
  • 决策图表
  • k 个最近邻居
  • 多层感知器

我们将使用 Scikit-Learn 的cross_val_score进行(5 重)交叉验证,而不是选择一个固定的验证集来估计测试集的准确性,sci kit-Learn 的cross_val_score返回一个数组,其中包含每次交叉验证迭代的分数。

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.neural_network import MLPClassifierX = df.iloc[:, 1:].values
y = df.iloc[:, 0].values# Logistic Regression
lr = LogisticRegression()
lr_score = np.mean(cross_val_score(lr, X, y))
print(f'Logistic Regression: {lr_score}')# Support Vector Machine
svc = SVC()
svc_score = np.mean(cross_val_score(svc, X, y))
print(f'Support Vector Machine: {svc_score}')# Decision Tree
dtc = DecisionTreeClassifier()
dtc_score = np.mean(cross_val_score(dtc, X, y))
print(f'Decision Tree: {dtc_score}')# K Nearest Neighbors
knc = KNeighborsClassifier()
knc_score = np.mean(cross_val_score(knc, X, y))
print(f'K Nearest Neighbors: {knc_score}')# Multi-Layer Perceptron
mlpc = MLPClassifier()
mlpc_score = np.mean(cross_val_score(mlpc, X, y))
print(f'Multi-Layer Perceptron: {mlpc_score}')

运行这段代码,我们得到了以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特征工程

让我们看看是否可以通过处理数据集的要素来提高精确度。为此,我们将首先恢复到应用序号编码之前所做的备份。

df = df_bkp.copy()

一键编码

现在,我们想对我们的分类变量应用一次性编码,而不是顺序编码。使用一键编码,我们不是给每个类分配一个数字,而是给一个向量分配所有的 0,除了一个特定于该类的位置,在该位置我们放置一个 1。也就是说,我们将每个类转换成一个独立的变量,其值为 0 或 1。我们将使用 Scikit-Learn 的OneHotEncoder对变量 PclassSexTicketembedded应用一键编码。

from sklearn.preprocessing import OneHotEncoder# Pclass
pclass_transf = OneHotEncoder(sparse=False, dtype=np.uint8, handle_unknown='ignore')
pclass_transf.fit(df['Pclass'].values.reshape((-1, 1)))
pclass = pclass_transf.transform(df['Pclass'].values.reshape((-1, 1)))
df['Pclass0'] = pclass[:, 0]
df['Pclass1'] = pclass[:, 1]
df['Pclass2'] = pclass[:, 2]
del df['Pclass']# Sex
gender_transf = OneHotEncoder(sparse=False, dtype=np.uint8, handle_unknown='ignore')
gender_transf.fit(df['Sex'].values.reshape((-1, 1)))
gender = gender_transf.transform(df['Sex'].values.reshape((-1, 1)))
df['Male'] = gender[:, 0]
df['Female'] = gender[:, 1]
del df['Sex']# Ticket
ticket_transf = OneHotEncoder(sparse=False, dtype=np.uint8, handle_unknown='ignore')
ticket_transf.fit(df['Ticket'].values.reshape((-1, 1)))
ticket = ticket_transf.transform(df['Ticket'].values.reshape((-1, 1)))
for i in range(ticket.shape[1]):
    df[f'Ticket{i}'] = ticket[:, i]
del df['Ticket']# Embarked
embarked_transf = OneHotEncoder(sparse=False, dtype=np.uint8, handle_unknown='ignore')
embarked_transf.fit(df['Embarked'].values.reshape((-1, 1)))
embarked = embarked_transf.transform(df['Embarked'].values.reshape((-1, 1)))
for i in range(embarked.shape[1]):
    df[f'Embarked{i}'] = embarked[:, i]
del df['Embarked']

缩放至[0,1]范围

我们还想将数值变量缩放到[0,1]范围。为此,我们将使用MinMaxScaler来缩放变量,以便最小值移动到 0,最大值移动到 1,其他中间值相应地在 0,1 之间缩放。我们将把这个转换应用到变量年龄SibSpParch费用

from sklearn.preprocessing import MinMaxScalerage_transf = MinMaxScaler().fit(df['Age'].values.reshape(-1, 1))
df['Age'] = age_transf.transform(df['Age'].values.reshape(-1, 1))sibsp_transf = MinMaxScaler().fit(df['SibSp'].values.reshape(-1, 1))
df['SibSp'] = sibsp_transf.transform(df['SibSp'].values.reshape(-1, 1))parch_transf = MinMaxScaler().fit(df['Parch'].values.reshape(-1, 1))
df['Parch'] = parch_transf.transform(df['Parch'].values.reshape(-1, 1))fare_transf = MinMaxScaler().fit(df['Fare'].values.reshape(-1, 1))
df['Fare'] = fare_transf.transform(df['Fare'].values.reshape(-1, 1))

对这种新的数据格式进行机器学习

现在,我们将对这种新的数据格式运行相同的机器学习算法,看看我们会得到什么结果。

X = df.iloc[:, 1:].values
y = df.iloc[:, 0].values# Logistic Regression
lr = LogisticRegression()
lr_score = np.mean(cross_val_score(lr, X, y))
print(f'Logistic Regression: {lr_score}')# Support Vector Machine
svc = SVC()
svc_score = np.mean(cross_val_score(svc, X, y))
print(f'Support Vector Machine: {svc_score}')# Decision Tree
dtc = DecisionTreeClassifier()
dtc_score = np.mean(cross_val_score(dtc, X, y))
print(f'Decision Tree: {dtc_score}')# K Nearest Neighbors
knc = KNeighborsClassifier()
knc_score = np.mean(cross_val_score(knc, X, y))
print(f'K Nearest Neighbors: {knc_score}')# Multi-Layer Perceptron
mlpc = MLPClassifier()
mlpc_score = np.mean(cross_val_score(mlpc, X, y))
print(f'Multi-Layer Perceptron: {mlpc_score}')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我们以这种方式设计了我们的特征之后,我们在所有分类器的准确性上得到了显著的提高。其中最好的分类器是决策树分类器。现在我们试图通过使用GridSearchCV进行超参数调整来改进它。

超参数调谐

from sklearn.model_selection import GridSearchCVdtc = DecisionTreeClassifier()
params = {
    'max_depth': list(range(2, 151)),
    'min_samples_split': list(range(2, 15))
}
clf = GridSearchCV(dtc, params)
clf.fit(X, y)print(f'Best params: {clf.best_params_}')
print(f'Best score: {clf.best_score_}')

我们得到的参数是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们得到的分数是 84.40% ,在超参数调优后提高了 0.9%

我希望这些信息对您有用,感谢您的阅读!

这篇文章也贴在我自己的网站这里。随便看看吧!

使用 SAP HANA 预测出租车目的地

原文:https://towardsdatascience.com/predicting-taxi-destinations-with-sap-hana-4125a62e2f5?source=collection_archive---------53-----------------------

基于真实实例展示多模型数据处理的优势

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

埃里克·诺帕宁在 Unsplash 上拍摄的照片

在我最近的故事中,我使用 SAP HANA 空间引擎和 SAP HANA 自动预测库,根据历史乘坐数据预测了在波尔图市乘坐出租车需要多长时间。在技术上,我利用 Jupyter 笔记本电脑和免费的 SAP HANA Express Edition 将所有操作(地理空间+机器学习)下推到数据库级别,而不是将数据(和计算)移动到客户端。

今天,我想更进一步,甚至根据起点、一天中的时间和轨迹的前几个点来预测出租车的目的地。在现实生活中,这种模型可以支持出租车运营,使后勤运营商能够预测某个区域内的可用出租车数量,甚至在这些出租车到达之前。

完整 Jupyter 笔记本 可在 GitHub 上查看。

让我们从代码开始——我不会详细介绍上传数据和六边形参考网格背后的概念,因为这已经在之前的博客中讨论过了。简单回顾一下:我们不是基于精确的坐标来预测结果,而是基于出租车出发的区域(即六边形单元)来预测出租车的目的地。

当查看出租车目的地区域的六边形单元时,我们最终处理多类分类问题,其中每个六边形单元(即其 ID 值)是一个目标类。HANA 的自动预测库提供了一个GradientBoostingClassifier,它能够进行多类分类。

数据准备和增强

然而,我们必须处理 GradientBoostingClassifier 的一个限制:它最多支持 100 个目标类。我们可以很容易地发现,我们的参考网格包含超过 1300 个潜在的目标区域。

那么,我们该如何处理呢?出租车经常去同一个地区。在前面的分析中,我们已经确定了波尔图的出租车接送热点。我们已经看到,在许多地区,抵达或出发的航班数量非常少。

*只预测前 100 个目的地会有什么影响?*我们可以使用下面的嵌套语句来检查到达前 100 个单元的总行程的百分比:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,我们看到只有不到 10%的行程到达其他地点。这意味着预测前 100 个目的地的模型将适用于超过 90%的旅行。当然,对于剩下的 10%,我们总是预测不正确的目的地。但是由于这些目的地很少,无论如何预测都很难。

好,我们来预测 100 个最常去的目的地。

为了使预测更有趣,我们将进一步包括滑行轨迹的前 10 个坐标。这可以让我们知道出租车朝哪个方向行驶。对于我们现实世界场景中的运营商来说,这对于不是超短的行程来说仍然是足够的提醒。

基于行程的前 10 个坐标,我们希望将以下特征添加到我们的训练数据集中:

  • 罗盘 =滑行前进的方向(N,NE,E,SE,S,SW,W,NW)
    我们将假设轨迹的第一个点在一个圆的中心,第十个点在其边缘。基于此,我们计算出指南针的方向。请注意,“ACOS(0)”的用法只是一种获取圆周率的黑客手段。

  • 罗盘 _DIST =出租车在轨迹的前 10 个点内行驶的直线距离。 想法是检测出租车是否快速进入一条主干道或者沿着一些小巷子行驶。

为了将这些特征添加到我们的数据集中,我们可以发出下面的语句,该语句也根据上面计算的值对指南针方向进行分类。

训练梯度增强模型

好吧,让我们用 75000 个样本轨迹构建一个数据集,分为训练数据集(80%)和测试数据集(20%)。为此,我们将使用 HANA 内置的窗口函数 RANDOM_PARTITION 。在选择前 100 个目的地时,我们已经看到了嵌套 SQL 语句的第二部分。

随机化的双重使用可能首先看起来令人困惑。我们使用“order by rand()”和“top 75000”来随机选取 75000 个样本。然后,我们使用“random_partition()”将这些样本随机分为训练和测试数据集。

结果数据集如下所示,其中 END_HEXID 是我们模型的目标变量,SET_NUM 确定记录是属于定型数据集(SET_NUM = 1)还是测试数据集(SET_NUM = 3)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我们准备好训练我们的梯度推进模型。在我装有 HANA Express 的笔记本电脑上,培训持续几分钟。所以,慢慢来,喝杯咖啡……或者浓缩咖啡,最好拿一杯浓缩咖啡。

使用 Python 的 hana_ml 客户端时,将从 Python 内部触发模型训练。但是,所有计算都在后台下推到数据库,数据不会传输到客户端。

喝完加了很多糖的浓缩咖啡后,我们观察分类模型的贡献特征。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

决定出租车目的地的三个最重要的影响因素是:

  1. 出租车前往的方向
  2. 提货区
  3. 一天中的时刻

这是有道理的——特别是白天的影响是可以预期的,因为晚上 8 点左右的旅行更有可能在酒吧或餐馆结束,午夜后的旅行更有可能在人们居住的郊区结束。

评估模型性能

当然,我们可以通过发出以下命令从 APL 中检索我们模型的统计度量:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是,这次我们要评估的模型略有不同。因为我们通过六边形来聚集我们的位置,所以我们可能在六边形的边缘有一些“接近失误”。上述性能测量仅反映了我们是否准确预测了正确的目标六边形,它不包括地理空间邻近性测量。

为了获得一些数据,我们将基于 15000 条记录的测试数据集进行预测。

对于每个预测的记录,我们现在有正确的目标六边形以及预测的目标六边形的 id。为了评估地理空间的接近程度,我们需要将参考格网中的几何数据连接回结果表。

生成的数据帧如下所示,其中 TRUE_CENTROID 和 PREDICTED_CENTROID 是相应六边形单元/区域的质心点。我们可以看到,APL 甚至在输出中添加了一个概率场,通过它我们可以根据模型确定预测位置的可能性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于此,我们可以计算出预测质心和真实质心之间的平均距离。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以平均来说,我们预测的范围是 2.6 公里。为了建立这种关系,我们需要知道我们的六角形细胞的直径。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这意味着由于我们的空间宁滨,我们无论如何只能在 1 公里的范围内进行预测。那么,我们的预测有多少是在正确的目标细胞中,或者是在它的一个相邻细胞中呢?根据直径,我们可以查询 1.1 公里范围内的质心。

我们可以看到,基于这个测量值**,我们正确预测了三分之一(在我的例子中是 33.9%)的行程**。

这听起来不错,但是我们应该将这个结果与适当的基线进行比较。*如果我们简单地总是预测具有最多整体滑行活动的六边形单元,会发生什么?*如果我们只有一个猜测,这个可能会很好。

我们可以确定最频繁访问的小区,并如下进行“预测”。

那么,我们的模型与作为基线的“多数票”相比如何呢?

使用我们的模型,我们的仍然比基线好 10%。我们的模型正确预测了 15000 次出行中的 5085 次,而基线多数投票只正确预测了 15000 次出行中的 3568 次

最后,我们可以将 APL 配置为也输出所有其他六边形簇的概率,这些簇没有被预测为目的地。

我们可以用这些数据来想象一个场景:

  • 在左侧,我们可以看到概率分布以及预测的目的地单元,以防我们在早上 8 点从 Campanha 火车站开始向西乘坐出租车。
  • 在右图中,我们看到同样的旅程只是在晚上 8 点开始,然后向东北方向行驶。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

同一起始位置的预测行程目标。

查看概率分布,我们可以知道,在任何情况下,城市中心都是一个可能的目的地(与时间和方向无关)。然而,对于向西的变量,我们在城市的东部没有看到任何高概率,而前往机场的概率明显更高。对于向东北方向的旅行,我们看到目的地在东北方向的概率较高,而机场和目的地在海边的概率较低。

作为一个附带收获,我们还可以在可视化中很好地看到,我们的前 100 个目的地地区基本上覆盖了波尔图的城市核心。

摘要

老实说,我不确定这是否是向出租车运营商推销解决方案的商业案例。但这仍然是一个有趣的例子,展示了如何将地理空间维度融入到机器学习模型中!

我们已经在这个(和我最近的)博客帖子中看到,如何将地理空间数据无缝地合并到一个简单的机器学习模型中。我们使用 SAP HANA 作为统一平台来处理空间数据和训练我们的模型。此外,我们还使用了 hana_ml Python 客户端来实现 Jupyter 笔记本的所有功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

【https://blogs.sap.com】最初发表于。关注作者上*LinkedInTwitter*。

用机器学习预测 2020 年 NBA 总冠军

原文:https://towardsdatascience.com/predicting-the-2020-nba-champion-with-machine-learning-32100f6b253d?source=collection_archive---------27-----------------------

使用常规赛统计的历史联盟排名

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

埃德加·恰帕罗在 Unsplash 上拍摄的照片

当新冠肺炎在三月份暂停 NBA 赛季时,我和其他数百万人一样,彻底崩溃了。作为一个铁杆湖人球迷,我很高兴看到勒布朗和他的团队最终带我们去了乐土。但在经历了过去 6 年完全平庸的表现,没有一场季后赛的表现,以及哀悼已故伟大的科比·比恩·布莱恩特(RIP)的去世后,我想,

当湖人队终于有机会夺冠时,这个赛季真的有必要出现一种不可见的病毒吗?

但是 7 月 31 日,篮球又回来了

不过,重新开始还有一个月,我已经看完了所有能想到的与篮球相关的内容,从观看 70 年代的 NBA 录像到 6 年级的 AAU 集锦。当我们耐心等待奥兰多的比赛结果时,我想让篮球界对这个赛季的未来有一点了解。我一直喜欢在季后赛开始前深入分析球队并预测每个赛季的冠军。在学习了一个月如何编码和使用数据分析工具后,我觉得已经准备好开始我的第一个机器学习项目来预测 2020 年的 NBA 冠军。(完整的 Github 回购可以在这里找到:https://github.com/trustinyoon/2020-NBA-Chip-Predictor)

数据收集

为什么我使用球队常规赛的联赛排名

我想创建一个模型,只使用常规赛的数据来预测 NBA 冠军。我总是着迷于球队的常规赛排名,并相信它们在决定球队在季后赛中的表现方面有着巨大的影响力。最初,我想过使用每场比赛的团队统计数据,然而,游戏在策略、速度、打法、运动员甚至游戏规则方面都发生了如此巨大的变化,如果我比较不同赛季的每场比赛统计数据,会有太多的噪音。例如,在 2003-2004 赛季,一支球队每场比赛的平均得分是 93.4 分,而上赛季是 111.2 分。仅仅通过比较原始数据来比较不同时代的球员或球队是不准确的。

确定一个团队的优势和劣势的最好方法是将它的表现相对于每个赛季的其他比赛进行比较。因此,我决定使用每个球队统计类别中的常规赛联赛排名作为特征来训练我的模型,以预测季后赛的胜利数。使用球队统计的联盟排名而不是每场比赛的球队统计,可以更清楚地显示出什么样的策略和执行对决定不同赛季的季后赛成功最有影响。

为了收集数据,我从网上刮下了自 2002-2003 赛季以来每支季后赛球队在 basketball-reference.com T2 的常规赛排名。联赛排名从 1 到 30,因为总共有 30 支球队:联赛排名 1 为最好,30 为最差。自从季后赛结构在 2004 年改变后,我没有刮旧赛季,因此 NBA 总冠军必须包括赢得 7 场比赛中的 4 场比赛,而以前的赛季没有。我也没有包括没有进入季后赛的球队,因为这将扭曲我的季后赛胜利数的因变量数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我从 basketball-reference.com 刮来的一个球队常规赛表格的例子。联赛排名显示在“Lg 排名”行中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个表是为我的 y 变量收集自 2003 年以来每个季后赛球队的季后赛胜利数的数据。

数据清理

在构建了熊猫的数据框架后,我运行了一个相关矩阵来过滤掉与季后赛胜利数(因变量)的皮尔逊相关系数小于 0 . 25 的联盟排名(自变量)。这给我留下了以下与季后赛胜利至少适度相关的联盟排名:投篮命中率%,3%,2%,防守篮板,对手投篮命中率%,对手 2%,对手盖帽,常规赛胜利,胜率,简单评分系统(SRS),整体进攻评分,整体防守评分,有效投篮命中率%,对手有效投篮命中率%,以及上座率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所选要素的多重共线性

在常规赛胜率(W)、胜率(MOV)和简单评分系统(SRS)中排名前三似乎是能够预测 NBA 冠军的体面指标。然而,SRS 和 MOV 是高度相关的,因为在计算两者时使用了点微分。我决定去掉 MOV,因为 SRS 稍微更准确一些,它考虑到了赛季安排的难度。上座率也有所下降,因为 2020 赛季的剩余比赛将在奥兰多的迪士尼世界进行,没有现场观众。

有效投篮命中率(eFG%和 O_eFG%)与其对应的投篮命中率(2P%、O_2P%、FG%、O_FG%)高度相关,所以我去掉了后四个,因为有效投篮命中率计算出的投篮效率稍微更准确一些。eFG%也与季后赛的胜场数稍有关联。

检查多重共线性后,我的模型具有以下特征:

  • 3 个百分点
  • 防守篮板
  • 对手拦网
  • 常规赛获胜
  • 简单评级系统
  • 总体进攻评分
  • 总体防御评级
  • 有效现场目标%
  • 对手有效投篮命中率%

探索性数据分析

冠军球队常规赛联赛随时间的排名

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就冠军常规赛团队进攻数据而言,2000 年代比 2010 年代有更多的可变性。这里最有趣的趋势是 3P%,因为金州勇士队自 2014 年以来以投篮 3 分彻底改变了篮球。三分球已经成为比赛中最重要的投篮,因为它有更高的 EV 和空间能力来创造更多的空位两分球。我们看到,一般来说,近几年的冠军往往在每个进攻团队的统计排名前 5-10,通常在 3P%排名前 5。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

常规赛球队防守统计排名的可变性似乎比球队进攻统计排名小得多,在这三个类别中排名前 5-10 可以是季后赛冠军的一个很好的指标。防守篮板(DRB)很重要,但比限制对手投篮效率(O_eFG%)和整体防守评分(DRtg)稍微次要一些。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

常规赛的胜数(W)和简单评分系统(SRS)似乎是预测一个冠军最一致的指标。冠军球队很少在常规赛胜利数或 Sr 数上排名前五之外。

限制对手拦网的影响被低估了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我发现对手的盖帽(O_BLK)类别是与季后赛胜利适度相关的最有趣的特征。这一发现让我假设,在 BLK 排名前百分之一的球队会让对手更难防守,这相当于更大的胜算。此外,篮球中的大部分盖帽来自非常短距离的投篮,因此对手盖帽能力较低的球队能够在更高的扣球率下得分,因为有更高的概率进行短距离投篮(例如上篮/扣篮)vs 中距离 2 分或 3 分。

预测模型

线性回归–随机森林–XGBoost

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

受邀参加奥兰多 2020 赛季重新开始的 22 支球队中每支球队的季后赛胜利预计数

在随机森林和 XGBoost 模型中交叉验证了训练和测试集,这有助于降低 MAEs 和防止过度拟合。

在每个模型中,密尔沃基雄鹿队预计将获得最多的季后赛胜利,湖人队紧随其后😒。尽管在 2019 年总决赛 MVP 科怀·伦纳德离开后,许多体育分析师都认为多伦多猛龙队排名很高,但卫冕冠军多伦多猛龙队的排名也令人惊讶。

但是在我把我所有的刺激资金都押在雄鹿队会赢得这个赛季之前,首先要考虑几件事。

结论

限制

我对数据的主要担忧是冠军球队(16 场季后赛胜利)的样本量非常小。这意味着每种模式中最好的球队的预期胜场数总是少于 16 场,这显然不足以赢得冠军。然而,我将分数解释为一个相对尺度,以查看哪支球队作为冠军具有最高的获胜预测值。

模型的 MAE 也随着每次测试和训练数据的变化而变化。每个型号的值通常在 2 到 3 之间。我用随机试验的预测和 MAE 的结果来总结发现。

摘要

使用常规赛 stat 联盟排名,我发现常规赛期间在胜场数(W)和简单评分系统(SRS)的联盟排名中名列前茅是预测冠军的最佳指标。在最近的趋势中,进攻得分高于防守得分也意味着赢得冠军的机会更大。

最佳预测性能由随机森林回归器实现,MAE 为 2.65,并预测雄鹿队以 13 场预期胜利成为冠军的热门。XGBoost 有一个较小的平均绝对误差 2.44,但是,它预测第一名雄鹿队只会赢得 9.3 场比赛,这与冠军所需的 16 场比赛相去甚远。

密尔沃基雄鹿队被每个模特选为最有希望赢得冠军的球队。湖人、猛龙、快船通常都混在雄鹿之后的积分榜上。

未来的工作

使用预测获胜次数可能不是确定冠军队伍的最有效方法。我会通过提供一支球队赢得 16 场季后赛的概率而不是它的期望值来增强我的模型预测。

我计划每季不断更新数据集,并继续完善现有模型/添加新模型。考虑到这是我的第一个数据科学项目,我使用的算法、参数和统计数据还有很大的改进空间。

用机器学习预测 NBA 季后赛比分

原文:https://towardsdatascience.com/predicting-the-2020-nba-playoffs-bracket-with-machine-learning-2030f80fa62c?source=collection_archive---------32-----------------------

利用历史篮球数据和机器学习预测每个系列赛的结果是可能的吗?

章鱼保罗是一只短命的头足类动物(2008 年 1 月 26 日-2010 年 10 月 26 日),饲养在德国奥伯豪森的海洋生物中心,他因被指能够预测国际足联世界杯足球赛的结果而一夜成名。他所要做的就是吃两个盒子中的一个,除了参赛国家队的旗帜之外,其他方面都一样。许多人认为章鱼是地球上最接近外星智慧的 T4 生物,人们可能会怀疑这种德国无脊椎动物(无意冒犯)是否知道一些关于足球的秘密,而这些秘密可能是更聪明的无毛猿(又名人类)事实上不知道的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有时候你只有一次机会赢得比赛。[图片由 Ramiro PianarosaUnsplash.com上拍摄]

基于计算机预测体育赛事结果的历史很长。内特·西尔弗的《信号与噪声的 T2》讲述了一个很好的故事,这是对这个主题感兴趣的人的必读之作。这本书还提醒读者,大多数这样的预测都失败了。然而,特别是自从深度学习的出现,先进的统计方法在体育赛事中的应用变得越来越重要,例如导致对棒球中的年轻球员进行球探,或者改进训练*,例如*到篮球中的投三分球。在这个历史时刻,我们很自然会问自己,在利用历史数据预测体育运动方面,人工智能能比我们强多少。在这篇文章中,我们将探索预测 NBA 季后赛的可能性,谁知道呢,甚至可能赢得 100 万美元。

用人工智能赢得 NBA 支架挑战赛

今年,美国国家篮球协会(NBA)发起了一项挑战,鼓励人们预测所有季后赛系列赛(加上决胜局)的结果,名为 NBA 括号挑战。虽然加入挑战的窗口现在已经关闭,并且在撰写本文时已经有了一些结果,但总体来看,如何安排机器学习系统来做出这样的预测是很有趣的。这当然是一种相当简化的方法,尽管在过去已经提出了更先进的例子,例如基于最大熵原理。我准备了一个 Google Colab 笔记本,你可以用它来玩。您还需要输入数据,您可以从这个共享文件夹中复制这些数据。

首先,我们从篮球参考网站收集数据。人们可以方便地下载常规赛和季后赛的统计数据。在这里,我们限制到 1990 年至 2019 年,我们将使用 2020 年的常规赛数据来预测 2020 年的支架。

对于每支球队,每年都有以下“经典”功能可用(平均每场比赛):

  • 常规赛末排名(Rk)
  • 玩游戏的次数(克)
  • 播放分钟数(MP)
  • 现场目标(FG)
  • 投篮尝试(FGA)
  • 现场目标百分比(FG%)
  • 三分球射门(3P)
  • 3 分投篮尝试(3PA)
  • 三分球命中率(3P%)
  • 两分投篮得分(2P)
  • 2 分投篮尝试(2PA)
  • 两分投篮命中率(2P%)
  • 罚球(英尺)
  • 罚球次数
  • 罚球百分比(英尺%)
  • 进攻篮板
  • 防守篮板(DRB)
  • 篮板总数(TRB)
  • 助攻数(AST)
  • 偷窃(短期)
  • 街区(BLK)
  • 周转率
  • 个人犯规

人们可以以 CSV 格式下载所有这些数据,这些数据可以很容易地作为一个 Pandas dataframe 来处理。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

熊猫数据框包含 1990 年至 2020 年的常规季节数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一些数据探索揭示了输入特征的平均值和百分位数。

毫不奇怪,这些特征之间存在相关性。为了减少输入特征的数量并尽可能消除相关性,习惯上是将标准化 ( 去除平均值并缩放方差),然后对输入应用主成分分析分解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输入要素之间相关性的热图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

成对输入特征变量的相关图。看起来像斑点的子图对应于不相关的变量。相反,一些子图显示了很强的相关性,如射门次数(FGA)与得分(pts)或得分(PTS)与排名(Rk)。

为了训练机器学习模型,在这个例子中只是一个浅层神经网络,我们假设常规赛数据包含足够的信息来预测季后赛比赛的结果,这有点夸张,但也不太疯狂。

Model: "DNN_regresson" _________________________________________________________________ Layer (type)                 Output Shape              Param #    ================================================================= input_69 (InputLayer)        [(None, 32)]              0          _________________________________________________________________ dense_185 (Dense)            (None, 32)                1056       _________________________________________________________________ dropout_98 (Dropout)         (None, 32)                0          _________________________________________________________________ dense_186 (Dense)            (None, 16)                528        _________________________________________________________________ dropout_99 (Dropout)         (None, 16)                0          _________________________________________________________________ dense_187 (Dense)            (None, 14)                238        ================================================================= Total params: 1,822 Trainable params: 1,822 Non-trainable params: 0 _________________________________________________________________

从技术角度来看,必须创建一组输入示例和相应的标签。有人可能天真地认为,预测比赛结果最明显的方法是让模型输出每个队赢的比赛数,例如4–1,2–4,等等。事实上,这种多维预测是不必要的,通常会产生 3-3、1-3 等不可能的结果。认识到可能结果的数量是有限的,这个问题就可以大大简化。例如,由于每个系列都必须以七局三胜结束(或在 2005 年前的第一轮中以五局三胜结束),因此只允许以下系列,因此可以在地图中进行编码:

valid_results = [(3,0), (3,1), (3,2), (4,0), (4,1), (4,2), (4,3), (3,4), (2,4), (1,4), (0,4), (2,3), (1,3), (0,3)]result_to_idx = {res: i for i, res in enumerate(valid_results)}
idx_to_result = {i: res for i, res in enumerate(valid_results)}

这样,我们可以要求网络输出 14 种可能结果中每一种的 softmax 概率。这样就不会得到不可能的结果作为输出。这种情况下的损失函数是sparse _ categorial _ cross entropy,它基本上是一个 categorial _ cross entropy,它不需要将标签表示为独热向量,而只是表示为整数,在这种情况下对应于有效游戏结果的索引。

该网络可以训练几十个时期和小批量。这种图的关键特征是训练和验证损失之间的必要一致。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作为训练时期的函数的训练(蓝色)和验证(橙色)损失。

决赛成绩

为了得到最终结果,训练好的网络被多次调用,每次比赛调用一次。首先,有必要定义一下互相对抗的队伍的名字。每个名字都被转换成一个表示索引的整数,该整数又被用于获取给定团队和给定年份(在本例中为 2020 年)的输入特征。

first_round = [
  ["milwaukee bucks", "orlando magic"],
  ["miami heat", "indiana pacers"],
  ["boston celtics", "philadelphia 76ers"],
  ["toronto raptors", "brooklyn nets"],
  ["los angeles lakers", "portland trail blazers"],
  ["oklahoma city thunder", "houston rockets"],
  ["denver nuggets", "utah jazz"],
  ["los angeles clippers", "dallas mavericks"]]

然后,该程序计算第一轮的结果,并根据结果,为半决赛、决赛和决赛创建类似的列表。

所以…预测如下:

第一轮

  • 密尔沃基雄鹿队 4-3 奥兰多魔术队
  • 迈阿密热火队 4-3 印第安纳步行者队
  • 波士顿凯尔特人队 4 比 1 费城 76 人队
  • 多伦多猛龙队 4 比 1 布鲁克林篮网队
  • 洛杉矶湖人队 2-4 波特兰开拓者队
  • 俄克拉荷马雷霆队 2-4 休斯顿火箭队
  • 丹佛掘金队 2-4 犹他爵士队
  • 洛杉矶快船队 4-1 达拉斯小牛队

胡人

  • 密尔沃基雄鹿队 4 比 3 迈阿密热火队
  • 波士顿凯尔特人队 2-4 多伦多猛龙队
  • 波特兰开拓者队 2-4 休斯顿火箭队
  • 犹他爵士队 2-4 洛杉矶快船队

大会决赛

  • 密尔沃基雄鹿队 4-3 多伦多猛龙队
  • 休斯顿火箭队 2-4 洛杉矶快船队

总决赛

  • 密尔沃基雄鹿队 4 比 1 洛杉矶快船队

那么,今年真的是扬尼斯·阿德托昆博年吗?

用 LSTM 神经网络预测南福克帕耶特河的流量

原文:https://towardsdatascience.com/predicting-the-flow-of-the-south-fork-payette-river-using-an-lstm-neural-network-65292eadf6a6?source=collection_archive---------41-----------------------

如何使用机器学习对时间序列数据进行预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

爱达荷州有一些世界上最美丽的河流!(📷威尔·斯托弗-诺里斯|东岔口南岔口萨蒙河)

TL;博士:

我制作了一个 LSTM 神经网络模型,它使用 30 多年的天气和河流流量数据来相当准确地预测明天的河流流量。

河流预报的问题是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

水遇到爱达荷花岗岩。📷威尔·斯托弗·诺里斯

我从事数据科学的主要原因是将它应用于现实世界的问题。作为一名皮划艇运动员,我花了很多很多时间研究天气预报、水文预报和斯诺特尔站的数据,以预测河流的流量。有很多好地方可以进行这种预测——NOAA 在全国各大河流流域都设有预测中心,包括南福克。

但是,这些预测往往达不到预期。特别是,我注意到预报容易受到重大降雨事件的影响(众所周知,太平洋西北部的河流很难预测),预报通常每天只发布一次或两次,这通常不够频繁,无法对快速变化的山区天气预报做出反应。美国国家海洋和大气管理局也只对一组选定的河流进行预报。如果你想要一个更小或更偏远的流域的预报,即使它被测量了,你也不走运。

因此,我开始着手创建一个模型,这个模型将达到或超过 NOAA 的预测,并为 NOAA 没有覆盖的一些流域建立模型。

首先,我将我的模型与由上游技术创建的行业标准模型进行对比。

南福克帕耶特是一个很好的起点,有几个原因:

  1. Lowman 上方的南岔口没有筑坝,因此避免了储层的混杂变量。
  2. 美国地质调查局在南福克操作一个计量器,国家海洋和大气管理局有气象站和河流预报,在盆地里有 SNOTEL 站点。首先有许多容易获取的数据。
  3. 我曾经在帕耶特教过皮划艇,我几乎划过河流系统的每个部分,所以我很了解这个地区及其水文!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

帕耶特的北叉是皮划艇运动员中的传奇。📷威尔·斯托弗·诺里斯

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

爱达荷州的河流总是不断变化。📷威尔·斯托弗·诺里斯

数据

我比较的上游技术模型使用气象和遥感数据来建立模型。我还没有加入任何卫星图像,尽管这是我的模型的下一个发展。

首先,我从位于南福克源头的班纳萨米特气象站下载了 NOAA 的每日气象数据。最终,我会将更多的站点合并到我的预测中,但是我想在第一次迭代中保持简单。测量的指标有:

  • 沉淀
  • 温度(最低和最高)
  • 积雪深度
  • 雪水当量
  • 一年中的某一天。

这些是我的预测特征。数据可以追溯到 1987 年。

接下来,我去了位于爱达荷州洛曼的美国地质勘探局测量站,获取了自 1987 年以来每天的流量。在一个更精确的模型中,我可能得到每小时的数据,但是我认为每天的数据对于这个迭代来说已经足够了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1987-2020 年 Lowman 南福克帕耶特的 CFS 排放

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

落基山脉的河流除了用于水力发电和灌溉外,还用于娱乐。📷威尔·斯托弗·诺里斯

争论

我用 pandas 合并了两个数据集,创建了一个包含特征和目标变量(流量)的数据框架。

气象数据中有一些缺失值,所以我用一些值来代替 NaNs。我创建了一个关联矩阵来查看是否有任何值是相关的,可以被删除。我决定去掉平均温度读数,因为已经有了最低和最高温度特征。

清理完数据后,是时候开始建模了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

美国西部的水是精确到最后一滴的。📷威尔·斯托弗·诺里斯

模型

我从一个基线开始——如果你只是猜测每次南福克的平均流量——大约 800 CFS——会发生什么?结果发现平均误差约为 600 CFS。这是不可接受的大,因为它几乎是河流本身的流量!

我知道我可以做得更好,好得多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

红线是大约 800 CFS 的基线预测。时间是 2019 年。

线性回归

线性回归非常简单,但也是一个不错的起点。我用了一个,然后两个,然后所有的特征,看看他们能多好地预测南汊的流量。答案是——非常糟糕。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于“一年中的某一天”特征的单一特征线性回归只是一条每年重置的斜线。不太有用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

双特征线性回归(基于“一年中的某一天”和“温度”)稍有细微差别。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在线性回归中使用所有八个特征并没有好到哪里去。

随机森林

好吧,所以线性回归不被认为是最强大的机器学习模型。是时候展示一些更复杂的东西了。我把所有的特征放在一个随机的森林模型中。我本来可以花更长的时间来调整超参数,但我决定只使用股票 scikit-learn 设置,例外情况是使用 100 个估计器。

结果是一个惊人的改进——随机森林没有完全捕捉到径流的细微差别,但它确实比线性回归更好地跟踪了一般的季节趋势。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个随机森林模型——越来越接近一个像样的预测!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

锯齿山脉,南福克帕耶特的源头。📷威尔·斯托弗·诺里斯

LSTM 神经网络

现在是最新、最大、最糟糕的模型——神经网络的时候了。LSTM 神经网络可用于时间序列预测,尽管它们有一些局限性。我用的是 LSTM 的模型。

这个模型有一些怪癖——你必须以一种非常特定的方式争论数据才能使它适合——我发现了一些非常有价值的教程(Keras 文档和机器学习大师)。

我在 1987 年至 2015 年期间训练了模型,并在 2016 年至 2020 年期间对其进行了评估。在以后的迭代中,我将更多地研究时间序列数据的更好的验证技术,比如嵌套的交叉验证。

最终,我设法得到了一个 R 值为 98%、平均绝对误差仅为~50 cfs 的模型!这比我试过的其他(相当简单的)型号好得多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我的模型性能随着时间的推移。LSTM 是明显的赢家!

最疯狂的是,我甚至没有将任何其他气象站或遥感数据纳入神经网络。

我怀疑前一天的流量对预测的贡献最大,因为预测的峰值似乎比实际峰值滞后一天左右。

我想对 LSTM 到底是如何得出预测的进行更多的调查,并可视化特征的重要性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我的 2019 年春季决选 LSTM 模型(提前一天)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就像爱达荷的穷乡僻壤一样,机器学习总有更多的东西可以探索。📷威尔·斯托弗·诺里斯

后续步骤

尽管我的模型在一天前表现得相当好,但我想在更长的预测范围内(2-10 天)对流量建模。我已经开始用 LSTM 做这个了,但是我需要花更多的时间。

我还想合并更多的气象站。NOAA 在该地区运营着几个站点,观察站点在分水岭的位置如何改变预测将会非常有趣。

我还想把卫星图像作为一个功能。这要复杂得多,因为文件很大,而且首先要获取图像。我已经开始建立一个管道,将谷歌地球引擎数据吸收到我的机器学习模型中。

最后,看看这个模型,它能够很好地预测过程线的下降段——但我也可以,只是凭直觉。该模型不太能够预测由于快速融雪或降雨事件导致的突然上升。在这些事件中,预测对于水电、防洪和公共安全至关重要。

一如既往,有更多的工作要做!

感谢您的阅读,请继续关注第 2 部分,在那里我将介绍一些后续步骤,尤其是合并卫星图像。

关于我的最新预测,请查看 rivers.fyi,我正在将 LSTM 神经网络投入多条河流的生产。

你可以在这里查看我在 Github 上用过的笔记本。

用深度学习预测主流音乐的声音

原文:https://towardsdatascience.com/predicting-the-future-sound-of-music-with-lstm-modeling-85488d8eac18?source=collection_archive---------32-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

夹具Unsplash 上拍照

毫无疑问,Spotify 是当今最受欢迎的音乐流媒体平台之一,它高度受数据驱动。数据科学家利用机器学习推荐系统进行个人策划的播放列表,这是该平台最受欢迎和准确得出奇的功能之一。更多深思熟虑的,甚至是新颖的功能被不断地寻找,以保持用户与平台的互动。

所以我在想如何利用 Spotify 的开发者数据来获得创意。

当有人提到一位艺术家时,你听说过“超越时代”这个词吗?如果我们今天就能预测明天谁会领先于他们的时代,那会怎么样?当然,“走在时代前面”的音乐家大多很有名,但更重要的是,他们通常负责发起他们流派的变革。声波历史进程的改变。

进入数据科学 Spotify 对每首歌曲的歌曲特征进行令人印象深刻的算法音频分析。

Spotify 使用算法,根据“声音”、“可跳舞性”和“速度”等特征,给每首歌曲一个数字轮廓。我们可以随着时间的推移汇总这些特征来回答我们的问题。

目标:

该项目的主要目标是分析和预测 Spotify 上超过 160,000 首歌曲的数据集的年平均(主流)趋势。我将尝试使用长短期记忆(LSTM)递归神经网络来预测每个特征在未来可能的值。这基本上是一个数据驱动的数字表示,代表了 5 年后普通音乐的声音。然后,可以创建与这些未来特征值最接近的歌曲播放列表,并将其命名为“领先于他们的时间的曲目”,并可以作为对应用程序用户的流行吸引力。

数据:

从 1920 年到 2020 年发行了超过 160,000 首曲目,每首曲目都有 14 个特征值:

点击“查看文件”可以在 Jovian.ai 上看到完整的 EDA/处理笔记本。

来自 Spotify 开发者页面的一些功能定义:

Acousticness :一个从 0.0 到 1.0 的置信度度量,表示音轨是否是声学的。1.0 表示音轨是声学的高置信度。

可跳性:可跳性描述了一首曲目在音乐元素组合的基础上适合跳舞的程度,包括速度、节奏稳定性、节拍强度和整体规律性。值 0.0 最不适合跳舞,1.0 最适合跳舞。

活跃度:检测录音中是否有观众。较高的活跃度值表示音轨被现场执行的概率增加。高于 0.8 的值表示该轨迹很有可能是实时的。

乐器性:预测一个音轨是否不包含人声。“Ooh”和“aah”在这种情况下被视为乐器。Rap 或口语词轨道明显是“有声的”。乐器度值越接近 1.0,轨道不包含人声内容的可能性就越大。高于 0.5 的值旨在表示乐器轨道,但随着该值接近 1.0,置信度会更高。

效价:从 0.0 到 1.0 的量度,描述一首曲目所传达的音乐积极性。高价曲目听起来更积极(例如,快乐、愉快、欣快),而低价曲目听起来更消极(例如,悲伤、沮丧、愤怒)。

探索数据

这些年来,音乐在数字上是如何发展的?以下是我在 EDA 期间看到的几个例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“声音”特征框随时间变化图

声音有明显的区别。20 世纪早期的高音质音乐。乐器、扩音器和制作设备的技术进步可能是大多数最新音乐的声学乐器和整体声音较少的原因。

这些数据的分布告诉我,每年的声学平均值可能并不能很好地代表这些数据,因为它们会受到异常值的影响。我们可能需要创建一个新的具有中间值的年度数据框。中值将更准确地代表大部分数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随着时间推移,小提琴演奏出了“关键”

这里我们有一个不同的音乐音阶的用法的概念,一个分类的特征,随着时间的推移。在大多数年份,0 和 7 键音阶是使用最多的,这可以从他们小提琴的粗细看出。

清洁

乍一看,这个数据集对我来说非常干净。它没有丢失的值,没有奇怪的字符,等等。但是经过 EDA 的进一步检查和可视化,一些需要处理的细节开始出现。

例如,“语速”的定义告诉我们:“语速检测音轨中口语单词的存在。越是类似语音的录音(例如脱口秀、有声读物、诗歌),属性值就越接近 1.0。高于 0.66 的值描述了可能完全由口语单词组成的音轨。”

我们现在知道过滤掉任何包含超过 0.66 的语音值的音轨,因为它们是由实际上不是音乐的歌曲组成的。换句话说,这些是录音讲话,也许是单口喜剧录音,它们不会在音乐潮流中扮演角色。

特征工程

我在 EDA 过程中注意到,我需要创建一个新的数据框架,该框架根据中位数而不是平均值对每年的每个值进行分组。这是因为异常值的不平衡分布使得平均值不是集中趋势测量的准确表示。看看一段时间内中值“声音”与平均值“声音”的比较:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我能够创建这个新数据框的最简单的方法是将“分组依据”中位数分配给单独的列,然后合并它们,因为有许多原始列与我们无关,如“显式”或“名称”。在这里看看我的代码:

点击“查看文件”可以在 Jovian.ai 上看到完整的 EDA/处理笔记本。

建模

我进行了 ARIMA 和 LSTM 建模和调整,最初使用“声学”功能,其绘制的时间序列如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里真正的目标是练习使用 LSTM 模型,但是我用 ARIMA 做了基线建模。在使用记录值、差分数据、LSTM 层叠加、双向 LSTM 层等众多 ARIMA 和 LSTM 模型后,给我最低均方根误差(RMSE)的模型是利用 1 滞后差分数据的 LSTM 模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用差异数据的 LSTM 验证损失曲线

那么,什么是 LSTM 模式呢? LSTM 代表“长短期记忆”,这是一种循环神经网络(RNN)。通过一系列的 sigmoid 和 tan 激活,LSTM 细胞选择性地遗忘其长期序列的一部分(通过循环遗忘门)。这些剩余值被用于预测下一个值,该值被输出到下一个单元中,作为下一个序列的存储单元输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你想从技术上更深入地了解如何创建 LSTM 模型,可以看看我写的分解编码过程的帖子(链接即将推出!).

用最佳 LSTM 模型预测未来值

由于价值(在我们的例子中是年)越来越难以预测,我们将预测上限定在 5 年。下面的图表显示了到 2025 年所有标准化要素的预测值(可以放在同一 y 轴上):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

过滤“超越时代”的艺术家

我决定从建模中去掉一些在历史上具有相同中值的特征,比如“显式”和“模式”。

不幸的是,我们的数据集不包含任何与所有特征的预测(中值)完全匹配的歌曲。对于最接近 2025 年预测值的歌曲,我采用每个预测模型 RMSE 与其预测值之间的间隔来过滤数据。

最“超前”的艺术家:二十一名飞行员——我心中的泪点

第二大“超前”艺人:新浪潮摇滚乐队——美少女

第三和第四位最“超前”的艺术家:卢·凯尔,里尔·特杰——错了(壮举。Lil Tjay)混音

莎拉·拉尔森清洁盗贼——交响乐(壮举。莎拉·拉尔森)

我们的数据集中没有符合每个预测特征范围的歌曲。我们发现与 2025 年预测(10 个中有 7 个)特征范围最相似的一首歌是《21 个飞行员》——《我心中的泪》。这首歌在我们的“可跳舞性”、“持续时间 _ 毫秒”、“能量”、“速度”、“效价”、“流行度”和“关键”误差范围内,与实际预测值相差不大。有 10 个共有特征中有 6 个的歌曲是新浪潮摇滚乐队的《美丽的女孩》。两首歌分享了 10 分中的 5 分。12 首歌分享了 10 个值中的 4 个。

结论

我们已经成功预测了我们的每个特征。那么他们告诉了我们什么?我们的模型预测,到 2025 年,普通歌曲将具备以下特征:

节奏将增加到 122.2 BPM 左右。响度将继续反弹,并达到接近-6db 的中值。(挺大声的!)歌曲中的工具性可能已经卷土重来,从 0。语速(人声/口语)将趋于平稳。声学度将再次降低,降至 0.08。平均受欢迎程度将继续增长。效价(积极/快乐)将下降并稳定在 0.455。能量会继续反弹,触及 0.649。可跳舞性或多或少也会保持稳定,只会上升一小部分,达到 0.697。换句话说,未来 5 年将保持最高的可跳性。

随后的研究表明,简单的时间序列,如数据点较少的时间序列,通常在 ARIMA 模型中表现更好,而 LSTM 模型在非常复杂的时间序列中表现更好,效率更高。考虑到这一点,我们能够使用稳定数据,通过 LSTM 建模获得较低的 RMSE,用于我们对每个特征的最终预测!

进一步建议

如果可能的话,我们可以直接访问 Spotify API,在整个 Spotify 库中查询那些拥有所有功能的最前沿艺术家。Spotify 总共列出了超过 5000 万首歌曲。找到与每个建模特征的未来平均值完全匹配的歌曲的概率要高得多。

将这种预测进一步扩展到各个流派,看看每个流派是如何随着时间的推移而演变的,以及这些流派中的哪些艺术家更早就演奏了这些价值观的音乐,这将是很有趣的。

最后,更多的时间分配来改进模型分层和/或参数将有助于我们预测的准确性。

欢迎在 GitHub 这里查看整个项目,如果你对我的过程有任何问题或建议,也可以给我发消息!

预测未来。数据科学家什么时候应该把数据留在身后?

原文:https://towardsdatascience.com/predicting-the-future-when-should-data-scientists-leave-the-data-behind-e96c47b18802?source=collection_archive---------27-----------------------

数据科学家经常被要求预测未来事件。不幸的是,我们拥有的科学工具是有限的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

准确地说,预测未来就像写科幻小说一样

在这里,我想说的是,有时数据科学家必须超越数据和科学。通常没有时间等待足够的数据来对潜在的结果做出合理的预测。有时候我们必须开始一些事情。在这些情况下,有一些非科学的工具来帮助我们做出合理的预测,这至少比什么都没有要好。

预测未来很难

大约在公元前 550 年,吕底亚国王克罗伊斯向特尔斐的神谕献祭,这加强了他传说中的财富声望。有金属锭可以作为一座四分之一吨重的金像、两个巨大的瓮、一个金瓮、一个银瓮和各种其他珍贵物品的基座:一座五英尺高的金像,是救他免于中毒的厨师的,还有他妻子的珠宝和腰带。他妻子对此事的想法没有记录。

作为回报,他请求神谕预言如果他进攻波斯会发生什么。有人告诉他,如果他这样做,一个强大的帝国将会崩溃。他把这解释为他将征服的信号——他毕竟花光了所有的钱——他入侵了。神谕被证明是正确的。一个强大的帝国倒了。不幸的是,对克罗伊斯来说,那是他自己的。

事实证明,预测未来是一件棘手的事情。

我想我们可以有把握地说克罗伊斯没有拿回他的钱。 对于我们这些数据科学家来说,风险在于我们表现得像甲骨文 。人们付钱给我们,让我们告诉他们将会发生什么,但是,到了紧要关头,我们通常会用“相信度”和关于概率的深奥讲座来回应。现在不要误解我,我个人喜欢关于概率解释的讨论,但我想知道我们在外人听起来是否像特尔斐的牧师。

“谢谢你的薪水,这里有一些神秘暧昧的呜呜呜,希望它能让你感觉良好。现在跑吧,做你无论如何都要做的事情

这是不可持续的,很容易导致人们完全放弃数据科学。

数据科学家甚至应该从事“未来业务”吗?

前几天,我看到一位亲密的同事告诉一位客户,数据科学家不做预测。因为我见过他叫很多个**。predict()** 法,我无法真正理解他的意思。

后来,他的论点是,当客户听到“预测”这个词时,他们会认为我们在对世界的未来做出明确的陈述。他更喜欢用“预报”这个词,因为人们知道天气预报不可能 100%准确。

现在,他很可能对客户的看法是正确的(他通常都是这样)。然而,对我来说,这是一种没有区别的区分。我认为,事实上,大多数情况下,数据科学家使用一系列科学工具来进行预测。有时,例如在时间序列问题中,这是显而易见的:明天卖出这些股票,因为我们认为它们的价值会随着时间的推移而下降。其他时候不太明显:例如在分类问题中。你可能不会预测未来,本身,但问题是你要预测人类法官会给你分类的例子贴上什么标签。

也有一些例外,例如,某些类型的 GANs 可能不算在内。但总的来说,我认为我们大多数人都在预测将要发生的事件,或者已经发生但尚未被我们观察到的事件。

这没什么不好。我们应该拥抱它。这是科学家做的事情

科学方法的卡通解释是,科学家建立一个模型,然后出去寻找推翻它的证据。渐渐地,随着越来越多的证据被收集起来,这个模型也没有被证明是错误的,这个模型被认为是一个科学真理**【2】**。这大致是数据科学家声称的行为方式:他们查看一些数据,建立一个捕捉正在发生的事情的模型,然后将该模型投入使用。随着更多数据的出现,这个模型得到了验证。

科学在行动。

明摆着的难题

不幸的是,在许多现实世界中,我们的预测并不是很好!例如,即使知道潜在客户之前已经完成了购买过程——这似乎应该是一个巨大的意向指标——也只能在预测谁会点击广告方面提供有限的改进。如果我能预测明天哪些股票会下跌,我会在地中海的游艇上写这篇博客,而不是在伦敦郊区的公寓里。

我们的技术是这样的,我们认为比随机机会做得好一点点就是胜利。如果我们也能比竞争对手做得好一点点,我们就成功了。我们正在尽最大努力使用科学方法,但是在方法和技术上遇到了限制。

现在,有一种数据科学家认为,当科学停止时,我们也应该停止。在这场争论中,科学方法是人类成就的顶峰。当我们不能用它来说任何有意义的事情时,就意味着我们不能真正了解任何事情。一个人不能说的,他必须保持沉默。

作为一个受过科学家训练的人,我对这种想法有些同情。然而,这个世界并不是这样的!如果你的公司以科学的速度前进,也就是说,缓慢而谨慎,只有在积累了足够的证据后才前进,你肯定会被那些行动更快的公司打败。

但是,我们的数据科学家可能会说,这些公司是在凭猜测行事!他们最终肯定会失败。这可能是真的,但是有两个相反的论点。一个是,这是一个非常大的世界,最终可能是一个非常长的时间。有一百个竞争者,他们中的一些人会碰巧猜对。他们的行动比你快得多,以至于在你收集数据证明猜测是否正确之前,你就已经被打败了。

然而,还有另一个更有趣的原因。我认为猜测不一定是随机的。猜测和做得比偶然更好是可能的,而且存在理性的,但本质上非科学的工具,帮助我们做到这一点。

于是,权衡的办法是等到有了数据,然后在一定程度上确定地继续下去,或者使用非科学的工具做出有根据的猜测。在许多情况下,我认为组织应该采取后一种方法。

进入“未来研究”的世界

到目前为止,我认为作为科学家,我们被要求预测未来,但基本上无法做到。对此有两种回应。一种是举起你的双手说,“我是科学家,这就是我停下来的地方”,然后看着你被击败。另一种是抛弃科学,尝试用其他工具来理解复杂的世界。

那么这些工具是什么呢?这里有一些,从未来研究领域借来的。对于数据科学家来说,它们可能看起来很陌生。我们要做的是想象一系列半可信的未来,然后给它们分配概率。这里我指的是赌徒意义上的“相信程度”的概率。令人高兴的是,这也是贝叶斯概率的意义。如果你持怀疑态度,请记住人类的努力不仅仅是科学。哈姆雷特在某种意义上是真实的,尽管它不是“字面上的真实”。

工具 1:科幻想象。在这里,你可以无拘无束地坐下来,编造一些似是而非的东西。这个想法是让你的思想自由。太空电梯?为什么不呢!海底殖民地?当然可以!或许更黑暗的东西?私营公司进行的总人口监测。那是科幻吧?

这个工具的用途不是产生现实的想法。让我们摆脱数据驱动培训带来的限制,尽情发挥想象力。如果你像我一样,通过克拉克和阿西莫夫到达了伊恩·M·班克斯,你可以引导那些未来的幻象,让整个过程不那么…奇怪。

工具二:视界扫描。未来已经到来——只是分布不均匀【5】。创新的历史上充满了想法从利基市场扩散并占领世界的例子。加拿大的那些家伙,直到 2010 年还在研究神经网络?那是无处可去的,直到它无处不在。那么外面还有什么呢?中国的 A.I .大概算主流,但是日本的纳米材料呢?班加罗尔正在进行哪些数据科学创新?或者拉各斯的城市设计创新?这不仅限于技术。想想中非音乐家的文化活力,在用法语**【6】说唱。**

关键是未来可能已经在某个地方存在了。涉及现有创新传播的预测比从头开始发生的预测更可信。

工具三: 趋势。好吧,瞎编只能让我们到此为止。我们必须查看数据,将想象的未来与我们现有的现状联系起来。你可能有所有这些疯狂的想法,但是我们能辨别它们中的任何一个,以任何方式,是现实的吗?一种方法是从数据中挑选一些相关的趋势,然后进行推断。记得那个太空电梯吗?纳米材料拉伸强度的提高会有多快?

这经常被描述为未来研究的科学部分。对于一个数据科学家来说,这可能不算科学。但至少观察数据趋势的过程应该是熟悉的。只是挑数据是一门艺术,你不能构建一个万物的因子模型,但不代表你什么都不能做。记住我们在这里讨论的是信仰的程度。

工具 4:场景测试。对于任何从事金融工作的人来说,这应该很熟悉。这是管理风险的人一直在做的那种压力测试(或者至少从 2008 年 9 月开始)。在他们的案例中,他们将调查局限于事件对金融投资组合的影响,例如,如果美国退出世贸组织,股价会发生什么变化,或者如果恐怖主义封锁马六甲海峡,大宗商品价格会发生什么变化?同样,我们可以思考重大事件对我们预测的影响,例如,南海战争对日本将建造第一架太空电梯的预测会有什么影响?关键是,没有一个单一的大效应事件是非常可能的,但一些事情最终会发生。通过调查一系列事件,希望你能发现以类似方式影响你预测的共同主题。

合成。您可能会轮流使用这些工具来完善您的预测。最后,你会想象出一堆未来,调查了世界各地的一堆创新,并试图用趋势和假设的场景来反驳它们。然而,当音乐停止时,你必须停止跳舞。记住我们不是在这里做科学研究。你必须下来,用你的判断力去 决定 。如果你愿意,你可以把它想成对将要发生的事情有一个预先的信念,你用微弱的证据更新了它。问题是,你不知道那个证据有多弱,所以数学帮不了你。

良好判断项目

最后,我需要提一下这是如何与 Philip Tetlock 的工作以及他在 Good judgment Project**【7】**中的工作相吻合的。这是一个测试人们预测未来能力的竞赛。他发现了一群超级预测家,他们比同时代的人更擅长预测未来。他接着指出了让他们变得优秀的性格特征:基本上要聪明、思想开放,与其他聪明、思想开放的人交往,努力工作,对概率意味着什么有一种直觉,并解释你的偏见。

这些都是好东西,但是没有说明如果你不得不做一个预测的话该怎么做。努力工作?当然,但是在哪里?然而,当我读到超级预测者描述他们如何做出预测时,他们给出了上面详述的两种方法,我松了一口气。

所以在结论 中,我认为数据科学家不能忽视预测问题,因为这是人们付钱给我们的目的。然而,我们需要面对这样一个事实,我们用来预测的工具并不是很好。有时候“不太好”就足够好了。然而,在不是这样的情况下,在我们需要考虑更长远的未来的情况下,还有其他非科学的工具可供我们使用。

你怎么想呢?数据科学家应该放过预测吗?请在评论中告诉我!

脚注

【1】《史记》,第一册,逻各斯 1,1.1–1.94,希罗多德

**【2】**这当然是对卡尔·波普尔的简化,参见这里的讨论。波普尔本人也有一个模型“确证”的概念,这一概念被与似然法相关的统计学家们所接受。当然还有库恩,所以你明白为什么我的是卡通版了。

**【3】**7、路德维希·维特斯坦根

**【4】**这些工具摘自我在彼得·马登教授的未来城市弹射器讲座上的笔记。任何错误都是我的!

**【5】**引自威廉·吉布森,确切地点一如既往有争议

**【6】**参见此处的示例。

**【7】**良好判断项目的参考资料可在这里找到

【8】识别和培养超级预测者作为提高概率预测的方法。芭芭拉·a·梅勒,菲利普·泰特洛克。心理科学透视,第 10 卷,第 3 期,第 267-81 页

****【9】这里引用的方法我认为包括趋势(朝鲜核试验)和情景测试(南海死亡)。

预测同行撰写的产品评论的“有用性”

原文:https://towardsdatascience.com/predicting-the-helpfulness-of-peer-written-product-reviews-ef7a0dfea2c3?source=collection_archive---------23-----------------------

将自然语言处理和神经网络应用于复杂的文本处理问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这有帮助吗?菲公主想知道。

一些电子商务网站让顾客写下他们产品的评论,其他顾客在考虑购买产品时可以浏览这些评论。我知道我读过我的顾客朋友写的产品评论,这些评论帮助我判断一个产品是否符合尺寸,是否能持续很长时间,或者是否含有我担心的成分。

如果一家企业能够预测哪些评论对其客户会有帮助,那会怎样?也许它可以把这些评论放在页面的最前面,这样读者就可以更快地获得最好的信息。也许企业可以注意到哪些主题出现在这些有用的评论中,并修改其产品描述以包含更多此类信息。也许企业甚至可以识别“超级评论者”,即特别擅长撰写有用评论的用户,并激励他们评论更多产品。

利用亚马逊的大量产品评论,我训练了一系列机器学习模型,试图识别哪些评论被读者评为“有帮助的”。我尝试了随机森林、逻辑回归、支持向量机、GRU 网络和 LSTM 网络,以及各种自然语言处理(NLP)技术来预处理我的数据。事实证明,预测有用的评论非常困难,但并非不可能!直奔代码,查看我的 GitHub repo 。要了解更多关于我是如何做到的,请继续阅读。

数据集

以下是您需要了解的数据集:

  • 它来自亚马逊(via Kaggle) ,尤其是食品部门,不仅包括食品,还包括厨房小工具和宠物食品。
  • 它是在 2002 年至 2012 年期间收集的,所以它并不完全是最新的,但我认为在 2020 年我们仍然可以从中学习很多东西。
  • 它包含了超过 500,000 条评论,在我删除重复的评论后,还剩下 393,579 条评论。
  • 读者有机会将评论标记为“有用”或“无用”。还有一个否决评论的选项,但没怎么用过。大约 52%的评论获得了零个“有帮助”的投票,其余的获得了一个或多个“有帮助”的投票。
  • 除了“有用性”和评论本身的文本,数据集还记录了产品 ID、用户 ID、时间戳和评论作者给产品的星级(满分 5 分)。

以下是按类别划分的评论数、总令牌数和唯一令牌数的快速浏览:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

虽然有帮助的评论少了,但是比没有帮助的包含了更多的词和更多独特的词。

困惑于预测

鉴于这个数据集的内容,我有两个大问题。问题 1:除了评论本身的文本之外,“有用性”可以通过其他特征来预测吗?例如,如果有用的评论总是包括 5 星评级,或者总是由同一批评论者撰写,那我就省了很多文字争论!

事实证明,答案是否定的:使用数据集中的任何其他特征,或者我自己设计的少数特征,都无法预测有用的评论。有用的评论可以是短的、长的、正面的或负面的;可以是新手写的,也可以是有经验的审稿人写的;它们可以是流行或不知名的产品;而且他们的词汇和无益的评论很像。

这是 t-SNE 的评论样本图,主要关注文本本身。t-SNE 图基本上是对数据集进行主成分分析,将所有要素减少到 2 或 3 个成分,然后绘制它们,这样您就可以看到类是如何重叠(或不重叠)的。这个情节揭示了一个噩梦:至少在这两个维度上,这两个类有很多重叠*。*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这让我想到了问题 2:如果没有预测有用性的捷径,我该如何从文本中预测有用性呢?我应该如何为建模预处理评论?应该尝试哪些机型?众所周知,使用人工生成的文本作为预测模型的输入非常困难,部分原因是有太多的方法可以将文本转换为数据,然后您需要相当复杂的模型来处理这些数据。选哪个?

当决定如何预处理评论文本时,我想尝试一系列的技术,集中在那些在我的项目的探索阶段看起来最有希望的技术上。至于建模,我想从更简单、训练更快的模型开始,然后逐步进行最复杂的选择。我希望前几轮测试可以帮助我确定最佳的预处理选项,而最后几轮测试可以帮助我完善我的最佳模型。

第一阶段:进入森林

我的第一轮大实验包括针对基线随机森林模型测试不同的预处理技术:

  • 将文本作为二元模型处理,然后在其上训练一个随机森林。
  • 将文本作为术语-文档矩阵进行处理(基本计数矢量化),然后在此基础上训练一个随机森林。
  • 计算 TF-IDF(术语频率-逆文档频率)向量,然后在随机森林中运行这些向量。

所有这些在验证数据上的表现都在 54–55%的准确度范围内,这仅比随机猜测好一点点,但至少不比随机猜测差!TF-IDF 得分最高,所以我决定使用 TF-IDF 向量作为输入,尝试调整一个随机森林,以便做得更好。我尝试了以下方法:

  • 使用网格搜索来确定要使用的最佳估计数和最大树深。
  • 将 TF-IDF 向量的长度增加一倍(即,创建了更多的输入数据),然后进行一种形式的主成分分析(使用 TruncatedSVD )来选择一些可以解释训练数据中 80%方差的成分。
  • 使用我在前面两步中生成的所有东西训练了一个最终的随机森林。

所有这些都产生了一个模型,该模型对训练数据过度拟合(超过 99%的准确率),对验证数据的准确率为 57%,这是我迄今为止的最好成绩。

但是比随机猜测好 7 个百分点并不值得大书特书,所以我转向了迁移学习方法。

第二阶段:脱下手套

迁移学习包括将别人的模型计算出的权重代入你自己的模型。这可能是一种非常方便的方式,可以从其他人的投资中受益,例如,在维基百科的所有内容上训练一个巨大的模型。

这就是嵌入手套的原因。斯坦福大学的一些聪明人训练了一个巨大的模型来量化英语单词在上下文中的关系。通过从 GloVe 中为我的评论语料库中的每个单词收集相关的嵌入向量,我可以从中受益。然后,对于每篇评论,我取所有单个单词向量的平均值,形成一个新的向量,代表评论的整个文本。然后,可以将所有评审向量传递给模型进行训练或预测。

我将我的手套嵌入传递给三个模型:随机森林、逻辑回归和支持向量分类器。这些模型在验证数据上的准确率也在 53–56%之间,其中随机森林的准确率最高。经过一些额外的调优,我仍然只能得到 56%的验证准确率。

在这一切之后,我非常想看看神经网络能做什么。

第三阶段:只有蚊帐

众所周知,序列对序列模型在处理文本数据时表现良好,所以我决定尝试两种不同的这类神经网络架构。我特别感兴趣的是让这些网络动态地计算它们自己的嵌入;由于 GloVe 做得不太好,我希望仅基于我的数据集的嵌入可能是更好的选择。

看看我的基线神经网络的结构:

*# Try again with more epochs, callbacks
import tensorflow as tf

embedding_size = 128
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Embedding(200000, embedding_size, input_shape=(100,)))
model.add(tf.keras.layers.GRU(25, return_sequences=True, input_shape=(100,)))
model.add(tf.keras.layers.GRU(25, return_sequences=True, input_shape=(100,)))
model.add(tf.keras.layers.GlobalMaxPool1D())
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(50, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(50, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(1, activation='relu'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

history = model.fit(X_train, y_train, epochs=50, batch_size=2048, validation_data=(X_val, y_val))*

这是一个计算嵌入的层,两个各有 25 个门控递归单元(GRU)节点的层,一个汇集其输出的层,两个各有 50 个节点的密集层(有 50%的丢弃以避免过度拟合),然后一个节点对每个样本进行最终预测。我也尝试了同样的架构,但是用长短期记忆(LSTM)节点代替 GRUs。结果没有实质性的差异,GRU 稍微快了一点,所以我决定继续用更大的输入向量和更多的训练时段来调整 GRU 网络。

最佳模型和结果

总的来说,我最好的模型是最后一个:GRU 网络在验证数据上达到了 59%的准确率。在我的 holdout 数据集上,这个模型也达到了 59%的准确率,考虑到它试图解决的问题的复杂性,这还算不错。

像这样的模型可以用来对提交的评论进行排序,并将那些可能有帮助的评论排在队列的最前面。一家企业也可以从自己的网站上搜集评论,筛选出有用的,然后再去评论,以了解潜在客户想知道的、他们的产品描述没有提供的信息。类似地,企业可以确定有用评论的作者,并鼓励他们写更多,或者修改他们的评论提交表格,以包括撰写更多信息性评论的技巧(正如 AirBnB、猫途鹰和其他公司已经做的那样)。

如果你想在有用的评论上看到我的整个项目的精彩细节,请查看 GitHub 上的代码。感谢阅读!

跨贴自【jrkreiger.net】*。*

用线性回归预测社交媒体广告对销售的影响

原文:https://towardsdatascience.com/predicting-the-impact-of-social-media-advertising-on-sales-with-linear-regression-b31e04f15982?source=collection_archive---------7-----------------------

本文将详细介绍使用 r 软件包进行简单线性回归的步骤,还将涵盖相关的基本介绍性统计数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

活动创作者Unsplash 上拍摄的照片

什么是简单线性回归?

线性回归测量响应变量 Y 和预测变量 X 之间的关系。X 增加一个单位,Y 增加吗?还是随着 X 增加一个单位而减少?我们想用线性关系从 X 预测 Y 变量。我们可以理解两个变量是如何相互联系或相互影响的。

例如,假设 Y 是伦敦不同街区每 1000 人被刺伤的次数——刺伤次数越多,犯罪率越高。如果 X 是不同社区的中值房价,我们可以使用线性回归来测试中值房价较低的社区是否有较高的犯罪率,反之亦然。

回归方程:

数学上,线性回归可以表示如下:

Y=β1+β2X+ϵ

  • 响应(相关)变量 Y 是我们试图预测的。
  • 预测(独立)变量 X 用于预测响应。
  • β1 是截距,是一个常量值*。*如果 X = 0,那么 Y 将完全依赖于β1。
  • β2 是回归线的斜率。我们将这些术语称为系数。
  • ϵ是残差项。这将显示 x 可以解释多少 Y,误差项的平均值为 0。

让我们用一个例子来形象化这一点。

带 R 的示例

我们将使用datarium包中包含的marketing 数据集,其中包含一家虚构公司的三种媒体(脸书、YouTube 和报纸)的广告预算(以千美元计)以及该公司的销售数据。

1.提出我们的问题:

制定一个研究问题是指导探索性数据分析过程的有用方法。它可以帮助清理数据集,并通过消除不需要的变量、处理缺失值等为严格的分析做准备。我们的一般问题是:

考虑到 YouTube 和报纸广告的效果,脸书广告对公司的销售有什么影响?

我们希望开发一个线性模型来解释预测变量facebook 和数值响应变量sales之间的关系。在本文中,我们将使用 R 包来执行简单的线性回归。这里有一个简单的线性回归方程:

Sales=β0+β1*Facebook+ϵ

涉及多个预测变量的多元回归将在另一篇文章中进行解释(即将发布!)。例如,如果我们想测试脸书广告对公司销售的影响给定YouTube 和报纸广告的广告预算,我们的多元回归方程将如下所示:

销售额=β0+β1 * Facebook+β2 * YouTube+β3*newspaper+ϵ

我们将首先从一个简单的线性回归开始,找到预测响应sales的最佳直线,作为预测值facebook的函数。

2.安装

首先在 R Studio 中安装tidyverseggpubrdatarium包。从datarium包中导入marketing数据集。

library(tidyverse)
library(ggpubr)
data(“marketing”, package = “datarium”)

3.探索性数据分析

首先,我们将使用str()函数来获得数据结构的快照视图。我们可以看到有 200 行数据和 4 个变量——YouTubefacebook报纸销售额。我们还可以看到每个变量的前几个单独的值。此外,我们可以看到每一列变量的类别——我们的每个变量都被归类为“数值型”。

> str(marketing)
'data.frame':	200 obs. of  4 variables:
 $ youtube  : num  276.1 53.4 20.6 181.8 217 ...
 $ facebook : num  45.4 47.2 55.1 49.6 13 ...
 $ newspaper: num  83 54.1 83.2 70.2 70.1 ...
 $ sales    : num  26.5 12.5 11.2 22.2 15.5 ...

我们也可以使用dim() 来了解数据帧的尺寸,即行数和列数。

> dim(marketing)
[1] 200 4

接下来,我们将使用head()函数来浏览一下我们的原始数据。默认情况下,该函数将返回前六行,但是我们可以根据自己的喜好查看任意数量的行。我们希望看到前 10 行:

> head(marketing, 10)
   youtube facebook newspaper sales
1   276.12    45.36     83.04 26.52
2    53.40    47.16     54.12 12.48
3    20.64    55.08     83.16 11.16
4   181.80    49.56     70.20 22.20
5   216.96    12.96     70.08 15.48
6    10.44    58.68     90.00  8.64
7    69.00    39.36     28.20 14.16
8   144.24    23.52     13.92 15.84
9    10.32     2.52      1.20  5.76
10  239.76     3.12     25.44 12.72

让我们也用tail看看数据集的结尾。这非常有用,因为在一些数据集中,最后几列可能包含数据的总计或汇总,这可能是不相关的。

> tail(marketing)
    youtube facebook newspaper sales
195  179.64    42.72      7.20 20.76
196   45.84     4.44     16.56  9.12
197  113.04     5.88      9.72 11.64
198  212.40    11.16      7.68 15.36
199  340.32    50.40     79.44 30.60
200  278.52    10.32     10.44 16.08

现在,我想使用summary调出一些汇总统计数据。

> summary(marketing)
youtube          facebook       newspaper     
 Min.   :  0.84   Min.   : 0.00   Min.   :  0.36  
 1st Qu.: 89.25   1st Qu.:11.97   1st Qu.: 15.30  
 Median :179.70   Median :27.48   Median : 30.90  
 Mean   :176.45   Mean   :27.92   Mean   : 36.66  
 3rd Qu.:262.59   3rd Qu.:43.83   3rd Qu.: 54.12  
 Max.   :355.68   Max.   :59.52   Max.   :136.80  
     sales      
 Min.   : 1.92  
 1st Qu.:12.45  
 Median :15.48  
 Mean   :16.83  
 3rd Qu.:20.88  
 Max.   :32.40

我们必须理解这些重要的术语和数字代表什么。

  • **均值:**所有数值之和除以数值总数。在我们的示例数据集中,YouTube 广告的平均预算是 176.45 美元或 176,450 美元。另一方面,脸书的平均广告预算要低得多,为 27.92 英镑或 27,920 美元。
  • **中位数:**奇数排序列表中的中间数。在偶数列表中,中位数是将排序数据分为上下两半的两个数字的平均值。
  • **最小值:**这是每个变量的最小数值。
  • **最大值:**这是每个变量的最大数值。

所以我们已经收集了一些关于数据集的有趣信息。我们知道,该公司在 YouTube 上的平均广告支出高于脸书或报纸广告。

我们可以通过quantile更深入地了解数据的分布。

> quantile(marketing$facebook)
   0%   25%   50%   75%  100% 
 0.00 11.97 27.48 43.83 59.52

4.让我们开始策划吧!

太好了!我们有了一些关于数据集的初步信息,现在我们可以绘制一些图表。我们将使用ggpubr() 包中的ggplot()函数。首先,为了演示为什么我们使用ggpubr 包来绘制我们的图形,我们将使用plot() R 的内置绘图函数来绘制基本图形。

> plot(marketing$sales, marketing$facebook)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们将使用ggplot()

> ggplot(marketing, aes(x = facebook, y=sales)) + geom_point() + stat_smooth()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

脸书 vs 销售

允许以更美观的方式绘制图表。这里,情节是带有“aes”或“美学映射”的营销数据集、从 facebook销售变量导出的、一组和一个平滑器

上图(准备出版)显示了销售额facebook 变量之间的正线性关系。这表明广告预算的增加会导致公司销售额的增加。出于好奇,我们也可以想象一下销售和 YouTube 广告以及销售和报纸广告之间的关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

YouTube vs 销售

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

报纸 vs 销售

有趣的是,虽然salesyoutube 广告之间的关系也是线性的和正的,但是salesnewspaper 广告之间的关系却不是——它是一条曲线,实际上在报纸广告的非常低和非常高的水平上开始负斜率。

**自变量和因变量之间的相关性如何?**相关性分析将确定两个连续变量之间的关系强度。我们必须计算相关系数来执行该分析。相关性取+1 和-1 之间的值。接近 0 的值表示两个变量之间的相关性较弱。

在我们的示例数据集中,如果高销售额伴随着高脸书广告价值,变量将是正相关的,反之亦然。正如我们在图表中已经看到的,销售额和脸书广告之间存在正相关关系。然而,销售和 YouTube 广告之间有更强的正相关性。

销售和报纸广告之间的相关性最弱。这表明销售(Y)的大部分变化是报纸广告(X)无法解释的。为了衡量销售额的显著变化,我们需要一个具有强相关性的解释变量,即 YouTube 或脸书。

> cor(marketing$sales, marketing$facebook)
[1] 0.5762226> cor(marketing$sales, marketing$youtube)
[1] 0.7822244> cor(marketing$sales, marketing$youtube)
[1] 0.7822244

5.简单线性回归

为了在 R 中执行简单的线性回归,我们将使用lm()

> model1 = lm(sales ~ facebook, data = marketing)
> model1Call:
lm(formula = sales ~ facebook, data = marketing)Coefficients:
(Intercept)     facebook  
    11.1740       0.2025

5.回归线

现在,让我们为我们的回归生成一个图表。回归线将尝试最小化残差平方和(RSS 或残差平方和)。

> ggplot(marketing, aes(facebook, sales)) +
 geom_point() +
 stat_smooth(method = lm)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回归概念:

  • 拟合值和残差:通常,真实世界的数据不会正好落在回归线上,这就是为什么回归方程包含误差项ϵ.的原因拟合/预测值用.表示如果β用表示,则系数为估计值。统计学区分估计值和已知值,因为估计值是不确定的,而已知值是固定的。误差项ϵ将包含估计值和已知值之间的差异。
  • *最小二乘法:*在简单回归中,我们会使用 OLS 或普通最小二乘法来估计我们的回归模型与数据的拟合程度。用^表示的系数是使 RSS 最小的值。然而,在多元回归中,我们将使用最大似然来估计模型拟合度。

6.解读我们的回归

估计回归线为:

Sales=11.174+0.2025*Facebook+ϵ

  • 截距(β0)为 11.174,可以解释为脸书广告预算值为零时的预测美元销售额。因此,对于等于零的脸书广告预算,我们可以预计销售额为 11.174 * 1000 = 11,174 美元。
  • 回归系数(β1)表明,对于等于 1000 美元的脸书广告预算,我们可以预期销售额增加 202.5 单位(0.2025*1000),即sales = 11.174 + 0.2025*1000 = 56.44 units。这相当于 213,670 美元的销售额。

7.评估我们的模型

现在我们有了回归模型,我们需要理解如何解释它。仅仅创建一个回归模型是不够的。我们必须检查(a)我们的回归是否有统计学上的显著关系,以及(b)我们的模型是否与数据吻合。很好地拟合数据的回归模型是这样的,X 的变化导致 y 的变化。

在继续之前,我们必须了解标准误差和假设检验。

标准误差:

标准误差衡量我们的系数估计值与我们的响应变量的实际平均值相差多少。标准误差可用于计算置信区间。置信区间量化回归系数的不确定性。通过使用confint()函数,我们了解到区间[0.12,0.24]有 95%的机会包含β1 的真值。

> confint(model1)
                2.5 %     97.5 %
(Intercept) 9.8419062 12.5060253
facebook    0.1622443  0.2427472

假设检验:

标准误差可用于对回归系数进行假设检验。最常见的假设检验是检验零假设和替代假设。

  • 零假设(H0):系数等于零,即预测变量和响应变量之间没有关系。
  • 替代假设(H1):系数不等于零,即预测变量和响应变量之间存在关系。

为了检验零假设,我们必须确定β1 的估计值是否离零足够远,使得β1 不为零。如果β1 估计值的标准误差足够小,那么即使β1 估计值很小,也会提供反对零假设的证据。

我们如何衡量β1 的估计值离零有多远?t 统计量将测量我们对β1 的估计值偏离 0 的标准偏差的数量。我们需要使用回归模型来拒绝零假设,并证明销售facebook 变量之间存在关系。

为了解释我们的线性回归,我们将展示我们模型的统计摘要。为此,我们使用summary()

> summary(model1)Call:
lm(formula = sales ~ facebook, data = marketing)Residuals:
     Min       1Q   Median       3Q      Max 
-18.8766  -2.5589   0.9248   3.3330   9.8173 Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 11.17397    0.67548  16.542   <2e-16 ***
facebook     0.20250    0.02041   9.921   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 5.13 on 198 degrees of freedom
Multiple R-squared:  0.332,	Adjusted R-squared:  0.3287 
F-statistic: 98.42 on 1 and 198 DF,  p-value: < 2.2e-16

8.测试我们模型的准确性

让我们来分解这个摘要输出:

  • 残差:如前所述,残差是由^.表示的估计系数残差是实际值和估计值之间的差值。理想情况下,残差的分布应该是对称的。
  • 系数:我们的系数β0 和β1 分别代表截距和斜率。我们已经在上一节解释了这些系数。
  • 系数标准误差,如上所述,衡量我们的系数估计值与我们的响应变量的实际平均值相差多少。换句话说,它衡量系数估计的准确性。我们的标准误差越接近零越好。
  • 系数 t 值测量我们的系数估计值离 0 有多远(以标准偏差表示)。相对于标准误差,较大的 t 值将提供反对零假设的证据,并表明预测变量和响应变量之间存在关系。具有低 t 统计量的预测器可以被丢弃。理想情况下,t 值应大于 1.96,p 值应小于 0.05。
  • c 系数— Pr( > t) 代表 p 值或观察到大于 t 的值的概率。p 值越小,我们越有可能拒绝零假设。通常,5%或更低的 p 值是一个很好的分界点。注意符号。在我们的例子中,代码’ T9 '与每个评估相关联。三个星号代表高度显著的 p 值。由于销售和脸书广告之间的关系非常重要,我们可以拒绝我们的零假设。
  • 剩余标准误差:这衡量我们回归拟合的质量。这是销售变量将偏离真实回归线的平均金额。
  • 多重 R 平方:除了 t 统计量和 p 值,这是我们测量回归模型拟合度最重要的指标。r 衡量我们的预测变量(销售额)和我们的回应/目标变量(脸书广告)之间的线性关系。它总是介于 0 和 1 之间。接近 0 的数字表示回归,不能很好地解释响应变量的方差,接近 1 的数字可以解释响应变量中观察到的方差。在我们的例子中,调整后的 R(根据自由度进行调整)是 0.3287——只有 32.87%的销售增长可以用脸书广告来解释。如果我们进行多元回归,我们会发现 R 会随着响应变量数量的增加而增加。(注:YouTube 广告预算与公司销售额的关系更强,R 为 0.612。因此,与脸书广告相比,YouTube 广告可以更好地预测公司销售数据)
  • F 统计量:这是一个很好的指标,表明 Y 和 x 之间是否存在关系,我们的 F 统计量离 1 越远,我们的回归模型就越好。在我们的例子中,F 统计量是 98.42,在给定数据集大小(200 个观察值)的情况下,它相对大于 1。在多元回归模型中,F 统计量更相关。

因此,我们需要重点关注的模型拟合的四个关键指标是 t 统计量、p 值、R 和 F 统计量。t 统计量越大,p 值越小。p 值越小,X 和 Y 之间关系的几率越大。R 衡量模型与数据的拟合程度-如果 R 接近 1,则表明 Y 中的大部分变化可以用 X 来解释。F 统计显示了模型的总体显著性。较大的 F 统计量将对应于具有统计显著性的 p 值(p < 0.05)。

8.总结我们的结果

总的来说,我们已经进行了简单的线性回归,也涵盖了一些基本的介绍性统计。这绝不是对营销数据集的全面分析,而只是一个如何执行和解释简单的 r 线性回归的示例。这是一个很好的起点,尤其是在试图理解 t 统计量、p 值和标准误差等重要统计概念的相关性时。在下一篇文章中,我们将继续讨论这个数据集的多元回归。多元回归练习将是迈向全面数据分析项目的一步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值