【问题标题】:Any efficient way to build up regression model on panel data?在面板数据上建立回归模型的任何有效方法?
【发布时间】:2019-09-15 01:41:39
【问题描述】:

我有二维数据,包括某些地区的频繁犯罪类型和全年对应的房价。我想了解某些地区的犯罪频率与房价波动之间可能存在的关联。最初我尝试使用线性回归来做到这一点,但效果不佳。现在我想尝试对我的数据进行 PCA 分析,但我仍然无法获得有意义的结果。为了进行回归,我如何对面板数据执行有效的 PCA 分析?任何有效的解决方法来实现这一点?谢谢

数据

因为我的数据维度有点长,这里做可复现的例子有点困难,让我们看看面板数据是什么样子的:

这里是最安全的云链接,您可以浏览输入面板数据:example data snippet

更新:我的尝试

由于@flyingmeatball 指出使用 PCA 不是一个好主意,我尝试了简单的线性回归,但它并没有帮助我捕捉到犯罪频率和房价之间的关系。这是我所做的:

from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import scale
import re
import urllib
import pandas as pd

# download data from cloud
u = "https://filebin.net/ml0sjn455gr8pvh3/crime_realEstate?t=7dkm15wq"
crime_realEstate = urllib.request.urlretrieve (u, "Ktest.csv")

# or just manually download data first and read
crime_realEstate = pd.read_csv('crime_realEstate.csv')
cols_2012 = crime_realEstate.filter(regex='_2012').columns
crime_realEstate['Area_Name']=crime_realEstate['Area_Name'].apply(lambda x: re.sub(' ', '_', str(x)))
regDF_2012 = crime_realEstate[cols_2012]
regDF_2012 = regDF_2012.assign(community_code=crime_finalDF['community_area'])
regDF_2012.dropna(inplace=True)
X_feats = regDF_2012.drop(['Avg_Price_2012'], axis=1)
y_label = regDF_2012['Avg_Price_2012'].values

poly = PolynomialFeatures(degree=2)
sc_y = StandardScaler()
X = poly.fit_transform(X_feats)
y= sc_y.fit_transform(y_label.reshape(-1,1)).flatten()
X = log(X)
y = log(y)
regModel = LinearRegression()
regModel.fit(X, y)

上面的代码对我没有帮助,因为我想看看哪些功能会导致一年中的房价波动。关于如何实现这一点的任何想法?

目标

我想要实现的是建立模型来解释某些地区的犯罪频率与各自的房价波动之间的动态关系。任何有效的解决方法来实现这一点?

更新

如果 PCA 不是一个好主意,那么任何可能的回归模型可以捕捉某些社区区域的犯罪频率与房价波动之间的关系?有什么想法吗?

【问题讨论】:

    标签: python regression panel-data


    【解决方案1】:

    我查看了您的数据。这是我在几个预处理步骤上的 2 美分:

    1. 您需要重新排列它,使 Y 为 Price_For_Area_Year。例如您的第一条记录转换为以下内容:

    1. 1 热编码 area/area_code
    2. 使用某些标准方法估算缺失值
    3. 使用 pca 等处理多重共线性。自变量具有高度相关性。

    我认为你应该得到一些有意义的线性相关。如果没有,请尝试将一些变量转换为等级。分享一下效果如何。

    【讨论】:

    • 你能用草图编码解决方案来详细说明你的观点吗?
    【解决方案2】:

    几个想法:

    1) 请发布完整的代码。我看不到在哪里定义了 crime_realEstate 。如果您省略了将数据读取到该变量的行,那么很难重现您的错误,并且您不太可能获得帮助。此外,您应该组织所有导入语句,使它们位于代码的顶部。它实际上并不是一个函数式的东西,它更像是一个每个人都期望并使其更易于阅读的约定。

    2)当您引用面板数据时,您真的在谈论 pandas DataFrame 吗?这是存储此类东西以供分析的一种“典型”方式。您可能希望养成将数据称为数据框的习惯,以便您的听众更清楚。您还应该发布完整的错误回溯,以便我们可以看到究竟是哪一行代码被轰炸了。

    3) 我认为您可能误解了 PCA,或者至少误解了它的用途。 PCA(原理成分分析)是一种数据转换方法,您可以在其中捕获跨多个变量的数据变化,并将该数据重新表述为更少的成分,这些成分捕获相同数量(或更少,取决于您保留的成分数量)的可变性.运行 PCA 后,您将无法查看哪些功能会导致犯罪,因为它们将被全新的组件所取代。如果识别与犯罪相关的特征很重要,那么 PCA 是个坏主意。

    请修复以上项目。

    编辑

    我并不是说 PCA 是错误的,我只是说您在上面提出的问题(“我如何应用 PCA 以及为什么我的代码轰炸”)并不是真的正确的问题。如果您认为有许多相关变量需要减少到较低的维度,则应使用 PCA。不过我不会从那里开始 - 看看不这样做你可以获得什么样的准确性。您现在已经重新制定了一个更广泛的问题“我如何为这些数据制作预测模型,最好使用回归?”,这可能应该转到https://datascience.stackexchange.com/,但我会给你一个起点我将如何编写该解决方案。

    首先 - PCA 可能不是理想的起点,因为仅查看数据/列,您的问题不在于维度。在 5 年内,您基本上有 10 种不同的罪行。您也只有 58 个不同的行……或者这只是示例数据?此外,您的数据有点奇怪——多行的价格相同,但犯罪行为不同。我不知道这是否只是因为您发布了示例数据。如果这确实是完整的数据集,请立即停止分析并获取更多数据/去做其他事情。

    我就如何解决问题做出了一些行政决定。所有这些都只是为了演示如何编写回归代码。我总结了所有年份的犯罪率(你可能想要平均?最高?变化?这些都是你的设计决定)。我的指标是 2012-2016 年的价格变化,即您拥有犯罪数据的时间范围。我按犯罪类型将犯罪计数标准化。没有缩放目标变量。

    我会这样开始:

    from sklearn.linear_model import LinearRegression
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import r2_score
    from sklearn.preprocessing import scale
    import pandas as pd
    
    # Load data
    filePath = 'L:\\crime_realEstate.txt'
    crime_df = pd.read_csv(filePath, sep = '\t').drop(['Unnamed: 0','community_area'],axis = 1)
    
    #calculate price change between 2016 and 2012 - same timeframe you have crime data
    crime_df['price_change'] = crime_df['Avg_Price_2016'] - crime_df['Avg_Price_2012']
    crime_df.drop(['Avg_Price_2012','Avg_Price_2013','Avg_Price_2014','Avg_Price_2015','Avg_Price_2016','Avg_Price_2017','Avg_Price_2018','Avg_Price_2019'],axis = 1,inplace = True)
    
    #split years if they are data over time
    crime_df.columns =  pd.MultiIndex.from_tuples([(x.split('_20')[1] if '_20' in x else x ,x.split('_20')[0]) for x in crime_df.columns])
    #sum across years for crimeFields
    crime_df = crime_df.groupby(level=[1],axis = 1).sum(axis = 1)
    
    #split out tgt var
    price_growth = crime_df['price_change']
    
    #create dummy variable from area name
    dummy_df = pd.get_dummies(crime_df['Area_Name'])
    
    
    crime_df.drop(['Area_Name','price_change'],axis = 1,inplace = True)
    
    #scales crime variables
    scaler = StandardScaler()
    crime_df[crime_df.columns] = scaler.fit_transform(crime_df)
    
    crime_df = pd.merge(crime_df,dummy_df,left_index = True, right_index = True)
    
    regModel = LinearRegression()
    
    #split to training testing
    train_df = crime_df.sample(frac=0.8,random_state=200)
    test_df = crime_df.drop(train_df.index)
    
    regModel.fit(train_df, price_growth[train_df.index])
    
    #R2 
    r2_score(price_growth.drop(train_df.index),regModel.predict(test_df))
    0.7355837132941521
    

    对您的分析的更简单回答:无论白人住在芝加哥,哪里的房产都很贵。

    【讨论】:

    • @flyingmeatball 我解决了这个问题。如果 PCA 更糟,那我该怎么办?如何建立模型来捕捉特定区域的犯罪频率与房价波动之间的关系?您能否通过可能的编码练习详细说明您的观点?谢谢
    • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
    • @Zoe 我用清晰的规范和干净的编码部分更新了我的帖子,你能指出我如何解决我的问题吗?有什么想法吗?
    • @zoe 批评/澄清不可能在
    • @flyingmeatball 这样吗?您仍然可以发布多个 cmets。 600 个字符的限制不是滥用答案部分的借口。此外,没有什么可以阻止您连续发布多个 cmets。请重新阅读How to Answerwhen to comment
    猜你喜欢
    • 2021-06-29
    • 2020-12-15
    • 1970-01-01
    • 2014-09-11
    • 2023-01-19
    • 1970-01-01
    • 2014-11-21
    • 2011-06-15
    • 1970-01-01
    相关资源
    最近更新 更多